spring mvc4:异常处理

来源:互联网 发布:金九银十原油利多数据 编辑:程序博客网 时间:2024/06/15 16:20

前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理:

一、Servlet配置文件修改

复制代码
1     <bean id="exceptionResolver"2         class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">3         <property name="defaultErrorView" value="errors/error" />        4         <property name="exceptionMappings">5             <props>6                 <prop key="java.lang.Throwable">errors/error</prop>7             </props>8         </property>9     </bean> 
复制代码

增加上面这一节,大意是:只要有异常就跳到/WEB-INF/views/errors/error.jsp这个页面,当然如果要实现个性化的错误处理,比如:业务错误跳到页面A,SQL错误跳到页面B...,直接在props节点下,根据不同的异常类型,自行扩充 (注:404之类的错误,仍然参考struts2异常处理中的做法,在web.xml中配置解决)

 

二、创建一个BaseController基类,里面放一个以下方法:

复制代码
 1     @ExceptionHandler 2     public String exp(HttpServletRequest request, Exception ex) { 3         String resultViewName = "errors/error"; 4  5         // 记录日志 6         logger.error(ex.getMessage(), ex); 7  8         // 根据不同错误转向不同页面 9         if (ex instanceof BusinessException) {10             resultViewName = "errors/biz-error";11         } else {12             // 异常转换13             ex = new Exception("系统太累了,需要休息!");14         }15         request.setAttribute("ex", ex);16         return resultViewName;17     }
复制代码

记录异常日志、根据不同的异常类型转到不同的处理页面、友好异常转换(如果需要的话),都在上面的方法中处理了

 

三、所有Controller都继承自BaseController

这个,就不解释了

 

四、error.jsp页面

复制代码
 1 <%@ page contentType="text/html;charset=UTF-8" language="java"%> 2 <% 3     Exception e = (Exception) request.getAttribute("ex"); 4 %> 5 <html> 6 <head> 7 <title>师傅,有妖怪:error</title> 8 </head> 9 <body>10     <H2>11         错误:<%=e.getClass().getSimpleName()%></H2>12     <hr />13     <P>14         <strong>错误描述:</strong><%=e.getMessage()%>15     </P>16     17     <P>18         <strong>详细信息:</strong>19     </P>20     <pre>21     <%22         e.printStackTrace(new java.io.PrintWriter(out));23     %>24     </pre>25 </body>26 </html>
复制代码

上面的内容只是示意,大家可以根据需要自行美化

 

另:前文struts2的异常处理中,采用的是拦截器思想,spring mvc中也有拦截器,而且拦截的点更灵活:

复制代码
 1 package com.cnblogs.yjmyzz.interceptor; 2  3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5  6 import org.apache.logging.log4j.LogManager; 7 import org.apache.logging.log4j.Logger; 8 import org.springframework.web.servlet.ModelAndView; 9 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;10 11 public class ExcpetionInterceptor extends HandlerInterceptorAdapter {12 13     protected Logger logger = LogManager.getLogger();14 15     @Override16     public boolean preHandle(HttpServletRequest request,17             HttpServletResponse response, Object handler) throws Exception {18         System.out.println("ExcpetionInterceptor.preHandle");19         // 演示:限制仅允许从本机访问20         if (request.getLocalAddr().equals("127.0.0.1")21                 || request.getLocalAddr().equals("0.0.0.0")) {22             return true;23         }24         logger.error("非法入侵:" + request.getLocalAddr());25         return false;26     }27 28     @Override29     public void postHandle(HttpServletRequest request,30             HttpServletResponse response, Object handler,31             ModelAndView modelAndView) throws Exception {32         System.out.println("ExcpetionInterceptor.postHandle");33     }34 35     @Override36     public void afterCompletion(HttpServletRequest request,37             HttpServletResponse response, Object handler, Exception ex)38             throws Exception {39         System.out.println("ExcpetionInterceptor.afterCompletion");40         if (ex != null) {41             logger.error(handler);42             logger.error(ex.getMessage(), ex);43         }44     }45 46     @Override47     public void afterConcurrentHandlingStarted(HttpServletRequest request,48             HttpServletResponse response, Object handler) throws Exception {49         System.out50                 .println("ExcpetionInterceptor.afterConcurrentHandlingStarted");51     }52 53 }
复制代码

拦截器创建后,依然要在servlet配置文件中注册:

    <mvc:interceptors>        <bean class="com.cnblogs.yjmyzz.interceptor.ExcpetionInterceptor"></bean>    </mvc:interceptors>

spring mvc的拦截器提供了4个处理方法:

preHandle在Controller被调用前,先执行,可以在这里执行一些安全检查(上面示意了如何对IP做限制)

postHandle在Controller调用后执行,这时,可以修改ModelAndView,比如转到其它view之类

afterCompletion在Controller调用全部完成后执行,如果ex变量不为空,表示有异常了,这里可以记录异常日志

afterConcurrentHandlingStarted这个没怎么研究过,暂时不做评价

值得一提的是:spring-mvc中的拦截器,虽然可以在afterCompletion中记录异常日志,但如果按前面的baseController配合@ExceptionHandler做了处理,这里的ex就变成了null,因为异常在前面已经得到了处理,所以这二种方法不推荐混用,另外afterCompletion方法中,如果要根据不同的异常类型转到不同处理页面,并不方便。

原创粉丝点击