SpringFramework 例外処理のハンドリングと共通化

ほしがき2017/09/23(土) - 10:19 に投稿

コントローラクラスの例外処理を共通化します。

例外のハンドルは@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;
    }
}

 

 

タグ