【SpringBootAOP记录用户操作日志】4.切面和切点

编程

定义一个LogAspect类,使用@Aspect标注让其成为一个切面,切点为使用@Log注解标注的方法

加aop依赖

<!-- aop依赖 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

 

新建LogAspect类

import com.aoplog.springbootaoplog.annotation.Log;

import com.aoplog.springbootaoplog.domain.SysOperLog;

import com.aoplog.springbootaoplog.enums.BusinessStatus;

import com.aoplog.springbootaoplog.manager.AsyncManager;

import com.aoplog.springbootaoplog.manager.factory.AsyncFactory;

import com.aoplog.springbootaoplog.util.JSON;

import org.apache.commons.lang3.StringUtils;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.Signature;

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.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.web.context.request.RequestAttributes;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;

import java.util.Map;

/**

* 操作日志记录处理

*

* @author hekang

*/

@Aspect

@Component

public class LogAspect

{

private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

/**

* 配置织入点

*/

@Pointcut("@annotation(com.aoplog.springbootaoplog.annotation.Log)")

public void logPointCut()

{

}

/**

* 处理完请求后执行

*

* @param joinPoint 切点

*/

@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")

public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)

{

handleLog(joinPoint, null, jsonResult);

}

/**

* 拦截异常操作

*

* @param joinPoint 切点

* @param e 异常

*/

@AfterThrowing(value = "logPointCut()", throwing = "e")

public void doAfterThrowing(JoinPoint joinPoint, Exception e)

{

handleLog(joinPoint, e, null);

}

protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)

{

try

{

// 获得注解

Log controllerLog = getAnnotationLog(joinPoint);

if (controllerLog == null)

{

return;

}

// 获取当前的用户资料取数据库 或者 Shiro Session

// *========数据库日志=========*//

SysOperLog operLog = new SysOperLog();

operLog.setStatus(BusinessStatus.SUCCESS.ordinal());

// 请求的地址 从Shiro或者security取都行

String ip = "127.0.0.1";

operLog.setOperIp(ip);

// 返回参数

operLog.setJsonResult(JSON.marshal(jsonResult));

/**

* 请求url

*/

RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

ServletRequestAttributes getRequestAttributes = (ServletRequestAttributes) attributes;

operLog.setOperUrl(getRequestAttributes.getRequest().getRequestURI());

//动态 从Shiro或者security取都行

operLog.setOperName("admin");

if (e != null)

{

operLog.setStatus(BusinessStatus.FAIL.ordinal());

operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));

}

// 设置方法名称

String className = joinPoint.getTarget().getClass().getName();

String methodName = joinPoint.getSignature().getName();

operLog.setMethod(className + "." + methodName + "()");

// 设置请求方式

operLog.setRequestMethod(getRequestAttributes.getRequest().getMethod());

// 处理设置注解上的参数

getControllerMethodDescription(controllerLog, operLog);

// 保存数据库

AsyncManager.me().execute(AsyncFactory.recordOper(operLog));

}

catch (Exception exp)

{

// 记录本地异常日志

log.error("==前置通知异常==");

log.error("异常信息:{}", exp.getMessage());

exp.printStackTrace();

}

}

/**

* 获取注解中对方法的描述信息 用于Controller层注解

*

* @param log 日志

* @param operLog 操作日志

* @throws Exception

*/

public void getControllerMethodDescription(Log log, SysOperLog operLog) throws Exception

{

// 设置action动作

operLog.setBusinessType(log.businessType().ordinal());

// 设置标题

operLog.setTitle(log.title());

// 设置操作人类别

operLog.setOperatorType(log.operatorType().ordinal());

// 是否需要保存request,参数和值

if (log.isSaveRequestData())

{

// 获取参数的信息,传入到数据库中。

setRequestValue(operLog);

}

}

/**

* 获取请求的参数,放到log中

*

* @param operLog 操作日志

* @throws Exception 异常

*/

private void setRequestValue(SysOperLog operLog) throws Exception

{

RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

ServletRequestAttributes getRequestAttributes = (ServletRequestAttributes) attributes;

Map<String, String[]> map = getRequestAttributes.getRequest().getParameterMap();

String params = JSON.marshal(map);

operLog.setOperParam(StringUtils.substring(params, 0, 2000));

}

/**

* 是否存在注解,如果存在就获取

*/

