采用自定義注解實現(xiàn)
用戶操作日志記錄
簡介及說明:
記錄登陸用戶的操作日志,目前只針對(運營管理平臺)itas系統(tǒng)
目前采用spring的切面技術(shù)來實現(xiàn)記錄日志的功能,切面點在controller層,主要是針對數(shù)據(jù)庫的增刪改操作
注解類說明
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public?@interface?OperationDescription {
Stringdesc()default"無描述信息";StringuslModule() ;//操作模塊StringuslFunction();//操作功能StringoperationType();//操作類型增刪改StringsysId()default"01";
}
如何使用
舉個栗子
機構(gòu)新建
@RequestMapping(value = "/insert", method = RequestMethod.POST)
@ResponseBody
@OperationDescription(uslModule = "用戶模塊",uslFunction = "新建機構(gòu)",operationType = "新建")
public BaseResp insert(@RequestBody Map 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=“大模塊的子模塊具體功能"例如 用戶模塊新建權(quán)限
切面類
@Aspect
@Component
public class LogAspect {
private final Loggerlogger = LoggerFactory.getLogger(this.getClass());
? ? ? ? private StringrequestPath =null; // 請求地址
? ? ? ? private StringuserName =null; // 用戶名
? ? ? ? private MapinputParamMap =null; // 傳入?yún)?shù)
? ? ? ? private MapoutputParamMap =null; // 存放輸出結(jié)果
? ? ? ? private long startTimeMillis =0; // 開始時間
? ? ? ? private long endTimeMillis =0; // 結(jié)束時間
? ? ? ? @Autowired
private UserLogServiceuserLogService;
? ? ? ? //? ? Controller層切點
? ? ? ? @Pointcut(value ="@annotation(com.landi.common.OperationDescription)")
public void controllerAspect() {
}
/**
*
? ? ? ? * @Title:doBeforeInServiceLayer
? ? ? ? * @Description: 方法調(diào)用前觸發(fā)
*? 記錄開始時間
? ? ? ? * @author pengjm
? ? ? ? * @param joinPoint
? ? ? ? */
//? ? @Before("controllerAspect()")
//? ? public void doBeforeInControllerLayer(JoinPoint joinPoint) {
//? ? ? ? startTimeMillis = System.currentTimeMillis(); // 記錄方法開始執(zhí)行的時間
//? ? }
? ? ? ? /**
? ? ? ? * @param pjp
? ? ? ? * @return
? ? ? ? * @throws Throwable
? ? ? ? * @Title:doAround
? ? ? ? * @Description: 環(huán)繞觸發(fā)
? ? ? ? * @author hotsmile
*/
? ? ? ? @Around(value ="@annotation(description)")
public ObjectdoAround(ProceedingJoinPoint pjp, OperationDescription description)throws Throwable {
/**
* 1.獲取request信息
* 2.根據(jù)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);
// 獲取輸入?yún)?shù)
? ? ? ? ? ? inputParamMap = request.getParameterMap();
? ? ? ? ? ? // 獲取請求地址
? ? ? ? ? ? requestPath = request.getRequestURI();
? ? ? ? ? ? // 執(zhí)行完方法的返回值:調(diào)用proceed()方法,就會觸發(fā)切入點方法執(zhí)行
? ? ? ? ? ? outputParamMap =new HashMap();
? ? ? ? ? ? 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 (resultinstanceof 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: 方法調(diào)用后觸發(fā)
*? 記錄結(jié)束時間
? ? ? ? * @param joinPoint
? ? ? ? */
//? ? @After("controllerAspect()")
//? ? public void doAfterInControllerLayer(JoinPoint joinPoint) {
//? ? ? ? endTimeMillis = System.currentTimeMillis(); // 記錄方法執(zhí)行完成的時間
////? ? ? ? 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));
? ? ? ? }
}