spring mvc 异常处理(转)
链接:http://gaojiewyh.iteye.com/blog/1297746 (附源码)
链接:http://zywang.iteye.com/blog/983801
链接:http://www.cnblogs.com/xguo/p/3163519.html
链接:http://fuliang.iteye.com/blog/947191
链接:http://blog.csdn.net/FansUnion/article/details/17038103
链接:http://cgs1999.iteye.com/blog/1547197(附源码)
Spring3.0对异常的处理通过HandlerExceptionResolver来实现。HandlerExceptionResolver有4个实现类DefaultHandlerExceptionResolver、AnnotationMethodExceptionResolver、ResponseStatusExceptionResolver、SimpleMappingExceptionResolver。
Spring3.0对异常的处理主要可通过这两种方式:一种是使用HandlerExceptionResolver接口;一种是在@Controller处理器内部使用@ExceptionHandler注解。使用第一种方式可以实现全局异常控制,并且Spring已经提供了一个默认的实现类SimpleMappingExceptionResolver;使用第二种方式可以在Controller内部实现更个性化异常处理方式。
---方式一:HandlerExceptionResolver接口,复写resolveException()方法
springmvc通过HandlerExceptionResolver处理程序的异常,该接口仅有一个方法ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)。我们可复写该方法实现全局异常的处理。
当发生异常时,springmvc会调用resolveException()方法,并返回一个ModelAndView对象。如果该方法返回了null,Spring会搜索所有注册在其环境中的实现了HandlerExceptionResolver接口的Bean,逐个执行,直到返回一个ModelAndView对象,最后转到ModelAndView对应的视图作为一个异常报告页面!
- /**
- * 基于HandlerExceptionResolver接口的异常处理类
- * 这个类必须声明到Spring中去,让Spring管理它,你可以使用@Component标签:
- * <context:component-scan base-package="test.*" />
- * 或者使用在配置文件通过<bean/>节点配置:
- * <bean id="exceptionResolver" class="test.CustomExceptionHandler "/>
- */
- @Component
- public class CustomExceptionHandler implements HandlerExceptionResolver {
- @Override
- public ModelAndView resolveException(HttpServletRequest request,
- HttpServletResponse response, Object object, Exception exception) {
- if(exception instanceof IOException){
- return new ModelAndView("ioexp");
- }else if(exception instanceof SQLException){
- return new ModelAndView("sqlexp");
- }
- return null;
- }
- }
---区分ajax请求和普通http请求进行异常处理返回:
- /**
- * 代码2:
- * 说明:当在系统应用中出现普通异常时,根据是系统异常还是应用异常,跳到相应的界面,
- * 当ajax异常时,在ajax的error中可直接获得异常。普通的异常我们都配置好了界面,系统会自动跳转。
- */
- public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {
- @Override
- protected ModelAndView doResolveException(HttpServletRequest request,
- HttpServletResponse response, Object handler, Exception ex) {
- // Expose ModelAndView for chosen error view.
- String viewName = determineViewName(ex, request);
- if (viewName != null) {// JSP格式返回
- if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
- .getHeader("X-Requested-With")!= null && request
- .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
- // 如果不是异步请求
- // Apply HTTP status code for error views, if specified.
- // Only apply it if we're processing a top-level request.
- Integer statusCode = determineStatusCode(request, viewName);
- if (statusCode != null) {
- applyStatusCodeIfPossible(request, response, statusCode);
- }
- return getModelAndView(viewName, ex, request);
- } else {// JSON格式返回
- try {
- PrintWriter writer = response.getWriter();
- writer.write(ex.getMessage());
- writer.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- } else {
- return null;
- }
- }
- }
---方式二:@ExceptionHandler
AnnotationMethodExceptionResolver:springmvc也默认配置了AnnotationMethodExceptionResolver,它允许通过@ExceptionHandler指定处理特定异常的方法。@ExceptionHandler:处理同一个类内触发的局部异常(如果要让其处理多个需拦截异常的处理器,则可另其他类继承此类!)
- @Controller
- //可以被其他处理器继承
- public class MyExceptionFilter {
- ...
- //该处理器类中的所有方法抛出的异常都可由此方法捕获并处理
- //该注解也可制定多个异常类,如@ExceptionHandler(value={IOException.class,SQLException.class})
- @ExceptionHandler(Exception.class)
- public String handleException(Exception e, HttpServletRequest req) {
- System.out.println("exception name: " + e.getClass().toString());//异常名
- System.out.println("exception cause: " + e.getCause());
- System.out.println("exception msg: " + e.getLocalizedMessage());
- //e.printStackTrace();
- StackTraceElement[] ste = e.getStackTrace();
- StringBuffer sb_e = new StringBuffer();
- for(int j=0;j<ste.length;j++){
- if(ste[j].toString().contains("xxxx")) {
- sb_e.append(ste[j].toString()+", ");
- }
- }
- System.out.println("Exception detail: ");//异常详细信息
- System.out.println(sb_e.toString());
- StringBuffer sbUrl = new StringBuffer();//拼url
- System.out.println("request method: "+req.getMethod());//get,post
- System.out.println("request encode: " + req.getCharacterEncoding());//编码
- System.out.println("request mapping: "+req.getRequestURL().toString());//请求url方法
- sbUrl.append(req.getRequestURL().toString());
- Enumeration en = req.getParameterNames();//请求参数-值
- for(int i=0; en.hasMoreElements(); i++){
- String arg = en.nextElement().toString();
- if(i==0){
- sbUrl.append("?");
- }else{
- sbUrl.append("&");
- }
- sbUrl.append(arg + "=" + req.getParameterValues(arg)[0]);
- }
- System.out.println("request url: " + sbUrl.toString());
- // if(ex instanceof BusinessException) {
- // return "error-business";
- // }else if(ex instanceof ParameterException) {
- // return "error-parameter";
- // } else {
- // return "error";
- // }
- return "forward:error.jsp";
- }
- }
---方式三:SimpleMappingExceptionResolver
SimpleMappingExceptionResolver:可对全局异常进行统一处理。
- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
- <!--设置日志输出级别,不定义则默认不输出警告等错误日志信息。链接:http://elf8848.iteye.com/blog/875830 -->
- <property name="warnLogCategory" value="WARN" />
- <!-- 默认错误页面,就是不在exceptionMappings指定范围内 -->
- <property name="defaultErrorView" value="error"></property>
- <!-- 定义需要特殊处理的异常,如当发生IOException异常时跳转到error/ioexp视图-->
- <property name="exceptionMappings"><span style="font-family: Arial, Helvetica, sans-serif;"><!—key为异常类,可以是全路径,错误页面或Controller路径!会自动跳转到对应url --></span>
- <props>
- <prop key="IOException">redirect:/login</prop>
- <prop key="java.sql.SQLException">error/sqlexp</prop>
- </props>
- </property>
- </bean>
---方式四:<error-page>
DefaultHandlerExceptionResolver:Springmvc默认装配了DefaultHandlerExceptionResolver,它会将springmvc的异常转换成对应的响应状态码(500,404等)。对于Unchecked Exception而言,由于代码不强制捕获,往往被忽略,如果运行期产生了Unchecked Exception,而代码中又没有进行相应的捕获和处理,则我们可能不得不面对尴尬的404、500……等服务器内部错误提示页面。
我们需要一个全面而有效的异常处理机制。目前大多数服务器也都支持在web.xml中通过<error-page>(Websphere/Weblogic)或者<error-code>(Tomcat)节点配置特定异常情况的显示页面。(springmvc)操作如下:
1.在web.xml中配置响应状态码对应的页面,如:
- <error-page>
- <error-code>500</error-code>
- <location>/WEB-INF/pages/error/500.jsp</location>
- </error-page>
- <!-- 未捕获的错误,同样可指定其它异常类,或自定义异常类 -->
- <error-page>
- <exception-type>java.lang.Exception</exception-type>
- <location>/uncaughtException</location>
- </error-page>
2. applicationContext.xml中配置
- <!-- 错误路径和错误页面,注意指定viewResolver -->
- <mvc:view-controller path="/404" view-name="404"/>
- <mvc:view-controller path="/500" view-name="500"/>
- <mvc:view-controller path="/uncaughtException" view-name="uncaughtException"/>
附:https://www.google.com.hk/search?newwindow=1&safe=strict&espv=210&es_sm=93&q=error+page%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8&revid=601630396&sa=X&ei=ORwOU7K_INKbiQeTjIG4BA&ved=0CIcBENUCKAE&biw=1440&bih=737
---方式五:Spring3.2新注解@ControllerAdvice
链接:http://jinnianshilongnian.iteye.com/blog/1866350
@ControllerAdvice,是spring3.2提供的新注解。会把@ControllerAdvice注解内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法(全局的)
有一次发现springmvc3.2.x的@ControllerAdvice注解不起作用,参考链接http://www.07net01.com/linux/spring3_2_mvc__ControllerAdvice_buqizuoyong_554229_1375786240.html加上@EnableWebMvc后就可以了。但是,后来又发现会导致这个原因是因为项目的springmvc配置文件中没有配置<mvc:annotation-driven />,于是将其配置上。但是配置上<mvc:annotation-driven />后问题就来了,启动的时候就报异常,看了下原因,感觉是@EnableWebMvc注解导致的,于是将该注解删除掉,果然就正常启动了。不过,至于其中的原理还是理解不深刻,不知道内部是怎么调用的,只是发现当配置上<mvc:annotation-driven />的时候不应该用@EnableWebMvc修饰@ControllerAdvice。(待研究)附链接:http://hahalq.iteye.com/blog/1738599。http://www.yulezhandian.com/?p=196。
测试后发现,当全局异常和局部异常都存在时,全局异常处理会被局部异常处理覆盖。
- /**
- * 全局异常
- */
- //@EnableWebMvc
- @ControllerAdvice
- public class MyExceptionHandler {
- @ExceptionHandler(Exception.class)
- public String handleException(Exception re, HttpServletRequest request) {
- System.out.println("error.......");
- return "forward:error.jsp";
- }
- }
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