Spring MVC - ビューページでスローされた例外をキャッチします.

Spring MVC –ビューページによってスローされた例外をキャッチする

シナリオは次のとおりです。コントローラーはModelAndViewを返し、JSPビューページのレンダリング中に例外がスローされます。理由は、メッセージコードの1つが見つからないためです。

org.apache.jasper.JasperException: org.springframework.context.NoSuchMessageException:
    No message found under code 'Diff.userform.password' for locale 'en_US'.

    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

例外がスローされ、HTTP 500エラーページが直接表示されます。

1. 問題

グローバルに例外ハンドラーを宣言しましたが、それでもNoSuchMessageExceptionをキャッチできませんか?

@ControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest req,
               Exception e) throws Exception {

        logger.error("[URL] : {}", req.getRequestURL(), e);

        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.addObject("url", req.getRequestURL());
        mav.setViewName("error"");
        return mav;
    }

}

2. 溶液

いいえ、ビューページによってスローされる例外をキャッチできません。 @ExceptionHandlerは、Controllerクラスによってスローされた例外をキャッチするためにのみ使用されます。

あなたができる最善のことは、web.xmlでエラーページを定義することです

web.xml

    
    
        500
        /WEB-INF/views/jsp/error.jsp
    

    
    
        /WEB-INF/views/jsp/error.jsp
    

Note
より良い解決策があるかどうか教えてください:)

3. サーブレットフィルター

または、フィルタを作成して、Webアプリケーションのリクエスト全体をインターセプトできます。 例外がスローされた場合は、ログに記録するか、必要な操作を行います。

package com.example.form.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.example.form.service.UserService;

public class ErrorHandleFilter implements Filter {

    private final Logger logger = LoggerFactory.getLogger(ErrorHandleFilter.class);

    //Your custom bean to handle error
    ErrorHandlerSpecialForce errHandle;

    @Override
    public void destroy() {
        // ...
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //Get bean from Spring container
        errHandle = (ErrorHandlerSpecialForce) WebApplicationContextUtils
          .getRequiredWebApplicationContext(filterConfig.getServletContext())
                  .getBean("errorHandlerSpecialForce");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain)
            throws IOException, ServletException {

        try {
                        // your code, do whatever
            errHandle.handle(request, response);

            chain.doFilter(request, response);

        } catch (Exception ex) {

            logger.error("Error : {}", ex); //log it
            request.setAttribute("errorMessage", ex);
            request.getRequestDispatcher("/WEB-INF/views/jsp/error.jsp")
                .forward(request, response);

        }

    }

}

上記のフィルターを登録するには、web.xmlで宣言します

web.xml

    
    
        
                     org.springframework.web.context.ContextLoaderListener
                
    

    
        errorHandlerFilter
        com.example.form.web.ErrorHandleFilter
    
    
        errorHandlerFilter
        /*
    

または、初期化クラスで宣言します。

package com.example.form.config.servlet3;

import javax.servlet.Filter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.example.form.web.ErrorHandleFilter;

public class MyWebInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

    //...

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{new ErrorHandleFilter()};
    }
}