记录日志的自定义注解
package com.apabi.leopard.annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.ElementType; /** * @author pengjin * @version 2.1 * @since 2.1 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface LogAnnotation { String operateModelNm(); String operateFuncNm(); String operateDescribe(); }
aop切面处理方法:
package com.apabi.leopard.annotation; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; import javacommon.base.BaseSpringController; import javacommon.security.springsecurity.SpringSecurityUtils; import org.aspectj.lang.JoinPoint; import org.springframework.beans.factory.annotation.Autowired; import com.apabi.leopard.model.Admin; import com.apabi.leopard.model.OperateLog; import com.apabi.leopard.service.OperateLogManager; import com.apabi.leopard.sso.SsoService; import com.apabi.leopard.sso.User; /** * @author pengjin * @version 2.1 * @since 2.1 */ public class WriteOperateLog { @Autowired private OperateLogManager operateLogManager; public void writeLogInfo(JoinPoint joinPoint) throws Exception, IllegalAccessException { String temp = joinPoint.getStaticPart().toShortString(); String longTemp = joinPoint.getStaticPart().toLongString(); joinPoint.getStaticPart().toString(); String classType = joinPoint.getTarget().getClass().getName(); String methodName = temp.substring(10, temp.length() - 1); Class<?> className = Class.forName(classType); // 日志动作 @SuppressWarnings("rawtypes") Class[] args = new Class[joinPoint.getArgs().length]; String[] sArgs = (longTemp.substring(longTemp.lastIndexOf("(") + 1, longTemp.length() - 2)).split(","); for (int i = 0; i < args.length; i++) { if (sArgs[i].endsWith("String[]")) { args[i] = Array.newInstance(Class.forName("java.lang.String"), 1).getClass(); } else if (sArgs[i].endsWith("Long[]")) { args[i] = Array.newInstance(Class.forName("java.lang.Long"), 1) .getClass(); } else if (sArgs[i].indexOf(".") == -1) { if (sArgs[i].equals("int")) { args[i] = int.class; } else if (sArgs[i].equals("char")) { args[i] = char.class; } else if (sArgs[i].equals("float")) { args[i] = float.class; } else if (sArgs[i].equals("long")) { args[i] = long.class; } } else { args[i] = Class.forName(sArgs[i]); } } Method method = className.getMethod( methodName.substring(methodName.indexOf(".") + 1, methodName.indexOf("(")), args); BaseSpringController thisController = (BaseSpringController) joinPoint .getTarget(); // 如果该方法写了注解才做操作 if (method.isAnnotationPresent(LogAnnotation.class)) { LogAnnotation logAnnotation = method .getAnnotation(LogAnnotation.class); String operateModelNm = logAnnotation.operateModelNm(); String operateFuncNm = logAnnotation.operateFuncNm(); String operateDescribe = logAnnotation.operateDescribe(); List<String> logArgs = null; if (operateDescribe.indexOf("#") != -1) { logArgs = new ArrayList<String>(); int startIndex = operateDescribe.indexOf("#", 0); int endIndex = operateDescribe.indexOf("#", startIndex + 1); while (startIndex != -1) { String tempArg = operateDescribe.substring(startIndex + 1, endIndex); startIndex = operateDescribe.indexOf("#", endIndex + 1); endIndex = operateDescribe.indexOf("#", startIndex + 1); logArgs.add(tempArg); } } // 获取被注解方法的参数,实现动态注解 String logArg = null; // 被注解方法只有一个参数的情况可用%替代要传入的参数 if (args.length == 1) { if (args[0].getName().equals("java.lang.Long") || args[0].getName().equals("java.lang.Integer") || args[0].getName().equals("java.lang.String")) { logArg = String.valueOf((joinPoint.getArgs())[0]); } else if (args[0] == String[].class) { String[] arrayArg = (String[]) (joinPoint.getArgs())[0]; logArg = Arrays.toString(arrayArg); } else if (args[0].getName().startsWith( "com.apabi.leopard.model")) { Method m = args[0].getMethod("getId"); logArg = String.valueOf(m.invoke(joinPoint.getArgs()[0])); // 包含了两个操作的日志内容如save方法中包含了增加和修改操作,根据是否存在参数来判断是什么操作 if (operateDescribe.indexOf("|") != -1) { if (!logArg.equals("null")) { operateDescribe = operateDescribe .substring(operateDescribe.indexOf("|") + 1); } else { operateDescribe = operateDescribe.substring(0, operateDescribe.indexOf("|")); } } } // 将注解中%转换为被拦截方法参数中的id if (!logArg.equals("null")) { operateDescribe = operateDescribe.indexOf("%") != -1 ? operateDescribe .replace("%", logArg) : operateDescribe; } } else { Object obj[] = joinPoint.getArgs(); for (int k = 0; k < logArgs.size(); k++) { for (int j = k; j < obj.length; j++) { // 如果是实体 if (logArgs.get(k).startsWith("@")) { if (args[j].getName().startsWith( "com.apabi.leopard.model")) { Method m = args[j].getMethod("getId"); logArg = String.valueOf(m.invoke(joinPoint .getArgs()[j])); // 包含了两个操作的日志内容如save方法中包含了增加和修改操作,根据是否存在参数来判断是什么操作 if (!logArg.equals("null")) { operateDescribe = operateDescribe .substring(operateDescribe .indexOf("|") + 1); } else { operateDescribe = operateDescribe .substring(0, operateDescribe .indexOf("|")); } } else { continue; } // 数组 } else if (logArgs.get(k).startsWith("{1}quot;)) { String[] arrayArg = thisController.request .getParameterValues(logArgs.get(k) .substring(1)); logArg = Arrays.toString(arrayArg); // String } else { logArg = thisController.request .getParameter(logArgs.get(k)); if (logArgs.get(k).equals("bsId") && logArg == null) { logArg = SpringSecurityUtils.getCurrentAdmin() .getNwOfficeId().toString(); } if (operateDescribe.indexOf("|") != -1) { if (!logArg.equals("null")) { operateDescribe = operateDescribe .substring(operateDescribe .indexOf("|") + 1); } else { operateDescribe = operateDescribe .substring(0, operateDescribe .indexOf("|")); } } } if (logArg == null || logArg.equals("null")) { logArg = ""; } operateDescribe = operateDescribe.replace( "#" + logArgs.get(k) + "#", logArg); break; } } } OperateLog log = null; Admin admin = SpringSecurityUtils.getCurrentAdmin(); if (admin != null) { log = new OperateLog(admin.getNwOfficeId(), admin.getLoginName(), operateModelNm, operateFuncNm, operateDescribe, new Date(), getIpAddr(thisController.request)); } else { final User user = (User) thisController.request.getSession() .getAttribute(SsoService.SESSION_USER); log = new OperateLog(user.getNwOfficeId(), user.getUsername(), operateModelNm, operateFuncNm, operateDescribe, new Date(), user.getIpAddress()); } operateLogManager.saveOrUpdate(log); } } public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
配置文件springmvc-servlet.xml增加
<aop:config proxy-target-class="true">
<aop:aspect id="goLogAspect" ref="AfterReturningAdvice">
<aop:pointcut id="actionPointcut" expression="execution(* com.*..*.web.*Controller.*(..))" />
<aop:before pointcut-ref="actionPointcut"
method="writeLogInfo" />
</aop:aspect>
</aop:config>
<bean id="AfterReturningAdvice" class="com.xxx.leopard.annotation.AfterReturningAdvice"></bean>
例:
/**
* 保存对象.
**/
@RequestMapping
@LogAnnotation(operateDescribe="公开策略")
public String save(final IssuePolicy issuePolicy, final String limitIpRange) throws Exception {
//
}
/**
* 开放公开策略.
*/
@RequestMapping
@LogAnnotation(operateDescribe="开放了id为%的公开策略")
public void open(final String[] ids) {
}
添加日志的方法:在需要添加日志的controller方法上面添加
传一个参数的情况用%
@LogAnnotation(operateModelNm = "模块名",operateFuncNm = "功能名",operateDescribe = "修好了id=%的套餐")
传多个参数的情况用#参数名#,实体类型前面加@ 数组类型前面加$,其他类型不加 例如#$参数名#
@LogAnnotation(operateModelNm = "模块名",operateFuncNm = "功能名",operateDescribe = "修好了id=#@role#,nwOfficeId=#nwOfficeId#的角色")
由于以上代码不能适应所有的情况,所以实际使用时还需要根据情况进行修改