采用自定义注解实现

用户操作日志记录

简介及说明:

记录登陆用户的操作日志,目前只针对(运营管理平台)itas系统
目前采用spring的切面技术来实现记录日志的功能,切面点在controller层,主要是针对数据库的增删改操作

注解类说明

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationDescription {

   String desc() default "无描述信息";
   String uslModule() ;//操作模块
   String uslFunction();//操作功能
   String operationType();//操作类型增删改
   String sysId() default "01";

}

如何使用

举个栗子
机构新建
@RequestMapping(value = "/insert", method = RequestMethod.POST)
@ResponseBody
@OperationDescription(uslModule = "用户模块",uslFunction = "新建机构",operationType = "新建")
public BaseResp insert(@RequestBody Map<String,Object> map) {
BaseResp baseRsp = new BaseResp();
try {
String operUserId = CurrentUser.getCurrentUserId(request);
if (StringUtils.isEmpty(operUserId)) {
baseRsp.setState(Constants.RESP_FAIL);
baseRsp.setMsg("登录超时,请重新登录");
return baseRsp;
}

    }

注解说明

 uslModule="大模块”
 例如用户模块管理

 uslFunction=“大模块的子模块具体功能"
    例如 用户模块新建权限

切面类

@Aspect
@Component
public class LogAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private String requestPath = null ; // 请求地址
    private String userName = null ; // 用户名
    private Map<?,?> inputParamMap = null ; // 传入参数
    private Map<String, Object> outputParamMap = null; // 存放输出结果
    private long startTimeMillis = 0; // 开始时间
    private long endTimeMillis = 0; // 结束时间

    @Autowired
    private UserLogService userLogService;


//    Controller层切点
    @Pointcut(value="@annotation(com.landi.common.OperationDescription)")
    public  void controllerAspect() {
    }


    /**
     *
     * @Title:doBeforeInServiceLayer
     * @Description: 方法调用前触发
     *  记录开始时间
     * @author pengjm
     * @param joinPoint
     */
//    @Before("controllerAspect()")
//    public void doBeforeInControllerLayer(JoinPoint joinPoint) {
//        startTimeMillis = System.currentTimeMillis(); // 记录方法开始执行的时间
//    }

    /**
     *
     * @Title:doAround
     * @Description: 环绕触发
     * @author hotsmile
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around(value = "@annotation(description)")
    public Object doAround(ProceedingJoinPoint pjp,OperationDescription description) throws Throwable {
        /**
         * 1.获取request信息
         * 2.根据request获取session
         * 3.从session中取出登录用户信息
         */
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes)ra;
        HttpServletRequest request = sra.getRequest();
        // 从session中获取用户信息
//        String loginInfo = (String) request.getSession().getAttribute("username");
        LoginUserInfo userInfo = CurrentUser.getCurrentUser(request);
        if(userInfo != null){
            userName = userInfo.getUserId();;
        }else{
            userName = "用户未登录" ;
        }

          Object[] args = pjp.getArgs();
//         logger.info("params="+JSONObject.toJSONString(args));
//        String className=pjp.getTarget().getClass().getSimpleName();
//        String methodName=pjp.getSignature().getName();
//        Object[] args=pjp.getArgs();
//        Class<?> classTarget=pjp.getTarget().getClass();
//        Class<?>[] par=((MethodSignature) pjp.getSignature()).getParameterTypes();
//        Method objMethod=classTarget.getMethod(methodName, par);
//        logger.info("===="+description.uslModule());

//        Cache aCache=objMethod.getAnnotation(Cache.class);

        // 获取输入参数
        inputParamMap = request.getParameterMap();
        // 获取请求地址
        requestPath = request.getRequestURI();

        // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
        outputParamMap = new HashMap<String, Object>();
        Object result = pjp.proceed();// result的值就是被拦截方法的返回值
        outputParamMap.put("result", result);
        Userlog userlog=new Userlog();
        userlog.setUslId(UuidUtils.getRandomUuidWithoutSeparator());
        userlog.setSysId(description.sysId());
        userlog.setUslDate(DateUtils.curDateTime());
        userlog.setUslModule(description.uslModule());
        userlog.setUslFunction(description.uslFunction());
        userlog.setUserId(userInfo.getUserId());
        userlog.setUslParameter(JSONObject.toJSONString(args));
//        logger.info("param="+JSON.toJSONString(inputParamMap));
        if(result instanceof BaseResp){
            if(((BaseResp) result).getState().equals(Constants.RESP_SUCCESS)){
                userlog.setUslStatus(Constants.USERLOG_SUCC);
            }else{
                userlog.setUslStatus(Constants.USERLOG_FAIL);
            }

        }


//        if ("POST".equals(method)) {
//            Object[] paramsArray = joinPoint.getArgs();
//            params = argsArrayToString(paramsArray);
//        } else {
//            Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
//            params = paramsMap.toString();
//        }


        userLogService.save(userlog);

        return result;
    }


    /**
     *
     * @Title:doAfterInServiceLayer
     * @Description: 方法调用后触发
     *  记录结束时间
     * @param joinPoint
     */
//    @After("controllerAspect()")
//    public void doAfterInControllerLayer(JoinPoint joinPoint) {
//        endTimeMillis = System.currentTimeMillis(); // 记录方法执行完成的时间
////        System.out.println("哈哈哈!");
//        this.printOptLog();
//    }

    /**
     *
     * @Title:printOptLog
     * @Description: 输出日志
     * @author shaojian.yu
     * @date 2014年11月2日 下午4:47:09
     */
    private void printOptLog() {
        JSONObject gson = new JSONObject(); // 需要用到google的gson解析包
        String optTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTimeMillis);
        logger.info("\n user:"+userName
                +"  url:"+requestPath+"; op_time:" + optTime + " pro_time:" + (endTimeMillis - startTimeMillis) + "ms ;"
                +" param:"+ JSON.toJSONString(inputParamMap)+";"+"\n result:"+JSON.toJSONString(outputParamMap));
    }


}
03-16 08:55