推荐一个开源免费java分布式开发框架: http://www.jeesuite.com/
最近在用轻量级Java web开发框架jfinal开发一个网站,由于网站是sns类型很多ajax交互请求。
考虑简化冗余代码,写了一个统一的异常及日志处理的拦截器。
自适配ajax请求和普通定向请求,输出错误信息。
直接上代码吧
package com.smhaochi.web.interceptor; import java.util.Date; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import com.smhaochi.exception.BaseBussException; import com.smhaochi.model.ActionLog; import com.smhaochi.model.Menu; import com.smhaochi.vo.ActionLogVo; import com.smhaochi.web.controller.BaseController; import com.jfinal.aop.Interceptor; import com.jfinal.core.ActionInvocation; import com.jfinal.core.JFinal; import com.jfinal.log.Logger; /** * @title: 日志/异常处理拦截器 * @className: ActionLogInterceptor * @description: TODO * @company: FOREVEROSS * @author: <a href="http://www.smhaochi.com">vakin jiang</a> * @createDate: 2014年4月2日 * @version: 1.0 */ public class ExceptionAndLogInterceptor implements Interceptor { private static final Logger log = Logger.getLogger(ExceptionAndLogInterceptor.class); @Override public void intercept(ActionInvocation ai) { BaseController controller = (BaseController)ai.getController(); HttpServletRequest request = controller.getRequest(); boolean successed = false; try { ai.invoke(); successed = true; } catch (Exception e) { // doLog(ai,e); //判断是否ajax请求 String header = request.getHeader("X-Requested-With"); boolean isAjax = "XMLHttpRequest".equalsIgnoreCase(header); String msg = formatException(e); if(isAjax){ msg = new StringBuilder().append("{\"status\":\"0\",\"msg\":\"") .append(msg).append("\"}").toString(); controller.renderJson(msg); }else{ String redirctUrl = request.getHeader("referer"); if(StringUtils.isBlank(redirctUrl)){ redirctUrl = request.getRequestURI(); } controller.setAttr("message", msg); controller.setAttr("redirctUrl",redirctUrl); controller.render("../public/failed.ftl"); } }finally{ //记录日志 try { Menu menu = matchDefineRecordLogMenu(request); if(menu != null){ ActionLogVo actionLog = controller.wrapActionLog(); new ActionLog().set(ActionLog.ACT_NAME, menu.getName())// .set(ActionLog.ACT_TIME, new Date())// .set(ActionLog.DATA, actionLog.getData())// .set(ActionLog.IP, actionLog.getIp())// .set(ActionLog.SUCESSED, successed)// .set(ActionLog.URI, actionLog.getUri())// .set(ActionLog.USER_ID, actionLog.getUserId())// .set(ActionLog.USER_NAME, actionLog.getUserName())// .save(); } } catch (Exception e2) {} } } /** * @methodName: matchDefineRecordLogMenu * @description: 匹配已定义需要记录日志的菜单 * @author: vakinge * @createDate: 2014年4月3日 * @param request * @return */ private Menu matchDefineRecordLogMenu(HttpServletRequest request) { Map<String, Menu> menus = Menu.getAllUrlMenus(); if(menus != null){ String uri = request.getRequestURI(); Set<String> urls = menus.keySet(); for (String url : urls) { if(url == null)continue; //url匹配 && 有参数 && 已配置记录日志 if(url.contains(uri) && request.getParameterNames().hasMoreElements() && menus.get(url).isRecordLog()){ return menus.get(url); } } } return null; } /** * @methodName: doLog * @description: 记录log4j日志 * @author: vakinge * @createDate: 2014年4月3日 * @param ai * @param e */ private void doLog(ActionInvocation ai,Exception e) { //开发模式 if(JFinal.me().getConstants().getDevMode()){ e.printStackTrace(); } //业务异常不记录 ?? if( e instanceof BaseBussException)return; StringBuilder sb =new StringBuilder("\n---Exception Log Begin---\n"); sb.append("Controller:").append(ai.getController().getClass().getName()).append("\n"); sb.append("Method:").append(ai.getMethodName()).append("\n"); sb.append("Exception Type:").append(e.getClass().getName()).append("\n"); sb.append("Exception Details:"); log.error(sb.toString(), e); } /** * 格式化异常信息,用于友好响应用户 * @param e * @return */ private static String formatException(Exception e){ String message = null; Throwable ourCause = e; while ((ourCause = e.getCause()) != null) { e = (Exception) ourCause; } String eClassName = e.getClass().getName(); //一些常见异常提示 if("java.lang.NumberFormatException".equals(eClassName)){ message = "请输入正确的数字"; }else if (e instanceof BaseBussException || e instanceof RuntimeException) { message = e.getMessage(); if(StringUtils.isBlank(message))message = e.toString(); } //获取默认异常提示 if (StringUtils.isBlank(message)){ message = "系统繁忙,请稍后再试"; } //替换特殊字符 message = message.replaceAll("\"", "'"); return message; } }
相关推荐
为了达到这个目的,可以在拦截器中捕获并处理异常,或者在控制器中定义一个统一的错误处理方法。 5. **优化与扩展**:除了基本的登录验证,拦截器还可以进一步扩展,比如加入记住我功能的处理、登录超时的判断等。...
4. **AOP(面向切面编程)**:Jfinal 支持 AOP,允许开发者定义拦截器(Interceptor),实现对特定方法的前后处理,如日志记录、权限验证等。 5. **模型(Model)**:Jfinal 的 Model 类是对数据库表的映射,通过...
5. 异常处理:增强了异常处理机制,提供统一的错误页面和异常处理策略,提升了用户体验。 三、JFinal 主要组件详解 1. Controller:负责接收 HTTP 请求,处理业务逻辑,并返回视图或 JSON 数据。 2. Model:与...
- `Interceptor`:拦截器机制,允许在请求处理前后执行特定操作,例如权限验证、日志记录等。 - `Model`:模型层,用于数据操作,JFinal 提供了基于 Active Record 的简单 ORM 实现。 - `Service`:服务层,封装...
拦截器是JFinal的一大亮点,它可以对请求进行预处理和后处理,实现如权限控制、日志记录等多种功能。"jfinal demo"中的拦截器代码可以帮助我们了解如何编写和注册拦截器,以及它们在实际项目中的应用场景。 6. **...