LoginSignup
127
128

More than 5 years have passed since last update.

Springで例外ハンドリング

Last updated at Posted at 2016-05-08

環境

Spring-Boot 1.3.3
Spring-WebMVC 4.2.5

例外ハンドリング

Springでは、Controller個別で例外をハンドリングする方法と、Controllerを横断して例外をハンドリングする方法の2通りのハンドリング方法が存在する。ここでは、RestControllerでのハンドリングを例にしてやってみる。

Controller個別で例外をハンドリングする

Controller個別で例外をハンドリングする場合、Controllerクラス内にハンドリング用のメソッドを作成する。このメソッドには@ExceptionHandlerアノテーションを付与する。そうすることでそのControllerクラス内で発生した例外に対する設定を行うことができる。

CustomerRestController.java
@RestController
@RequestMapping("api/customers")
public class CustomerRestController {

    @Autowired
    CustomerService customerService;

    @RequestMapping(method = RequestMethod.GET)
    Page<Customer> getCustomers(@PageableDefault Pageable pageable) {
        Page<Customer> customers = customerService.findAll(pageable);
        return customers;
    }

    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    @ResponseBody
    public Map<String, Object> handleError() {
        Map<String, Object> errorMap = new HashMap<String, Object>();
        errorMap.put("message", "許可されていないメソッド");
        errorMap.put("status", HttpStatus.METHOD_NOT_ALLOWED);
        return errorMap;
    }
}
  • @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    • このController内でHttpRequestMethodNotSupportedExceptionが発生した場合は、handleErrorメソッドでハンドリングを行う。
  • @ResponseStatus(HttpStatus.BAD_REQUEST)
    • クライアントにレスポンスを返す際のステータスコード。ここでは400を返す設定。
  • @ResponseBody
    • レスポンスにJSONを返却する際に利用するアノテーション。

Controllerを横断して例外をハンドリングする

Controllerを横断して例外をハンドリングする場合、まずは例外ハンドリング用のクラスを作成する。このクラスには@ControllerAdviceアノテーションを付与する。そうすることで全てのControllerクラスで発生した例外に対する共通の設定を行うことができる。
例えば以下の例では、TrendRestControllerとCustomerRestControllerでHttpRequestMethodNotSupportedExceptionが発生した場合、ExceptionHandlerクラスのhandleErrorメソッドで例外がハンドリングされる。

TrendRestController.java
@RestController
@RequestMapping("api/trends")
public class TrendRestController {

    @RequestMapping(method = RequestMethod.GET)
    String getTrends() {
        return "Something Trends";
    }
}
CustomerRestController.java
@RestController
@RequestMapping("api/customers")
public class CustomerRestController {

    @Autowired
    CustomerService customerService;

    @RequestMapping(method = RequestMethod.GET)
    Page<Customer> getCustomers(@PageableDefault Pageable pageable) {
        Page<Customer> customers = customerService.findAll(pageable);
        return customers;
    }
}
ExceptionHandler.java
@ControllerAdvice
public class ExceptionHandler {

    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @org.springframework.web.bind.annotation.ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    @ResponseBody
    public Map<String, Object> handleError() {
        Map<String, Object> errorMap = new HashMap<String, Object>();
        errorMap.put("message", "許可されていないメソッド");
        errorMap.put("status", HttpStatus.METHOD_NOT_ALLOWED);
        return errorMap;
    }
}

その他

Controllerを横断して例外をハンドリングする場合の例外ハンドリング用のクラスと、Controller個別で例外をハンドリングする場合のControllerクラスの双方で同じハンドリング処理があった場合、Controller個別で例外をハンドリングをする方が優先される。

参考

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling
http://m12i.hatenablog.com/entry/2014/10/29/010801

127
128
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
127
128