Browse Source

aop保存日志

master
nelson 4 years ago
parent
commit
22720c758d
  1. 4
      build.gradle
  2. 19
      src/main/java/com/aiprose/mbp/annotation/OperLog.java
  3. 186
      src/main/java/com/aiprose/mbp/aop/OperLogAspect.java
  4. 7
      src/main/java/com/aiprose/mbp/controller/UserController.java
  5. 39
      src/main/java/com/aiprose/mbp/entity/ExceptionLog.java
  6. 45
      src/main/java/com/aiprose/mbp/entity/SysLog.java
  7. 10
      src/main/java/com/aiprose/mbp/mapper/ExceptionLogMapper.java
  8. 9
      src/main/java/com/aiprose/mbp/mapper/SysLogMapper.java
  9. 13
      src/main/java/com/aiprose/mbp/service/ExceptionLogService.java
  10. 18
      src/main/java/com/aiprose/mbp/service/SysLogService.java
  11. 19
      src/main/java/com/aiprose/mbp/service/UserService.java
  12. 26
      src/main/java/com/aiprose/mbp/util/IPUtil.java
  13. 1
      src/main/resources/application.yml

4
build.gradle

@ -15,8 +15,10 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-aop'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
@ -25,10 +27,12 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.3.2'
compile group: 'com.gitee.sunchenbin.mybatis.actable', name: 'mybatis-enhance-actable', version: '1.2.1.RELEASE'
// compile group: 'com.github.xiaoymin', name: 'knife4j-spring-boot-starter', version: '2.0.4'
// implementation 'com.github.xiaoymin:knife4j-spring-boot-starter:2.0.2'
compile group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.73'
}

19
src/main/java/com/aiprose/mbp/annotation/OperLog.java

@ -0,0 +1,19 @@
package com.aiprose.mbp.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义操作日志注解
* @author nelson
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {
String operModul() default ""; // 操作模块
String operType() default ""; // 操作类型
String operDesc() default ""; // 操作说明
}

186
src/main/java/com/aiprose/mbp/aop/OperLogAspect.java

