- maven依赖
需要spring aop, 由于要用到数据库,使用mybatis-plus生成crud代码,将mybatis-plus依赖也加上
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
<scope>test</scope>
</dependency>
- 数据库建表语句
DROP TABLE IF EXISTS `operation_log`;
CREATE TABLE `operation_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '操作日志id',
`username` VARCHAR(20) DEFAULT NULL COMMENT '操作人',
`module` VARCHAR(30) DEFAULT NULL COMMENT '执行模块',
`methods` VARCHAR(50) DEFAULT NULL COMMENT '执行方法',
`content` VARCHAR(255) DEFAULT NULL COMMENT '操作内容',
`actionurl` VARCHAR(50) DEFAULT NULL COMMENT '请求路径',
`ip` VARCHAR(50) DEFAULT NULL COMMENT 'IP地址',
`date` DATETIME DEFAULT NULL COMMENT '操作时间',
`commite` TINYINT(2) DEFAULT NULL COMMENT '执行描述(1:执行成功、2:执行失败)',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;
- 使用mybatis-plus创建crud
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class DevCodeGenerator {
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
String module = scanner("模块名");
String table = scanner("表名");
generate(module, table);
}
private static void generate(String module, String table) {
AutoGenerator mpg = new AutoGenerator();
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("360os");
gc.setOpen(false);
mpg.setGlobalConfig(gc);
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
PackageConfig pc = new PackageConfig();
pc.setModuleName(module);
pc.setParent("com.test");
mpg.setPackageInfo(pc);
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
}
};
String templatePath = "/templates/mapper.xml.ftl";
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(false);
strategy.setRestControllerStyle(true);
strategy.setInclude(table);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
- spring 切面
package com.test.config;
import com.google.gson.Gson;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class LogAopAction {
@Autowired
private IOperationLogService logService;
private Gson gson = new Gson();
@Pointcut("@annotation(com.test.config.OptionalLog)")
private void controllerAspect() {
}
@Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
OperationLog logBo = new OperationLog();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String username = (String) request.getSession().getAttribute("user");
logBo.setUsername(username);
logBo.setDate(new Date());
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
logBo.setIp(ipAddress);
Object target = pjp.getTarget();
String methodName = pjp.getSignature().getName();
Object[] args = pjp.getArgs();
String actionUrl = request.getRequestURI();
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();
Object object = null;
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}
if (null != method) {
OptionalLog op = method.getAnnotation(OptionalLog.class);
logBo.setModule(op.module());
logBo.setMethods(op.methods());
logBo.setActionurl(actionUrl);
try {
object = pjp.proceed();
Map<String, String[]> map = request.getParameterMap();
Map<String, String[]> newmap = new HashMap<String, String[]>();
for (Map.Entry<String, String[]> entry : map.entrySet()) {
String name = entry.getKey();
String[] values = entry.getValue();
if (values == null) {
newmap.put(name, new String[]{});
continue;
}
String[] newvalues = new String[values.length];
for (int i = 0; i < values.length; i++) {
String value = values[i];
value = new String(value.getBytes("iso8859-1"), request.getCharacterEncoding());
newvalues[i] = value;
}
newmap.put(name, newvalues);
}
logBo.setContent(gson.toJson(newmap));
logBo.setCommite(1);
logService.save(logBo);
} catch (Throwable e) {
Map<String, String[]> map = request.getParameterMap();
Map<String, String[]> newmap = new HashMap<String, String[]>();
for (Map.Entry<String, String[]> entry : map.entrySet()) {
String name = entry.getKey();
String[] values = entry.getValue();
if (values == null) {
newmap.put(name, new String[]{});
continue;
}
String[] newvalues = new String[values.length];
for (int i = 0; i < values.length; i++) {
String value = values[i];
value = new String(value.getBytes("iso8859-1"), request.getCharacterEncoding());
newvalues[i] = value;
}
newmap.put(name, newvalues);
}
logBo.setContent(gson.toJson(newmap));
logBo.setCommite(2);
logService.save(logBo);
}
}
return object;
}
}
- 操作日志注解
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OptionalLog {
String module() default "";
String methods() default "";
}
- 用法示例
@OptionalLog(module = "数据库模块",methods = "查询列表数据")
@PostMapping("/selectList")
public BaseRsp selectList(@RequestParam("sql") String sql){}
- 日志效果