zoukankan      html  css  js  c++  java
  • spring mvc4:异常处理

    前面学习过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     @Override
    16     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     @Override
    29     public void postHandle(HttpServletRequest request,
    30             HttpServletResponse response, Object handler,
    31             ModelAndView modelAndView) throws Exception {
    32         System.out.println("ExcpetionInterceptor.postHandle");
    33     }
    34 
    35     @Override
    36     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     @Override
    47     public void afterConcurrentHandlingStarted(HttpServletRequest request,
    48             HttpServletResponse response, Object handler) throws Exception {
    49         System.out
    50                 .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方法中,如果要根据不同的异常类型转到不同处理页面,并不方便。

    附:ajax的统一异常处理,请移步 Struts2、Spring MVC4 框架下的ajax统一异常处理

  • 相关阅读:
    linux中实现将多个连续的字符拆分为单个字符
    linux 中删除当前目录下指定文件外所有的文件
    linux中将指定行数据合并为一行数据
    gz文件压缩、解压缩保留源文件
    R语言中提取多个连续值的累计的中间位点
    .net的委托和事件的直接理解
    消息是什么
    显示进度条的无组件上传!!
    与Java相关的四十个名字
    循环为Label赋值!
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/spring-mvc-exception-handle.html
Copyright © 2011-2022 走看看