コントローラクラスの例外処理を共通化します。
例外のハンドルは@ExceptionHandlerを付与したメソッドで行います。
これを使用することでtry-catchも少しだけ減らすことができ、コントローラクラスに複数のAPIを用意した場合に
エラー処理を共通的に記述することができます。
まずは簡単なソースを。
package spring.rest.test; import java.sql.SQLException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class ExceptionController { @RequestMapping(value="/exception", method = RequestMethod.GET) public void exception() throws Exception { throw new Exception(); } /** * SQLExceptionの例外処理 * @param e * @throws Exception */ @ExceptionHandler(SQLException.class) private void sqlExceptionHandler(Exception e) { System.out.println("SQLException Handler"); // ここでthrow e;してもexceptionHandlerにはいかない } /** * Runtime系の例外処理 */ @ExceptionHandler(RuntimeException.class) private void runtimeExceptionHandler(RuntimeException e) { System.out.println("RuntimeException Handler"); } /** * その他のException例外処理 */ @ExceptionHandler(Exception.class) private void exceptionHandler(Exception e) { System.out.println("Exception Handler"); } }
上記の例ですと、exception()でExceptionをスローしているのでexceptionHandler()が実行されます。
ここに例外処理を記載することができます。
例えばSQLExceptionの場合だとロールバックとログ出力を行うなどなど。
これは簡単な例ですので実際には親クラスに@ExceptionHandlerを使用したエラー処理を書いておいて、
必要な場合には子クラスでオーバーライドして個別のエラー処理を書くのがいいと思います。
こんな感じでしょうか。
exceptionHandler()を子クラスでオーバーライドしなければ親クラスの
exceptionHandler()がコールされます。
BaseAbstractController.java
package spring.rest.test; import java.util.HashMap; import java.util.Map; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestController; @RestController public abstract class BaseAbstractController { /** * その他のExceptionの例外処理 * @param e */ @ExceptionHandler protected Map<String, Object> exceptionHandler(Exception e) { Map<String, Object> map = new HashMap<>(); map.put("basecontroller", "error"); return map; } }
ExceptionController.java
package spring.rest.test; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @RestController public class ExceptionController extends BaseAbstractController{ @RequestMapping(value="/exception", method = RequestMethod.GET) public void exception() throws Exception { throw new Exception(); } /** * SQLExceptionの例外処理 * @param e * @throws Exception */ @ExceptionHandler(SQLException.class) private void sqlExceptionHandler(Exception e) { System.out.println("SQLException Handler"); // ここでthrow e;してもexceptionHandlerにはいかない } /** * Runtime系の例外処理 */ @ExceptionHandler(RuntimeException.class) private void runtimeExceptionHandler(RuntimeException e) { System.out.println("RuntimeException Handler"); } /** * その他のException例外処理 */ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) @Override protected Map<String, Object> exceptionHandler(Exception e) { Map<String, Object> map = new HashMap<>(); map.put("override", "error"); return map; } }
コメント