Structs2拦截器和注解实现自动记录日志
先看效果,其他程序员使用的时候,如下,findAllCountry被调用时,调用时间、调用人、方法名、方法描述、testValue、testValue2的值都将被存入数据库中。
?
?
public class TestAction extends ActionSupport {private String testValue = "hellow";private String testValue2 = "hellow2"; @IDBLog(desc="分页查询数据", params="testValue;testValue2;")public void findAllCountry(){System.out.println("in CountryAction :findAllCountry"); //TODO: } //注解中要记录该参数的值,必须提供get方法 public String getTestValue() {return testValue;} public String getTestValue2() {return testValue2;}}?
1:先写一个DB日志实体:
/** * * 数据库日志记录实体 <p> * @author zhuoyueping @date 2012-5-8 <br> * @version <br> */public class DBLog extends Core {/** 操作的用户 **/protected String remote_user;/** 操作的时间 **/protected Date operate_date;/** 操作的action **/protected String operation;/** 操作的action的描述 **/protected String oper_desc;/** 操作的action的成员变量 **/protected String oper_params; //getter 、 setter}?
2:注解IDBLog,指定了该注解的action方法:
/** * 定义注入Action的log远程业务接口<p> * @author zhuoyueping @date 2012-05-7<br> * @version 1.0<br> */@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface IDBLog {/** * 指定action方法的描述名称 如:查询用户 * @return */public abstract String desc();/** * 指定action方法的成员参数名称,指定的参数应该覆盖toString方法,多个成员参数用;分隔 * @return */public abstract String params() default "";}
?
3:structs2的拦截器代码,CommonBaseInterceptor是公司内部对拦截器的简单封装类
/** * 以拦截器的方式动态注入action方法,记录用户、时间、操作的action * @author zhuoyueping @date 2012-04-08<br> * @version 1.0<br> */public class DBLogInteceptor extends CommonBaseInterceptor {/** * 系统默认生成版本号 */private static final long serialVersionUID = 1L;private IDBLogService dbLogService;/** * 实现拦截功能<p> */public String intercept(ActionInvocation actionInvocation) throws Exception {Object action = actionInvocation.getAction();java.lang.reflect.Method[] methods = action.getClass().getDeclaredMethods();for (Method method : methods) {boolean hasAnnotation = method.isAnnotationPresent(IDBLog.class);if (hasAnnotation) { IDBLog avicLog = method.getAnnotation(IDBLog.class);//上下文 ActionContext actionContext = actionInvocation.getInvocationContext(); HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST); //登陆用户 String uid =request.getRemoteUser(); //操作时间 Date currentDate = new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String date = sdf.format(currentDate); //操作方法: String operation = action.getClass().getName()+"."+method.getName(); //操作的方法描述 String desc = avicLog.desc(); //参数 String params = avicLog.params(); List<String> fieldNames = splitParams(params); StringBuffer sb = new StringBuffer(); if(fieldNames!=null){ for(String fieldName:fieldNames){ //调用getXX方法 String methodName = convertMethodName(fieldName); Method getMethod=action.getClass().getMethod(methodName, new Class[]{}); Object fieldValue=getMethod.invoke(action, new Object[]{}); String value = formatFidlParam(fieldName,fieldValue.toString()); sb.append(value); } } DBLog log = new DBLog(); log.setRemote_user(uid); log.setOperate_date(currentDate); log.setOperation(operation); log.setOper_desc(desc); log.setOper_params(sb.toString()); System.out.println("************************in AvicDBLogInteceptor\n "+log ); //取得spring中管理的bean,取得service执行save保存数据 ServletContext sc=request.getSession().getServletContext(); ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc); dbLogService = (IDBLogService) ac.getBean("com.system.common.dbLogService");//写数据库日志dbLogService.save(log); System.out.println("******************************************写日志完成");}}return actionInvocation.invoke();}//根据传入的参数名称,private List<String> splitParams(String params){System.out.println("input:"+params);List<String> lst = null;if(params==null||params.trim().equals("")){return null;}lst = new ArrayList<String>();StringTokenizer st = new StringTokenizer(params,";");while(st.hasMoreTokens()){String paramName = st.nextToken().trim();lst.add(paramName);}return lst;}//根据成员变量名,改第一个字母大写后,再增加get前缀,转为getXxxx方法名。private String convertMethodName(String fieldName){String fisrLetter = fieldName.substring(0, 1).toUpperCase();String methodName = "get"+fisrLetter+fieldName.substring(1);System.out.println(methodName);return methodName;}//格式化参数名和参数值输出格式private String formatFidlParam(String fieldName,String fiedldValue){String rtnValue = null;rtnValue = "["+fieldName+" = {"+fiedldValue+"}]";return rtnValue;}}
?
3:配置拦截器:
<package name="common" extends="struts-default"><interceptors><interceptor name="dbLogInteceptor" name="code"><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts><package name="avic-system-json" extends="json-default,common"><!-- ************************************************配置自定义ACTION类************************************************* --><action name="userList" method="getPageList"><result name="success" type="json"></result></action></package></struts>