@ -0,0 +1,186 @@
package com.aiprose.mbp.aop;
import com.aiprose.mbp.annotation.OperLog;
import com.aiprose.mbp.entity.ExceptionLog;
import com.aiprose.mbp.entity.SysLog;
import com.aiprose.mbp.service.ExceptionLogService;
import com.aiprose.mbp.service.SysLogService;
import com.aiprose.mbp.util.IPUtil;
import com.alibaba.fastjson.JSON;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class OperLogAspect {
@Value("${version}")
private String operVer;
@Autowired
private SysLogService sysLogService;
@Autowired
private ExceptionLogService excService;
/**
* 设置操作日志切入点 记录操作日志 在注解的位置切入代码
*/
@Pointcut("@annotation(com.aiprose.mbp.annotation.OperLog)")
public void syslogPoinCut() {
}
/**
* 设置操作异常切入点记录异常日志 扫描所有controller包下操作
*/
@Pointcut("execution(* com.aiprose.mbp.controller..*.*(..))")
public void operExceptionLogPoinCut() {
}
/**
* 正常返回通知拦截用户操作日志连接点正常执行完成后执行 如果连接点抛出异常则不会执行
* @param joinPoint 切入点
* @param keys 返回结果
*/
@AfterReturning(value = "syslogPoinCut()", returning = "keys")
public void savesyslog(JoinPoint joinPoint, Object keys) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
SysLog syslog = new SysLog();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
OperLog opLog = method.getAnnotation(OperLog.class);
if (opLog != null) {
String operModul = opLog.operModul();
String operType = opLog.operType();
String operDesc = opLog.operDesc();
syslog.setOperModul(operModul); // 操作模块
syslog.setOperType(operType); // 操作类型
syslog.setOperDesc(operDesc); // 操作描述
}
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = method.getName();
methodName = className + "." + methodName;
syslog.setOperMethod(methodName); // 请求方法
// 请求的参数
Map<String, String> rtnMap = converMap(request.getParameterMap());
// 将参数所在的数组转换成json
String params = JSON.toJSONString(rtnMap);
syslog.setOperRequParam(params); // 请求参数
syslog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果
syslog.setOperUserId(1l); // 请求用户ID
syslog.setOperUserName("nelson"); // 请求用户名称
syslog.setOperIp(IPUtil.getIpAddr(request)); // 请求IP
syslog.setOperUri(request.getRequestURI()); // 请求URI
syslog.setOperVersion(operVer); // 操作版本
sysLogService.save(syslog);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 异常返回通知用于拦截异常日志信息 连接点抛出异常后执行
*
* @param joinPoint 切入点
* @param e 异常信息
*/
@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
ExceptionLog excepLog = new ExceptionLog();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = method.getName();
methodName = className + "." + methodName;
// 请求的参数
Map<String, String> rtnMap = converMap(request.getParameterMap());
// 将参数所在的数组转换成json
String params = JSON.toJSONString(rtnMap);
excepLog.setExcRequParam(params); // 请求参数
excepLog.setOperMethod(methodName); // 请求方法名
excepLog.setExcName(e.getClass().getName()); // 异常名称
excepLog.setExcMsg(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息
excepLog.setOperUserId(1l); // 请求用户ID
excepLog.setOperUserName("nelson"); // 请求用户名称
excepLog.setOperUri(request.getRequestURI()); // 操作URI
excepLog.setOperIp(IPUtil.getIpAddr(request)); // 操作员IP
excepLog.setOperVersion(operVer); // 操作版本号
excService.save(excepLog);
} catch (Exception e2) {
e2.printStackTrace();
}
}
/**
* 转换request 请求参数
*
* @param paramMap request获取的参数数组
*/
public Map<String, String> converMap(Map<String, String[]> paramMap) {
Map<String, String> rtnMap = new HashMap<String, String>();
for (String key : paramMap.keySet()) {
rtnMap.put(key, paramMap.get(key)[0]);
}
return rtnMap;
}
/**
* 转换异常信息为字符串
*
* @param exceptionName 异常名称
* @param exceptionMessage 异常信息
* @param elements 堆栈信息
*/
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
StringBuffer strbuff = new StringBuffer();
for (StackTraceElement stet : elements) {
strbuff.append(stet + "\n");
}
String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
return message;
}
}

7
src/main/java/com/aiprose/mbp/controller/UserController.java

