Tomcatを埋め込みWebコンテナとして使用して、Spring 4.0.4およびSpring Boot 1.0.2でWebアプリケーションを作成しています。すべての例外をインターセプトし、特定の方法でログに記録するグローバルな例外処理を実装します。私の簡単な要件は次のとおりです。
これまでのところ、私の解決策は次のようになります(単純化され、ログ記録もエラービューへのリダイレクトもない)。
@Controller
@RequestMapping("/errors")
public class ErrorHandler implements EmbeddedServletContainerCustomizer
{
@Override
public void customize(final ConfigurableEmbeddedServletContainer factory)
{
factory.addErrorPages(new ErrorPage("/errors/unexpected"));
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/notfound"));
}
@RequestMapping("unexpected")
@ResponseBody
public String unexpectedError(final HttpServletRequest request)
{
return "Exception: " + request.getAttribute("javax.servlet.error.exception");
}
@RequestMapping("notfound")
@ResponseBody
public String notFound()
{
return "Error 404";
}
}
その結果、コントローラーでスローされた例外はunexpectedError
メソッドによって正しく処理され、404ステータスコードはnotFound
メソッドによって処理されます。これまでのところは良いですが、次の問題があります。
javax.servlet.error.exception
からifを取得します。そして、それはスローされた例外でさえありません。それはorg.springframework.web.util.NestedServletException
のインスタンスであり、実際の例外を取得するにはこのネストされた例外に飛び込む必要があります。もっと簡単な方法があると確信していますが、見つけることができません。これらの問題をどのように解決できますか?それとも、このグローバル例外ハンドラを実装した方法が完全に間違っており、より良い代替手段がありますか?
ControllerAdviceをご覧ください次のようなことができます:
@ControllerAdvice
public class ExceptionHandlerController {
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = {Exception.class, RuntimeException.class})
public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) {
ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
mav.addObject("datetime", new Date());
mav.addObject("exception", e);
mav.addObject("url", request.getRequestURL());
return mav;
}
}