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

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

     
其实这种错误对于客户来说毫无意义,因为他们通常是看不懂这是什么意思的。
刚学java的时候,我们处理异常通常两种方法:
①   直接throws,放任不管;
②    写try...catch,在catch块中不作任何操作,或者仅仅printStackTrace()把异常打印到控制台。
第一种方法最后就造就了上图的结果(不符合操作);而第二种方法更不好:页面不报错,但是也不执行用户的请求,简单的说,其实这就是bug。
那么发生异常到底应该怎么办呢?我想在大家对java异常有一定了解以后,会知道:异常应该在action控制转发之前尽量处理,同时记录log日志,然后在页面以友好的错误提示告诉用户出错了,如。
然后我们回到刚才处理异常的地方,如果大家积累了一些项目经验以后会发现使用上面那种处理异常的方式可能还不够灵活:
①因为spring把大多数非运行时异常都转换成运行时异常(RuntimeException)最后导致程序员根本不知道什么地方应该进行try...catch操作
②每个方法都重复写try...catch,而且catch块内的代码都很相似,这明显做了很多重复工作而且还很容易出错。
使用truts2拦截器定义异常拦截器用来解决上述问题,如下图所示:

   
首先我的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. <global-results>
  13. <result name="errorMsg">/errorMsg.jsp</result>
  14. </global-results>
  15. <global-exception-mappings>
  16. <exception-mapping result="errorMsg" exception="java.lang.Exception"></exception-mapping>
  17. </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

Struts2拦截器实现异常处理相关推荐

  1. Struts2拦截器实现异常处理机制

    http://bbs.itcast.cn/thread-10364-1-1.html Struts2拦截器实现异常处理机制   在j2ee项目中,系统内部难免会出现一些异常,如果把异常放任不管直接打印 ...

  2. Struts2 拦截器(Interceptor )原理和配置

    Struts2 拦截器 拦截器在概念上与servlet过滤器或JDK代理类相同.拦截器允许横切功能,把action以及框架分开实现.你可以使用拦截器实现以下操作: 在调用action之前提供预处理逻辑 ...

  3. Struts2拦截器的使用

    如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了str ...

  4. SpringMVC拦截器与异常处理

    SpringMVC拦截器与异常处理 参考文章: (1)SpringMVC拦截器与异常处理 (2)https://www.cnblogs.com/luckgood/p/9724057.html 备忘一下 ...

  5. SpringMVC——自定义拦截器、异常处理以及父子容器配置

    SpringMVC--自定义拦截器.异常处理以及父子容器配置 参考文章: (1)SpringMVC--自定义拦截器.异常处理以及父子容器配置 (2)https://www.cnblogs.com/so ...

  6. Struts2拦截器属性excludeMethods、includeMethods配置无效之解决方法

    参考:http://blog.csdn.net/coolcoffee168/article/details/7963251 在配置struts2 拦截器属性excludeMethods.include ...

  7. Struts2 拦截器 及如何获得 servlet 请求对象 以及Struts 基本配置 Session 超时设置...

    在拦截器中可以三种实现 一:继承 AbstractInterceptor 类 二:继承 MethodFilterInterceptor类 三:实现 Interceptor 接口 在实现Intercep ...

  8. 基于struts2拦截器实现用户操作日志记录

    2019独角兽企业重金招聘Python工程师标准>>> 这里基于struts2的拦截器来实现. 使用struts2拦截器拦截所有或者指定的请求,对用户操作过程中的:操作用户,操作时间 ...

  9. 从struts2拦截器到自定义拦截器

    http://www.cnblogs.com/withyou/p/3170440.html 拦截器可谓struts2的核心了,最基本的bean的注入就是通过默认的拦截器实现的,一般在struts2.x ...

  10. SpringMVC自定义拦截器与异常处理(自定义异常)

    SpringMVC自定义拦截器与异常处理 拦截器概念 拦截器代码演示 创建maven工程 pom.xml <?xml version="1.0" encoding=" ...

最新文章

  1. MySQL中REGEXP正则查询同一个字段模糊搜索
  2. 《Elasticsearch 权威指南》阅读笔记
  3. go预防CSRF攻击
  4. python——logging模块
  5. 事件捕获(capture)和冒泡事件(Bubble)
  6. 均值文件转matlab,LMD局域均值分解的matlab程序及示例代码
  7. C++编程语言中整型转换为字符串类型的方法
  8. 汇编语言编写Hello World
  9. Ubuntu 安装微信,网页版无法登陆
  10. [Error] ‘for‘ loop initial declarations are only allowed in C99 or C11 mode 解决方法
  11. 计算机专硕日语考研学校排名,日语考研院校排名(日语专硕学校排名)
  12. 小米node2红外_小米监控open-falcon-0.2安装部署详细配置
  13. 228句最常用英文口语短句(转)
  14. 墙面有几种装修方法_墙面装修有哪几种常见方法?
  15. java什么时候触发gc_什么时候触发 GC
  16. Git冲突:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed.
  17. -webkit-tap-highlight-color
  18. Path环境变量是什么?有什么用?怎么工作?JDK,JRE,JVM,集成开发工具是什么?有什么用?怎么工作?JDK安装包文件结构?有必要设置Path环境变量?Eclipse和IDEA开发工具的运作
  19. c位边上还有什么位_章泽天聚会站边位,被称太委屈,看清C位的万宝宝后就明白了...
  20. XXL-JOB配置迁移到Nacos Could not resolve placeholder ‘xxl.job.accessToken’ in value “${xxl.job.accessToke

热门文章

  1. AHCI驱动问题导致Windows 10卡死的解决办法
  2. 【广东大学生网络攻防大赛-WriteUp(非官方)】Crypto | crypto-xor2
  3. 静态HTML网页设计作品 DIV布局 HTML5+CSS大作业——个人网页(6页) 网页制作期末大作业成品
  4. win7 win8 64位系统上装CAD2008挂燕秀外挂的办法
  5. 弘辽科技:掌握淘宝直通车的工作原理很有必要!其核心是什么?
  6. R语言将两个矩阵数据进行相乘
  7. vue可拖拽悬浮按钮组件
  8. 2023年东南大学机械工程考研考情与难度、参考书上岸前辈备考经验
  9. 搜索引擎为什么不收录原创文章
  10. 如何隐藏电脑下方工具栏个别图标_小编教你电脑如何隐藏任务栏图标