Spring MVC Catch the exceptions thrown by view page

摘要: Here’s the scenario, the controller returns a ModelAndView, and an exception is thrown while rendering the JSP view page, reason behind is one of message code is not found.

Here’s the scenario, the controller returns a ModelAndView, and an exception is thrown while rendering the JSP view page, reason behind is one of message code is not found.

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)

An exception is thrown and render an HTTP 500 error page directly.

1. Problem

Declared an exception handler globally, but still unable to catch the 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. Solution

No, you can’t catch the exception which is thrown by the view page. The @ExceptionHandler is used to catch the exceptions thrown by the Controller class only.

The best you can do is defined an error page in web.xml

web.xml
	<!-- This will catch Http 500 error -->
	<error-page>
	    <error-code>500</error-code>
	    <location>/WEB-INF/views/jsp/error.jsp</location>
	</error-page>
	<!-- This will catch any exception -->
	<error-page>
	    <location>/WEB-INF/views/jsp/error.jsp</location>
	</error-page>
Note
Tell me if you have a better solution :)

3. Servlet Filter

Alternatively, you can create a filter and intercepts the entire requests on your web application. If any exceptions are thrown, log it or do whatever you want.

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

To register above filter, declares it in web.xml

web.xml
	<!-- must register this, else WebApplicationContext not found -->
	<listener>
		<listener-class>
                     org.springframework.web.context.ContextLoaderListener
                </listener-class>
	</listener>
	<filter>
		<filter-name>errorHandlerFilter</filter-name>
		<filter-class>com.mkyong.form.web.ErrorHandleFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>errorHandlerFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

Or declares it in an initializer class.

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

References

  1. Exception Handling in Spring MVC
  2. How to register a servlet filter in Spring MVC

上一篇: HSQL identify auto increase ID
下一篇: How to register a servlet filter in Spring MVC
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号