这是在控制层实现日志系统的,之前是在service中实现的日志,垃圾的一批,还麻烦,自定义注解来实现日志功能很方便
操作日志表
CREATE TABLE `t_log` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志编号',
`user_name` varchar(10) DEFAULT NULL COMMENT '操作者姓名',
`ip` varchar(255) DEFAULT NULL COMMENT 'IP',
`operate_content` varchar(255) DEFAULT NULL COMMENT '操作说明',
`method` varchar(255) DEFAULT NULL COMMENT '方法名',
`controller` varchar(255) DEFAULT NULL COMMENT '控制器名',
`operate_time` datetime DEFAULT NULL COMMENT '操作时间',
`parameters` longtext COMMENT '方法参数',
`return_value` longtext COMMENT '返回值',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8mb4;
操作日志的实体类,mapper文件等自行解决
//用来保存用户信息的
@Data
public class UserInfo {
private long userId;
private String userName;
private String password;
}
package com.itwangpt.pojo;
import java.io.Serializable;
import java.util.Date;
/**
* @author 王鹏滔
*/
@Data
public class Log implements Serializable {
private Integer id;
private String parameters;
private String returnValue;
private String ip;
private String operateContent;
private String method;
private String controller;
private Date operateTime;
private String userName;
}
在spring-mvc.xml中开启aop
<aop:aspectj-autoproxy/>
<aop:config proxy-target-class="true"></aop:config>
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ArchivesLog {
/**
* 操作说明
*/
public String operteContent() default "";
}
aop类
package com.itwangpt.aop;
import com.itwangpt.annotation.ArchivesLog;
import com.itwangpt.pojo.Log;
import com.itwangpt.pojo.UserInfo;
import com.itwangpt.service.LogService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
@Aspect
@Component
public class ArchivesLogAspect {
@Reference
private LogService logService;
private static final Logger logger = LoggerFactory.getLogger(ArchivesLog.class);
@Pointcut("@annotation(com.itwangpt.annotation.ArchivesLog)")
public void controllerAspect() {
}
/**
* 方法调用后触发 , 记录正常操作
*
* @param joinPoint
* @throws ClassNotFoundException
*/
@AfterReturning(value = "controllerAspect()", returning = "returnValue")
public void after(JoinPoint joinPoint, Object returnValue) throws ClassNotFoundException, UnknownHostException, UnknownHostException {
String userName = getUSerMsg().getUserName();
// 用户IP
String ip = InetAddress.getLocalHost().getHostAddress();
// 控制器名
String targetName = getMethodDesc(joinPoint).getController();
// 方法名
String methodName = getMethodDesc(joinPoint).getMethod();
// 操作说明
String operteContent = getMethodDesc(joinPoint).getOperateContent();
String parameters = Arrays.toString(removeServletObjects(joinPoint.getArgs()));
String returnValueStr = (returnValue == null ? "null" : returnValue.toString());
System.out.println("操作者:" + userName);
System.out.println("操作说明:" + operteContent);
System.out.println("方法参数:" + Arrays.toString(joinPoint.getArgs()));
System.out.println("方法返回值:" + (returnValue == null ? "null" : returnValue.toString()));
Log log = new Log();
log.setParameters(parameters);
log.setReturnValue(returnValueStr);
log.setIp(ip);
log.setOperateContent(operteContent);
log.setMethod(methodName);
log.setController(targetName);
log.setOperateTime(new Date());
log.setUserName(userName);
logService.insertLog(log);
}
/**
* 发生异常,走此方法
*
* @param joinPoint
* @param e
*/
@AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
public void AfterThrowing(JoinPoint joinPoint, Throwable e) {
try {
// 用户id
int userId = (int) getUSerMsg().getUserId();
// 操作者姓名
String userName = getUSerMsg().getUserName();
// 用户IP
String ip = InetAddress.getLocalHost().getHostAddress();
// 控制器名
String targetName = getMethodDesc(joinPoint).getController();
// 方法名
String methodName = getMethodDesc(joinPoint).getMethod();
// 操作说明
String operteContent = getMethodDesc(joinPoint).getOperateContent();
Log log = new Log();
String exMsg = e.getCause().toString();
String parameters = Arrays.toString(removeServletObjects(joinPoint.getArgs()));
System.out.println("操作者:" + userName);
System.out.println("操作说明:" + operteContent);
System.out.println("方法参数:" + Arrays.toString(joinPoint.getArgs()));
System.out.println("操作有异常:" + e.getCause().toString());
if (exMsg != null) {
int type = 2;
log.setIp(ip);
log.setOperateContent(operteContent);
log.setParameters(parameters);
log.setMethod(methodName);
log.setController(targetName);
log.setUserName(userName);
logService.insertLog(log);
}
} catch (Exception e1) {
logger.error(e1.getMessage());
}
}
/**
* 获取 注解中对方法的描述
*
* @return
* @throws ClassNotFoundException
*/
public static Log getMethodDesc(JoinPoint joinPoint) throws ClassNotFoundException {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String operteContent = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
//操作说明
operteContent = method.getAnnotation(ArchivesLog.class).operteContent();
break;
}
}
}
Log log = new Log();
log.setController(targetName);
log.setMethod(methodName);
log.setOperateContent(operteContent);
return log;
}
/**
* 得到用户信息
* @return
*/
public static UserInfo getUSerMsg() {
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username="";
String password="";
if (principal!=null){
username = principal.getUsername();
password = principal.getPassword();
}
//从spring_security中获取信息
UserInfo user = new UserInfo();
user.setUserName(username);
user.setPassword(password);
return user;
}
/*去掉方法参数的servlet对象*/
public static Object[] removeServletObjects(Object[] objects) {
List list = Arrays.asList(objects);
list = new ArrayList(list);
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
if (object instanceof HttpServletResponse || object instanceof HttpServletRequest) {
list.remove(object);
i--;
}
}
System.out.println(list);
objects = list.toArray();
return objects;
}
}
在controller(控制层)方法上加注解
@PreAuthorize("hasAuthority('CHECKITEM_EDIT')")
@ArchivesLog(operteContent = "更新检查组")
@RequestMapping("/updateCheckGroupEdit4ById")
public Result updateCheckGroupEdit4ById(@RequestBody CheckGroup checkGroup){
try {
checkGroupService.updateCheckGroupEdit4ById(checkGroup);
return Result.success(MessageConstant.EDIT_CHECKGROUP_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
return Result.error(MessageConstant.EDIT_CHECKGROUP_FAIL);
}
}
大家可以根据自己的需求更改