业务场景:业务要求记录用户在系统的操作行为,并保存到数据库当中。
1、自定义注解,记录操作日志
import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** @company ********** @description 类的方法描述注解* @author zzg* @create 2017-02-03==17*/@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MethodAction { /** * 方法描述 * @return */ public String optionDescription() default "no description"; /** * 方法名称 * @return */ public String methodName() default "no method name"; }2、切面类package aspect;import org.aspectj.lang.PRoceedingJoinPoint;import org.apache.commons.lang.StringUtils;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.alibaba.fastjson.JSON;import com.wlsq.kso.annotation.MethodAction;import com.wlsq.kso.entity.AccountSysLog;import com.wlsq.kso.service.AccountSysLogService;import com.wlsq.kso.util.SpringContextUtil;import java.lang.reflect.Method;import java.util.Date;import javax.servlet.http.HttpServletRequest;public class AccountSysOptionLogAspect { public Object doSystemLog(ProceedingJoinPoint point) throws Throwable { // 切入方法名称 String methodName = point.getSignature().getName(); // 目标方法不为空 if (StringUtils.isNotEmpty(methodName)) { String targetName = point.getTarget().getClass().getName(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); for (Method m : methods) { if (m.getName().equals(methodName)) { boolean hasAnnotation = m .isAnnotationPresent(MethodAction.class); if (hasAnnotation) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); //请求参数 String parame = null; StringBuilder builder = new StringBuilder(); // 用户openId String userOpenId = request.getParameter("userOpenId") == null ? null : request.getParameter("userOpenId").trim(); String accessToken = request.getParameter("accessToken") == null ? null : request.getParameter("accessToken").trim();// 用户访问令牌 String generalAccount = request.getParameter("generalAccount") == null ? null : request.getParameter("generalAccount").trim();// 未来社区总账户 String sellerOpenId = request.getParameter("sellerOpenId") ==null ? null :request.getParameter("sellerOpenId").trim();//商户唯一编号 String consumState = request.getParameter("consumState") == null ? null : request.getParameter("consumState").trim();// 消费状态【0:未消费,1:支付,2支付超时,订单取消 // ,3、已支付,超时需要退款】 String consumType = request.getParameter("consumType") == null ? null : request.getParameter("consumType").trim();// 消费类型【0:普通商品,1:服务商品,2预售商品,3余额充值】 String money = request.getParameter("money") == null ? null : request.getParameter("money").trim();// 消费金额 String orderDetail = request.getParameter("orderDetail") == null ? null : request.getParameter("orderDetail").trim();// 订单详情 String orderNum = request.getParameter("orderNum") == null ? null : request.getParameter("orderNum").trim();// 订单编号 String playType = request.getParameter("playType") == null ? null : request.getParameter("playType").trim();// 支付平台类型【0:余额支付,1:微信支付,2:支付宝支付】 String plateType = request.getParameter("plateType") == null ? null : request.getParameter("plateType").trim();// 平台类型【0:未来社区】 String sign = request.getParameter("sign") == null ? null : request .getParameter("sign").trim();// 数字签名证书。 //设置支付密码 String passWord = request.getParameter("password") == null ? null : request .getParameter("password").trim();//支付密码。 String optionType = request.getParameter("optionType") == null ? null : request .getParameter("optionType").trim();// 支付密码动作。 if(userOpenId != null){ builder.append(";参数userOpenId:"+userOpenId); } if(accessToken != null){ builder.append(";参数accessToken:"+accessToken); } if(generalAccount !=null){ builder.append(";参数generalAccount:"+generalAccount); } if(sellerOpenId !=null){ builder.append(";参数sellerOpenId:"+sellerOpenId); } if(consumState !=null){ builder.append(";参数consumState:"+consumState); } if(consumType !=null){ builder.append(";参数consumType:"+consumType); } if(money !=null){ builder.append(";参数money:"+money); } if(orderDetail !=null){ builder.append(";参数orderDetail:"+orderDetail); } if(orderNum !=null){ builder.append(";参数orderNum:"+orderNum); } if(playType !=null){ builder.append(";参数playType:"+playType); } if(plateType != null){ builder.append(";参数plateType:"+plateType); } if(sign !=null){ builder.append(";参数sign:"+sign); } if(password !=null){ builder.append(";参数password:"+password); } if(optionType !=null){ builder.append(";参数optionType:"+optionType); } parame = builder.toString(); MethodAction annotation = m .getAnnotation(MethodAction.class); // 方法描述 String methodDescp = annotation.optionDescription(); // 方法名称 String name = annotation.methodName(); // 用户IP地址 String ip = getIpAddr(request) == null ? null : getIpAddr( request).trim(); AccountSysLog log = new AccountSysLog(); log.setOpenId(userOpenId); log.setOptionDesc(methodDescp); log.setOptionIp(ip); log.setOptionMethod(name); log.setOptionTime(new Date()); log.setParame(parame); AccountSysLogService accountSysLogService =(AccountSysLogService) SpringContextUtil.getBean("accountSysLogService") ; accountSysLogService.insert(log); } } } } return point.proceed(); } // 返回用IP地址 public 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; }}3、spring-context.xml 切面类型配置<bean id="logAspect" class="aspect.AccountSysOptionLogAspect"/> <aop:config> <aop:aspect ref="logAspect"> <aop:pointcut id="logPointCut" expression="execution(* com.wlsq.kso.web.*.*(..))"/> <aop:around pointcut-ref="logPointCut" method="doSystemLog"/> </aop:aspect> </aop:config> 通过上面的配置,我们可以清楚知道切入点:com.wlsq.kso.web 下所有控制类的方法。切面类:aspect.AccountSysOptionLogAspect
切面方法:doSystemLog
4、切入目标控制层,相关注解配置
新闻热点
疑难解答