Рубрики
Без рубрики

Spring MVC – Перехватывать исключения, создаваемые страницей просмотра

– Spring MVC – Перехватывать исключения, создаваемые страницей просмотра

Вот сценарий, контроллер возвращает ModelAndView, и при отображении страницы представления JSP возникает исключение, причина которого заключается в том, что код сообщения не найден.

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 используется только для перехвата исключений, создаваемых классом контроллера.

Лучшее, что вы можете сделать, это определить страницу с ошибкой в web.xml

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

3. Фильтр сервлетов

Кроме того, вы можете создать фильтр и перехватывать все запросы в своем веб-приложении. Если возникнут какие-либо исключения, зарегистрируйте их или делайте все, что хотите.

package com.mkyong.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.mkyong.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

	
	
		
                     org.springframework.web.context.ContextLoaderListener
                
	
	
	
		errorHandlerFilter
		com.mkyong.form.web.ErrorHandleFilter
	
	
		errorHandlerFilter
		/*
	

Или объявляет его в классе инициализатора.

package com.mkyong.form.config.servlet3;
 
import javax.servlet.Filter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.mkyong.form.web.ErrorHandleFilter;
 
public class MyWebInitializer extends
	AbstractAnnotationConfigDispatcherServletInitializer {
 
	//...
 
	@Override
	protected Filter[] getServletFilters() {
		return new Filter[]{new ErrorHandleFilter()};
	}
}

Рекомендации

  1. Обработка исключений в Spring MVC
  2. Как зарегистрировать фильтр сервлетов в Spring MVC

Оригинал: “https://mkyong.com/spring-mvc/spring-mvc-catch-the-exceptions-thrown-by-view-page/”