private Log getAnnotationLog(JoinPoint joinPoint) throws Exception

{

Signature signature = joinPoint.getSignature();

MethodSignature methodSignature = (MethodSignature) signature;

Method method = methodSignature.getMethod();

if (method != null)

{

return method.getAnnotation(Log.class);

}

return null;

}

}

创建JSON解析处理工具包

import com.fasterxml.jackson.core.JsonGenerationException;

import com.fasterxml.jackson.core.JsonParseException;

import com.fasterxml.jackson.databind.JsonMappingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.ObjectWriter;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

/**

* JSON解析处理

*

* @author hekang

*/

public class JSON

{

public static final String DEFAULT_FAIL = ""Parse failed"";

private static final ObjectMapper objectMapper = new ObjectMapper();

private static final ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter();

public static void marshal(File file, Object value) throws Exception

{

try

{

objectWriter.writeValue(file, value);

}

catch (JsonGenerationException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static void marshal(OutputStream os, Object value) throws Exception

{

try

{

objectWriter.writeValue(os, value);

}

catch (JsonGenerationException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static String marshal(Object value) throws Exception

{

try

{

return objectWriter.writeValueAsString(value);

}

catch (JsonGenerationException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static byte[] marshalBytes(Object value) throws Exception

{

try

{

return objectWriter.writeValueAsBytes(value);

}

catch (JsonGenerationException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static <T> T unmarshal(File file, Class<T> valueType) throws Exception

{

try

{

return objectMapper.readValue(file, valueType);

}

catch (JsonParseException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static <T> T unmarshal(InputStream is, Class<T> valueType) throws Exception

{

try

{

return objectMapper.readValue(is, valueType);

}

catch (JsonParseException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static <T> T unmarshal(String str, Class<T> valueType) throws Exception

{

try

{

return objectMapper.readValue(str, valueType);

}

catch (JsonParseException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

public static <T> T unmarshal(byte[] bytes, Class<T> valueType) throws Exception

{

try

{

if (bytes == null)

{

bytes = new byte[0];

}

return objectMapper.readValue(bytes, 0, bytes.length, valueType);

}

catch (JsonParseException e)

{

throw new Exception(e);

}

catch (JsonMappingException e)

{

throw new Exception(e);

}

catch (IOException e)

{

throw new Exception(e);

}

}

}

 

创建操作状态BusinessStatus枚举

/**

* 操作状态

*

* @author hekang

*/

public enum BusinessStatus

{

/**

* 成功

*/

SUCCESS,

/**

* 失败

*/

FAIL,

}

 

修改SysOperLogController类加@Log

import com.aoplog.springbootaoplog.annotation.Log;

import com.aoplog.springbootaoplog.domain.SysOperLog;

import com.aoplog.springbootaoplog.enums.BusinessType;

import com.aoplog.springbootaoplog.service.ISysOperLogService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController

public class SysOperLogController {

@Autowired

private ISysOperLogService iSysOperLogService;

/**

* 查询全部日志 加操作日志

*

* @return

*/

@GetMapping("/api/operLog")

@Log(title = "查询全部日志", businessType = BusinessType.SELECT)

public List<SysOperLog> selectOperLogList1() {

return this.iSysOperLogService.selectOperLogList(null);

}

/**

* 修改日志 加操作日志

*

* @return

*/

@GetMapping("/api/operLog/{id}")

@Log(title = "修改日志", businessType = BusinessType.UPDATE)

public List<SysOperLog> updateOperLog(@PathVariable("id") Long id) {

//不做实际操作

return this.iSysOperLogService.selectOperLogList(null);

}

/**

* 查询全部日志

*

* @return

*/

@GetMapping("/operLog")

public List<SysOperLog> selectOperLogList2() {

return this.iSysOperLogService.selectOperLogList(null);

}

}

 

启动项目测试:

先查询没有数据:http://127.0.0.1:8080/operLog

 

访问:

查询操作

http://127.0.0.1:8080/api/operLog  

修改操作 

http://127.0.0.1:8080/api/operLog/1

 

再访问:http://127.0.0.1:8080/operLog 

 

源码:https://gitee.com/hekang_admin/spring-boot-aop-log.git

以上是 【SpringBootAOP记录用户操作日志】4.切面和切点 的全部内容, 来源链接: utcz.com/z/512231.html

回到顶部