jfinal统一的异常及日志处理的拦截器

最近在用轻量级Java web开发框架jfinal开发一个网站,由于网站是sns类型很多ajax交互请求。

考虑简化冗余代码,写了一个统一的异常及日志处理的拦截器。

自适配ajax请求和普通定向请求,输出错误信息。

直接上代码吧

  1. package com.smhaochi.web.interceptor;
  2. import java.util.Date;
  3. import java.util.Map;
  4. import java.util.Set;
  5. import javax.servlet.http.HttpServletRequest;
  6. import org.apache.commons.lang.StringUtils;
  7. import com.smhaochi.exception.BaseBussException;
  8. import com.smhaochi.model.ActionLog;
  9. import com.smhaochi.model.Menu;
  10. import com.smhaochi.vo.ActionLogVo;
  11. import com.smhaochi.web.controller.BaseController;
  12. import com.jfinal.aop.Interceptor;
  13. import com.jfinal.core.ActionInvocation;
  14. import com.jfinal.core.JFinal;
  15. import com.jfinal.log.Logger;
  16. /**
  17. * @title: 日志/异常处理拦截器
  18. * @className: ActionLogInterceptor
  19. * @description: TODO
  20. * @company: FOREVEROSS
  21. * @author: <a href="http://www.smhaochi.com">vakin jiang</a>
  22. * @createDate: 2014年4月2日
  23. * @version: 1.0
  24. */
  25. public class ExceptionAndLogInterceptor implements Interceptor {
  26. private static final Logger log = Logger.getLogger(ExceptionAndLogInterceptor.class);
  27. @Override
  28. public void intercept(ActionInvocation ai) {
  29. BaseController controller = (BaseController)ai.getController();
  30. HttpServletRequest request = controller.getRequest();
  31. boolean successed = false;
  32. try {
  33. ai.invoke();
  34. successed = true;
  35. } catch (Exception e) {
  36. //
  37. doLog(ai,e);
  38. //判断是否ajax请求
  39. String header = request.getHeader("X-Requested-With");
  40. boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header);
  41. String msg = formatException(e);
  42. if(isAjax){
  43. msg = new StringBuilder().append("{\"status\":\"0\",\"msg\":\"")
  44. .append(msg).append("\"}").toString();
  45. controller.renderJson(msg);
  46. }else{
  47. String redirctUrl = request.getHeader("referer");
  48. if(StringUtils.isBlank(redirctUrl)){
  49. redirctUrl = request.getRequestURI();
  50. }
  51. controller.setAttr("message", msg);
  52. controller.setAttr("redirctUrl",redirctUrl);
  53. controller.render("../public/failed.ftl");
  54. }
  55. }finally{
  56. //记录日志
  57. try {
  58. Menu menu = matchDefineRecordLogMenu(request);
  59. if(menu != null){
  60. ActionLogVo actionLog = controller.wrapActionLog();
  61. new ActionLog().set(ActionLog.ACT_NAME, menu.getName())//
  62. .set(ActionLog.ACT_TIME, new Date())//
  63. .set(ActionLog.DATA, actionLog.getData())//
  64. .set(ActionLog.IP, actionLog.getIp())//
  65. .set(ActionLog.SUCESSED, successed)//
  66. .set(ActionLog.URI, actionLog.getUri())//
  67. .set(ActionLog.USER_ID, actionLog.getUserId())//
  68. .set(ActionLog.USER_NAME, actionLog.getUserName())//
  69. .save();
  70. }
  71. } catch (Exception e2) {}
  72. }
  73. }
  74. /**
  75. * @methodName: matchDefineRecordLogMenu
  76. * @description: 匹配已定义需要记录日志的菜单
  77. * @author: vakinge
  78. * @createDate: 2014年4月3日
  79. * @param request
  80. * @return
  81. */
  82. private Menu matchDefineRecordLogMenu(HttpServletRequest request) {
  83. Map<String, Menu> menus = Menu.getAllUrlMenus();
  84. if(menus != null){
  85. String uri = request.getRequestURI();
  86. Set<String> urls = menus.keySet();
  87. for (String url : urls) {
  88. if(url == null)continue;
  89. //url匹配 && 有参数 && 已配置记录日志
  90. if(url.contains(uri)
  91. && request.getParameterNames().hasMoreElements()
  92. && menus.get(url).isRecordLog()){
  93. return menus.get(url);
  94. }
  95. }
  96. }
  97. return null;
  98. }
  99. /**
  100. * @methodName: doLog
  101. * @description: 记录log4j日志
  102. * @author: vakinge
  103. * @createDate: 2014年4月3日
  104. * @param ai
  105. * @param e
  106. */
  107. private void doLog(ActionInvocation ai,Exception e) {
  108. //开发模式
  109. if(JFinal.me().getConstants().getDevMode()){
  110. e.printStackTrace();
  111. }
  112. //业务异常不记录 ??
  113. if( e instanceof BaseBussException)return;
  114. StringBuilder sb =new StringBuilder("\n---Exception Log Begin---\n");
  115. sb.append("Controller:").append(ai.getController().getClass().getName()).append("\n");
  116. sb.append("Method:").append(ai.getMethodName()).append("\n");
  117. sb.append("Exception Type:").append(e.getClass().getName()).append("\n");
  118. sb.append("Exception Details:");
  119. log.error(sb.toString(), e);
  120. }
  121. /**
  122. * 格式化异常信息,用于友好响应用户
  123. * @param e
  124. * @return
  125. */
  126. private static String formatException(Exception e){
  127. String message = null;
  128. Throwable ourCause = e;
  129. while ((ourCause = e.getCause()) != null) {
  130. e = (Exception) ourCause;
  131. }
  132. String eClassName = e.getClass().getName();
  133. //一些常见异常提示
  134. if("java.lang.NumberFormatException".equals(eClassName)){
  135. message = "请输入正确的数字";
  136. }else if (e instanceof BaseBussException || e instanceof RuntimeException) {
  137. message = e.getMessage();
  138. if(StringUtils.isBlank(message))message = e.toString();
  139. }
  140. //获取默认异常提示
  141. if (StringUtils.isBlank(message)){
  142. message = "系统繁忙,请稍后再试";
  143. }
  144. //替换特殊字符
  145. message = message.replaceAll("\"", "‘");
  146. return message;
  147. }
  148. }

