Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 6408|回复: 0

spring mvc4:异常处理

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-16 13:49:43 | 显示全部楼层 |阅读模式

    前面学习过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统一异常处理

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 15:45 , Processed in 0.064395 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表