【Spring MVC】REST APIにてweb.xmlを使用して例外ハンドリングを行う方法

概要

REST APIアプリにて、web.xmlを使用して例外ハンドリングを行う方法についてまとめた。

あわせて読みたい

概要 REST APIアプリにて、入力チェックを行った際のエラーハンドリング方法についてまとめた。 エラーメッセージはBean Validationのデフォルトメッセージを使用する。

【Spring MVC】REST APIにて基本的な入力チェックエラーハンドリングを行う方法

 

Webアプリケーションの設定

例外がアプリ側でハンドリングされず、サーブレットコンテナ(Tomcat)まで伝播する場合、web.xmlを利用して例外ハンドリングを行う。

 

web.xml

例外の種類に応じて、エラー時の挙動を設定できる。
今回は特定のエラー情報がサーブレットコンテナまで伝播した場合、「/error」にフォワードさせる。

 

web.xml


<?xml version="1.0" encoding="UTF-8"?>

<web-app>
	<!-- WebアプリケーションコンテキストのDIコンテナ作成 -->
	<servlet>
		<servlet-name>app</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:/META-INF/spring/springMVCContext.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>app</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- ルートアプリケーションコンテキストのDIコンテナ作成 -->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:/META-INF/spring/applicationContext.xml
		</param-value>
	</context-param>

	<!-- HTTP 500 エラーページを指定 -->
	<error-page>
		<error-code>500</error-code>
		<location>/error</location>
	</error-page>

	<!-- NullPointerException が発生した場合に /error へリダイレクト -->
	<error-page>
		<exception-type>java.lang.NullPointerException</exception-type>
		<location>/error</location>
	</error-page>

	<!-- デフォルトエラーハンドリング -->
	<error-page>
		<location>/error</location>
	</error-page>
</web-app>

 

<error-page>
    <error-code>500</error-code>
    <location>/error</location>
</error-page>

上記はHTTPステータスコード500がサーブレットコンテナまで伝播した場合、「/error」にフォワードする。

 

<error-page>
    <exception-type>java.lang.NullPointerException</exception-type>
    <location>/error</location>
</error-page>

上記はNullPointerExceptionがサーブレットコンテナまで伝播した場合、「/error」にフォワードする。

 

<error-page>
    <location>/error</location>
</error-page>

上記はアプリ側でハンドリングされなかった、あらゆる例外がサーブレットコンテナまで伝播した場合に「/error」にフォワードする。

 

コントローラークラス

「/error」に対応したハンドラメソッドを保持するクラス。

 

ApiErrorHandleController.java


package com.example.rest_prototype.web.controller.error;


import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.rest_prototype.web.resources.error.ErrorInfo;
import com.example.rest_prototype.web.resources.error.ValidateErrorInfo;

/**
 * REST APIにてweb.xmlで例外ハンドリングする
 * 共通エラーコントローラーにリクエストさせる
 */
@RestController
public class ApiErrorHandleController {

	@GetMapping(value = "/error")
	public ResponseEntity<ErrorInfo> handleError(HttpServletRequest req) {
		Integer status = (Integer) req.getAttribute("javax.servlet.error.status_code");
		HttpStatus httpStatus = HttpStatus.resolve(status != null ? status : HttpStatus.INTERNAL_SERVER_ERROR.value());

		var errorInfo = new ValidateErrorInfo();
		errorInfo.setStatus(httpStatus.value());
		errorInfo.setErrorCode("SAMPLE_ERR0003");
		errorInfo.setErrorTitle("エラー");
		errorInfo.setErrorMsg("処理続行不能");
        // ResponseEntity を作成して返却
        return new ResponseEntity<>(errorInfo, httpStatus);
	}
}

 

@GetMapping(value = “/error“)
public ResponseEntity<ErrorInfo> handleError(HttpServletRequest req) {

サーブレットコンテナにエラーが伝播すると、このコントローラークラスにフォワードする。
ここで任意のエラーメッセージを返却する。

 

まとめ

 

☑ アプリ側でハンドリングされていない例外は、サーブレットコンテナ(Tomcat)まで伝播する

☑ web.xmlを使用することで、サーブレットコンテナまで伝播した例外をハンドリングできる

☑ 例外の種類に応じたハンドリングが可能(基本的には@ControllerAdvceでハンドリングすることが推奨される)

 

スポンサーリンク