时间: 2024-12-29 12:02:11

jfinal统一的异常及日志处理的拦截器的相关文章

struts2-权限拦截器、日志拦截器、execAndWait(进度条)拦截器配置

1.权限拦截器 package login; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class LoginI

Struts2拦截器记录系统操作日志

前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部分日志.这个系统并没有此要求,因此便想到了做一个系统通用的日志记录,主要记录数据有:操作时间.操作对象.操作方法.操作的一些参数以及操作结果.刚开始直接想到的是利用aspect实现aop记录日志,但实际应用中发现aspect并不能友好的拦截action,而是主要用作拦截service层业务.由于系统

SVN操作异常解决日志

1 svn locked某个目录-无法进行更新 产生这种情况大多是因为上次svn命令执行失败且被锁定了.如果cleanup没有效果的话只好手动删除锁定文件. 在命令提示符下cd 到svn项目出现问题的文件所在目录下,然后执行如下命令 del lock /q/s 就把锁删掉了.如图所示: 2.svn remains in conflict错误解决 情形:当有人在对某文件进行修改,假设为A文件,并提交至svn服务器,如果此时你正在修改A页面,并对其进行更新.会出现一些残余文件信息.如果在未删除这些文

SpringBoot2.0 使用AOP统一处理Web请求日志(完整版)

一,加入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 二,在src/main/java下的某个包中新建类 : import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Proce

MVC 使用HandleErrorAttribute统一处理异常

HandleErrorAttribute继承自FilterAttribute,且实现了IExceptionFilter接口. 属于AOP思想的一种实现,MVC的四大筛选器(权限,动作,结果,异常)中的异常处理. Usage 1.创建自定义异常处理 public class AppHandleErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext)

第十一章 异常,日志,断言和调试

第十一章 异常,日志,断言,调试 由于程序的错误或一些外部环境的影响造成用户数据的丢失,用户就有可能不再使用这个程序了.为了避免,应该做到以下几点: 向用户通告错误 保存所有的操作结果 允许用户以适当的形式退出程序. 11.1 处理异常 当由于出现错误而使得某些操作没有完成,程序应该: 返回到一种安全状态,并能够让用户执行一些其他命令:或者 允许用户保存所有操作的结果,以适当的方式终止程序 异常处理的任务就是将控制权从错误产生的地方转移给能够处理这种错误的处理器.程序中可能出现的错误和问题: 用

C# winform程序将异常写入日志的方法

转载地址:夏日里的春天的博客 http://hi.baidu.com/honfei/item/3a6f212998910099b73263b5 //出错之后计入日志文件        private void SqlConnError(SqlException e2)        {            //如果是同一天的话,则打开文件在末尾写入.如果不是同一天,则创建文件写入文件 //判断是否存在文件            if (File.Exists(DateTime.Today.To

WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)

WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作) 好吧,还是那个社区APP,非管理系统,用户行为日志感觉不是很必要的,但是,错误日志咱还是得记录则个.总不能上线后报bug了让自己手足无措吧,虽然不管有木有错误日志报bug都是件很头疼的事... 我们知道webAPI也有好几个Filter,上篇文章我们做token与权限用到了ActionFilterAttribute,这次我们用ExceptionFilterAttribute来做

SPRINGBOOT9--AOP的使用(本例展示统一处理Web请求日志)

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是Spring框架中的一个重要内容,它通过对既有程序定义一个切入点,然后在其前后切入不同的执行内容,比如常见的有: 打开数据库连接/关闭数据库连接.打开事务/关闭事务.记录日志等.基于AOP不会破坏原来程序逻辑,因此它可以很好的对业务逻辑的各个部分进行隔离, 从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效