Spring MVC - Fange die Ausnahmen, die von der Ansichtsseite ausgelöst werden

Spring MVC - Erfassen Sie die von der Ansichtsseite ausgelösten Ausnahmen

In diesem Szenario gibt der Controller ein ModelAndView zurück, und beim Rendern der JSP-Ansichtsseite wird eine Ausnahme ausgelöst. Grund dafür ist, dass der Nachrichtencode nicht gefunden wurde.

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)

Eine Ausnahme wird ausgelöst und eine HTTP 500-Fehlerseite wird direkt gerendert.

1. Problem

Weltweit einen Ausnahmebehandler deklariert, aber immer noch nicht in der Lage, dieNoSuchMessageException abzufangen?

@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. Lösung

Nein, Sie können die von der Ansichtsseite ausgelöste Ausnahme nicht abfangen. Mit@ExceptionHandler werden nur die von der Controller-Klasse ausgelösten Ausnahmen abgefangen.

Das Beste, was Sie tun können, ist, eine Fehlerseite inweb.xml zu definieren

web.xml

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

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

Note
Sag mir, ob du eine bessere Lösung hast :)

3. Servlet-Filter

Alternativ können Sie einen Filter erstellen und die gesamten Anforderungen in Ihrer Webanwendung abfangen. Wenn Ausnahmen ausgelöst werden, protokollieren Sie diese oder tun Sie, was Sie wollen.

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);

        }

    }

}

Um den obigen Filter zu registrieren, wird er inweb.xml deklariert

web.xml

    
    
        
                     org.springframework.web.context.ContextLoaderListener
                
    

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

Oder deklariert es in einer Initialisierungsklasse.

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()};
    }
}