Struts2拦截器实现异常处理[通俗易懂]

Struts2拦截器实现异常处理[通俗易懂]Struts2拦截器实现异常处理机制在j2ee项目中,系统内部难免会出现一些异常,如果把异常放任不管直接打印到浏览器可能会让用户感觉莫名其妙,也有可能让某些用户找到搞定系统的方法。所以不要在页面上输出错误信息,使用log日志的方式处理异常并记录异常。就拿struts2+hibernate+spring项目说明:通常一个页面请求到后台以后,首先是到action(也就是所谓mvc的c

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

Struts2
拦截器实现
异常处理机制
在j2ee项目中,系统内部难免会出现一些异常,如果把异常放任不管直接打印到浏览器可能会让用户感觉莫名其妙,也有可能让某些用户找到搞定系统的方法。 所以不要在页面上输出错误信息,使用log日志的方式处理异常并记录异常。
就拿struts2+hibernate+spring项目说明:通常一个页面请求到后台以后,首先是到action(也就是所谓mvc的controller),在action层会调用业务逻辑service,servce层会调用持久层dao获取数据。最后执行结果会汇总到action,然后通过action控制转发到指定页面,执行流程如下图所示:


Struts2拦截器实现异常处理[通俗易懂]
而这三层其实都有可能发生异常,比如dao层可能会有SQLException,service可能会有NullPointException,action可能会有IOException,一但发生异常并且程序员未做处理,那么该层不会再往下执行,而是向调用自己的方法抛出异常,如果dao、service、action层都未处理异常的话,异常信息会抛到服务器,然后服务器会把异常直接打印到页面,结果就会如下图所示:


Struts2拦截器实现异常处理[通俗易懂]     


其实这种错误对于客户来说毫无意义,因为他们通常是看不懂这是什么意思的。
刚学java的时候,我们处理异常通常两种方法:
①   直接throws,放任不管;
②    写try…catch,在catch块中不作任何操作,或者仅仅printStackTrace()把异常打印到控制台。
第一种方法最后就造就了上图的结果(不符合操作);而第二种方法更不好:页面不报错,但是也不执行用户的请求,简单的说,其实这就是bug。
那么发生异常到底应该怎么办呢?我想在大家对java异常有一定了解以后,会知道:异常应该在action控制转发之前尽量处理,同时记录log日志,然后在页面以友好的错误提示告诉用户出错了,如。
Struts2拦截器实现异常处理[通俗易懂]


然后我们回到刚才处理异常的地方,如果大家积累了一些项目经验以后会发现使用上面那种处理异常的方式可能还不够灵活:
①因为spring把大多数非运行时异常都转换成运行时异常(RuntimeException)最后导致程序员根本不知道什么地方应该进行try…catch操作
②每个方法都重复写try…catch,而且catch块内的代码都很相似,这明显做了很多重复工作而且还很容易出错。
使用truts2拦截器定义异常拦截器用来解决上述问题,如下图所示:


Struts2拦截器实现异常处理[通俗易懂]   
首先我的action类、service类和dao类如果有必要捕获异常,我都会try…catch,catch块内不记录log,通常是抛出一个新异常,并且注明错误信息,有拦截器来抛出异常信息,并写入log日志文件:


  1. Java代码
  2. //action层执行数据添加操作   
  3. public String save(){   
  4.    try{   
  5.          //调用service的save方法   
  6.          service.save(obj);   
  7.    }catch(Exception e){    
  8.       throw new RuntimeException(“添加数据时发生错误!”,e);   
  9.   }   
  10.    return “success”;   
  11. }  

复制代码

Struts2自定义拦截器的操作:
在struts2的配置文件<package>下添加:


  1. <interceptors>
  2.                    <!– 声明拦截器 –>
  3.                    <interceptor name=”errorInterceptor” class=”cn.itcast.elec.util.ErrorInterceptor” />
  4.                    <!– 配置拦截器栈 –>
  5.                    <interceptor-stack name=”myErrorInterceptor”>
  6.                                <interceptor-ref name=”defaultStack” />
  7.                                <interceptor-ref name=”errorInterceptor” />
  8.                    </interceptor-stack>
  9. </interceptors>
  10. <!– 覆盖底层的拦截器栈 对包中的所有action都有效 –>
  11. <default-interceptor-ref name=”myErrorInterceptor”/>
  12.             
  13.             <global-results>
  14.                     <result name=”errorMsg”>/errorMsg.jsp</result>
  15.             </global-results>
  16.             <global-exception-mappings>
  17.                     <exception-mapping result=”errorMsg” exception=”java.lang.Exception”></exception-mapping>
  18.         </global-exception-mappings>

复制代码

然后在异常拦截器对异常进行处理,看下面的代码:


拦截器的Java代码
  1. public class ErrorInterceptor implements Interceptor {


  2.         public void init() {


  3.         }

  4.         public String intercept(ActionInvocation actioninvocation) {


  5.                 String result = null; // Action的返回值   
  6.                 try {

  7.                         // 运行被拦截的Action,期间如果发生异常会被catch住   
  8.                         result = actioninvocation.invoke();
  9.                         return result;
  10.                 } catch (Exception e) {

  11.                         /**  
  12.                          * 处理异常  
  13.                          */
  14.                         String errorMsg = “出现错误信息,请查看日志!”;
  15.                         //通过instanceof判断到底是什么异常类型   
  16.                         if (e instanceof RuntimeException) {

  17.                                 //未知的运行时异常   
  18.                                 RuntimeException re = (RuntimeException) e;
  19.                                 //re.printStackTrace();
  20.                                 errorMsg = re.getMessage().trim();
  21.                         }
  22.                         //把自定义错误信息   
  23.                         HttpServletRequest request = (HttpServletRequest) actioninvocation
  24.                                         .getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
  25.                         /**  
  26.                          * 发送错误消息到页面  
  27.                          */
  28.                         request.setAttribute(“errorMsg”, errorMsg);

  29.                         /**  
  30.                          * log4j记录日志  
  31.                          */
  32.                         Log log = LogFactory
  33.                                         .getLog(actioninvocation.getAction().getClass());
  34.                         log.error(errorMsg, e);
  35.                         return “errorMsg”;
  36.                 }// …end of catch   
  37.         }

  38.         public void destroy() {


  39.         }
  40. }

复制代码

最后在errorMsg.JSP页面显示具体的错误消息即可:


   
  1. <body>   
  2. <s:if test=”%{#request.errorMsg==null}”>   
  3.     <p>对不起,系统发生了未知的错误,请查看日志</p>   
  4. </s:if>   
  5. <s:else>   
  6.     <p>${requestScope.errorMsg}</p>   
  7. </s:else>   
  8. </body>  

复制代码

以上方式可以拦截后台代码所有的异常,但如果出现数据库连接异常时不
能被捕获的,大家可以使用
struts2
的全局异常处理机制来处理:


Struts2
配置文件
代码
  1. <global-results>
  2.             <result name=”errorMsg”>/errorMsg.jsp</result>
  3. </global-results>
  4. <global-exception-mappings>
  5.                     <exception-mapping result=”errorMsg” exception=”java.lang.Exception”></exception-mapping>
  6. </global-exception-mappings>

复制代码

上面这是一个很简单的异常拦截器,大家可以使用自定义异常,那样会更灵活一些。

以上异常拦截器可以使用其它很多技术替换:比如spring aop,servlet filter等,根据项目实际情况处理。
辅助:
log4j.properties
文件的内容:
### direct log messages tostdout ###
log4j.appender.stdout=
org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=
System.out
log4j.appender.stdout.layout=
org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=
%d{ABSOLUTE}
 
%5p
 
%c
{1}
:
%L
 

 
%m%n
### direct messages to filehibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L – %m%n
### set log levels – for moreverbose logging change ‘info’ to ‘debug’ ###
log4j.rootLogger=
error,
 
stdout
#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
### log HQL query parseractivity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
#log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters###
#log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug
### log schema export/update###
#log4j.logger.org.hibernate.tool.hbm2ddl=debug
### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug
### log cache activity ###
#log4j.logger.org.hibernate.cache=debug
### log transaction activity
#log4j.logger.org.hibernate.transaction=debug
### log JDBC resourceacquisition
#log4j.logger.org.hibernate.jdbc=debug
### enable the following lineif you want to track down connection ###
### leakages when usingDriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
log4j.rootLogger= 
error,
 
A1,
 
R
log4j.appender.A1=
org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=
org.apache.log4j.PatternLayout
# Print the date in ISO 8601format
#log4j.appender.A1.layout.ConversionPattern=%d[%t] %-5p %c – %m%n
#log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss,SSS} %m%n
log4j.appender.A1.layout.ConversionPattern=
%d{yyyy-MM-dd
 
HH
:
mm:ss,SSS}
 
%l
 
“#”
 
%m%n
log4j.appender.R=
org.apache.log4j.RollingFileAppender
log4j.appender.R.File=
/elec.log
log4j.appender.R.MaxFileSize=
1000KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=
10
log4j.appender.R.layout=
org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=
%p
 
%t
 
%c
 

 
%m%n
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188570.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • DNS服务器的配置「建议收藏」

    DNS服务器的配置「建议收藏」DNS(DomainNameServer,域名服务器)是进行域名(domainname)和与之相对应的IP地址(IPaddress)转换的服务器。DNS中保存了一张域名(domainname)和与之相对应的IP地址(IPaddress)的表,以解析消息的域名。域名是Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。1、安装…

    2022年6月4日
    37
  • 超声波雷达应用总结「建议收藏」

    超声波雷达应用总结「建议收藏」超声波雷达应用总结超声波雷达简介超声波雷达的数学模型超声波雷达的特性超声波雷达配置情况无人驾驶中超声波主要的应用超声波雷达简介常见的超声波雷达有两种。第一种是安装在汽车前后保险杠上的,也就是用于测量汽车前后障碍物的倒车雷达,这种雷达业内称为UPA;第二种是安装在汽车侧面的,用于测量侧方障碍物距离的超声波雷达,业内称为APA。UPA超声波雷达UPA超声波雷达的探测距离一般在15~250cm之间,主要用于测量汽车前后方的障碍物。如下图所示,为单个UPA的探测范围示意图。APA超声波雷达A

    2022年9月12日
    0
  • 社会工程学三本_1.9万人报考,扩招近千人!被戏称为“大三本”的985——东南大学,低调有实力!…[通俗易懂]

    社会工程学三本_1.9万人报考,扩招近千人!被戏称为“大三本”的985——东南大学,低调有实力!…[通俗易懂]今天文章的“主角”是东南大学,著名的建筑老八校及原四大工学院之一,国家首批“211工程”、“985工程”、“双一流”A类世界一流大学建设高校。东南大学一流学科:材料科学与工程、电子科学与技术、信息与通信工程、控制科学与工程、计算机科学与技术、建筑学、土木工程、交通运输工程、生物医学工程、风景园林学、艺术学理论。一听到东南大学这个名字,很容易联系到东南电视台,东南汽车,所以东大人就自黑自己是“Hu建…

    2022年6月9日
    93
  • 数学建模之方差分析模型_数学建模层次分析法

    数学建模之方差分析模型_数学建模层次分析法《数学建模算法与应用》学习小结(11-20章)方差分析(AnalysisofVariance,ANOVA)应用场景单因素方差分析双因素方差分析方差分析(AnalysisofVariance,ANOVA)——用数理统计分析试验结果,鉴别各因素对结果影响程度的方法。人们关心的试验结果称为指标,试验中需要考察、可以控制的条件称为因素或因子,因素所处的状态称为水平应用场景为了使生产过…

    2022年10月15日
    0
  • Unity 地形高度图生成方法[通俗易懂]

    Unity 地形高度图生成方法[通俗易懂]Unity中地形(Terrain)高度图生成方法大概可以归纳为3类:手动绘制直接通过unity的terrain提供的工具手动绘制地形,让后导出成raw格式的高度图,这个没啥可说的,不会的话留言。。。PS等工具生成已经有现成的教程了就不详细描述了。老规则传送门如下:ps生成高度图当然你还可以用其他生成工具,生成raw格式的高度就行。通过noise调整高度图通过noise填充高度图,能够动图的生

    2022年5月26日
    58
  • h5文件怎么打开_h5下载文件

    h5文件怎么打开_h5下载文件用h5py的接口,只能帮你到这了

    2022年9月9日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号