コントローラクラスの例外処理を共通化します。
例外のハンドルは@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;
    }
}
  
  
  
  
コメント