aop+自定义注解实现操作日志记录

来源:互联网 发布:淘宝直播印记怎么弄 编辑:程序博客网 时间:2024/05/19 11:44
 

记录日志的自定义注解

 

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 {@Autowiredprivate 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("|"));}}}// 将注解中%转换为被拦截方法参数中的idif (!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#的角色")

由于以上代码不能适应所有的情况,所以实际使用时还需要根据情况进行修改

原创粉丝点击