@ -1,5 +1,6 @@
package com.aiprose.mbp.controller;
import com.aiprose.mbp.annotation.OperLog;
import com.aiprose.mbp.entity.User;
import com.aiprose.mbp.service.UserService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -7,6 +8,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@ -36,7 +38,8 @@ public class UserController {
@ApiOperation(value = "分页")
@GetMapping("page")
public Page<User> page() {
return userService.page();
@OperLog(operModul = "用户列表分页",operType = "分页")
public Page<User> page(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
return userService.page(pageNum,pageSize);
}
}

39
src/main/java/com/aiprose/mbp/entity/ExceptionLog.java

@ -0,0 +1,39 @@
package com.aiprose.mbp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;
import lombok.Data;
@Data
@Table(name="mbp_exception_log")
@TableName("mbp_exception_log")
public class ExceptionLog extends SuperEntity{
@Column(name = "oper_user_id",comment = "操作用户id")
private Long operUserId;
@Column(name = "oper_user_name",comment = "操作用户名")
private String operUserName;
@Column(name = "exc_requ_param",comment = "请求参数",type = MySqlTypeConstant.TEXT)
private String excRequParam;
@Column(name = "oper_method",comment = "操作方法")
private String operMethod;
@Column(name = "oper_uri",comment = "请求uri")
private String operUri;
@Column(name = "oper_ip",comment = "请求ip")
private String operIp;
@Column(name = "oper_version",comment = "版本号")
private String operVersion;
@Column(name = "exc_name",comment = "异常名称")
private String excName;
@Column(name = "exc_msg",comment = "异常信息",type = MySqlTypeConstant.TEXT)
private String excMsg;
}

45
src/main/java/com/aiprose/mbp/entity/SysLog.java

@ -0,0 +1,45 @@
package com.aiprose.mbp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;
import lombok.Data;
@Data
@Table(name="mbp_syslog")
@TableName("mbp_syslog")
public class SysLog extends SuperEntity{
@Column(name = "oper_user_id",comment = "操作用户id")
private Long operUserId;
@Column(name = "oper_user_name",comment = "操作用户名")
private String operUserName;
@Column(name = "oper_modul",comment = "功能模块")
private String operModul;
@Column(name = "oper_type",comment = "操作类型")
private String operType;
@Column(name = "oper_desc",comment = "操作描述")
private String operDesc;
@Column(name = "oper_requ_param",comment = "请求参数",type = MySqlTypeConstant.TEXT)
private String operRequParam;
@Column(name = "oper_resp_param",comment = "返回参数",type = MySqlTypeConstant.TEXT)
private String operRespParam;
@Column(name = "oper_method",comment = "操作方法")
private String operMethod;
@Column(name = "oper_uri",comment = "请求uri")
private String operUri;
@Column(name = "oper_ip",comment = "请求ip")
private String operIp;
@Column(name = "oper_version",comment = "版本号")
private String operVersion;
}

10
src/main/java/com/aiprose/mbp/mapper/ExceptionLogMapper.java

@ -0,0 +1,10 @@
package com.aiprose.mbp.mapper;
import com.aiprose.mbp.entity.ExceptionLog;
import com.aiprose.mbp.entity.SysLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ExceptionLogMapper extends BaseMapper<ExceptionLog> {
}

9
src/main/java/com/aiprose/mbp/mapper/SysLogMapper.java

@ -0,0 +1,9 @@
package com.aiprose.mbp.mapper;
import com.aiprose.mbp.entity.SysLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysLogMapper extends BaseMapper<SysLog> {
}

13
src/main/java/com/aiprose/mbp/service/ExceptionLogService.java

@ -0,0 +1,13 @@
package com.aiprose.mbp.service;
import com.aiprose.mbp.entity.ExceptionLog;
import com.aiprose.mbp.entity.SysLog;
import com.aiprose.mbp.mapper.ExceptionLogMapper;
import com.aiprose.mbp.mapper.SysLogMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class ExceptionLogService extends ServiceImpl<ExceptionLogMapper, ExceptionLog> {
}

18
src/main/java/com/aiprose/mbp/service/SysLogService.java

@ -0,0 +1,18 @@
package com.aiprose.mbp.service;
import com.aiprose.mbp.entity.SysLog;
import com.aiprose.mbp.entity.User;
import com.aiprose.mbp.mapper.SysLogMapper;
import com.aiprose.mbp.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysLogService extends ServiceImpl<SysLogMapper, SysLog> {
}

19
src/main/java/com/aiprose/mbp/service/UserService.java

@ -6,33 +6,28 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Service
public class UserService extends ServiceImpl<UserMapper,User> {
@Autowired
private UserMapper userMapper;
public List<User> list(){
List<User> userList1 = userMapper.queryList();
List<User> userList = userMapper.selectList(new QueryWrapper<User>().lambda().eq(User::getName,"nelson"));
List<User> userList1 = baseMapper.queryList();
List<User> userList = baseMapper.selectList(new QueryWrapper<User>().lambda().eq(User::getName,"nelson"));
return userList;
}
public List<User> fingByName(String name,Integer age){
List<User> userList = userMapper.selectByName(name,age);
List<User> userList = baseMapper.selectByName(name,age);
return userList;
}
public Page<User> page(){
Page<User> page = userMapper.selectPage(new Page<User>(1, 2), new QueryWrapper<User>().eq("name","nelson"));
public Page<User> page(Integer pageNum,Integer pageSize){
Page<User> page = baseMapper.selectPage(new Page<User>(pageNum, pageSize), new QueryWrapper<User>().eq("name","nelson"));
return page;
}
}

26
src/main/java/com/aiprose/mbp/util/IPUtil.java

@ -0,0 +1,26 @@
package com.aiprose.mbp.util;
import javax.servlet.http.HttpServletRequest;
public class IPUtil {
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话X-Forwarded-For的值并不止一个而是一串IP地址X-Forwarded-For中第一个非unknown的有效IP字符串则为真实IP地址
*/
public static 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 "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
}

1
src/main/resources/application.yml

@ -1,3 +1,4 @@
version: v0.1
server:
port: 8200
spring:

Loading…
Cancel
Save