使⽤(intercept)和AOP记录操作⽇志-springboot
⽇志⽅法
⽅法⼀ .创建类(使⽤全局拦截所有请求)
public class LogInterceptor implements HandlerInterceptor {
private final Logger logger = Logger(LogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//把整个log中的参数,交给logUtil来获取,并返回log对象
Log log = null;
try {
log = Log(httpServletRequest);
}catch (GeneralException g){
logger.warn("logger",g.getMessage());
}catch (Exception e){
<("logger",e.getMessage());
}
httpServletRequest.setAttribute(LoggerUtil.LOG_OPERATE,log);
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exc }
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//返回视图时,插⼊操作⽇志
LogMapper logMapper = getMapper(LogMapper.class,httpServletRequest);
Log log = (Log) Attribute(LoggerUtil.LOG_OPERATE);
if(log == null){
logger.warn("⽇志信息为空",log);
}else{
logMapper.insert(log);
}
}
private <T> T getMapper(Class<T> clazz,HttpServletRequest request)
{
BeanFactory factory = ServletContext());
Bean(clazz);
}
}
的执⾏顺序,这⾥不解释了。这⾥注意mapper类是如何创建的。
2. 注册
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login"); registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
1. LoggerUtil类(保存数据⼊库使⽤)
public class LoggerUtil {
public static final String LOG_TARGET_TYPE="targetType";
public static final String LOG_ACTION="action";
public static final String LOG_REMARK="remark";
public LoggerUtil(){}
public static Log getLog(HttpServletRequest request){
//1.依次获取每个属性信息 userId,operator,action,remark,ip,targetType
Log log = new Log();
log.CliectIp(request));
log.setOperator("operator");
log.setUserId(1);
log.setAction("create");
log.setCustomerId("0000-1111");
log.setTargetType("message");
log.setRemark("消息发布");
return log;
}
/**
* 获取客户端ip地址
* @param request
* @return
*/
public static String getCliectIp(HttpServletRequest request){
String ip = Header("X-Real-IP");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
return ip;
}
ip = Header("X-Forwarded-For");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个IP值,第⼀个为真实IP。
int index = ip.indexOf(',');
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
} else {
RemoteAddr();
}
}
}
loggerUtil类主要返回⼀个Log对象的实体类。
⽅法⼆ AOP记录操作⽇志
1. 引⼊springboot的aop的jar
<dependency>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
1. LogAopAction类
@Aspect
@Component
public class LogAopAction {
private final Logger logger = Logger(LogAopAction.class);
@Autowired
private OperatorLogService operatorLogService;
@Autowired
private OperationUserService userService;
@Pointcut("@annotation(s.config.aopLog.LogAnnotation)")//配置切点
private void pointCutMethod() {
}
//around可获取请求和返回参数!
@AfterReturning(value = "pointCutMethod()",returning = "rtv") //执⾏后操作
public void after(JoinPoint joinPoint, Object rtv) {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestAttributes(); HttpServletRequest request = Request();
OperationUserCmsModel userSession = UserSession(request);
if (userSession != null) {
//获取请求参数
String beanName = Signature().getDeclaringTypeName();
String methodName = Signature().getName();
String url = RequestURI();
String remoteAddr = getIpAddr(request);
String requestMethod = Method();
try {
String targetName = Target().getClass().getName();
Class targetClass = Class.forName(targetName);
Method[] methods = Methods();
OperatorLogDto optLog = new OperatorLogDto();
//请求参数
if (ParameterMap()!=null && ParameterMap().isEmpty()!=true) {//dan
optLog.ParameterMap()));
}else {
Object[] object = Args();
if (object.length>1){
optLog.JSONString(object[1]));
}
}
optLog.JSONString(rtv));//返回参数
for (Method method : methods) {
if (Name().equals(methodName)) {
LogAnnotation logAnnotation = Annotation(LogAnnotation.class);
if (logAnnotation != null) {
springboot aopoptLog.ark());
optLog.setTargetType(logAnnotation.targetType());
}
}
}
optLog.setOperatorUrl(url);
optLog.setMethodName(methodName);
optLog.setRemoteAddr(remoteAddr);
operatorLogService.operatorLogAdd(optLog, request);
} catch (Exception e) {
<("***操作请求⽇志记录失败doBefore()***", e);
}
}
}
2.1 Pointcut优化部分
//切⼊点设置到⾃定义的log注解上
@Pointcut("@annotation(cn.vobile.hss.annotation.LogAnnotation)")
private void pointCutMethod(){}
我们可以将切⼊⽅法设置到⾃定义的log注解上,这样aop就会只在有log注解的⽅法进⾏拦截了。
1. 特殊字段的注解
@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运⾏时可通过反射获取
@Target(ElementType.METHOD)//⽬标是⽅法
@Documented//⽂档⽣成时,该注解将被包含在javadoc中,可去掉
public @interface LogAnnotation {
String targetType() default "";
String remark() default "";
}
1. 引⽤部分
@ApiOperation("商品列表-删除")
@LogAnnotation(targetType = "ProductInfo-Delete", remark = "商品删除")//切点信息
@RequestMapping(value = "/deleteProductById", method = RequestMethod.POST)
public DataOutput deleteProductById(
HttpServletRequest request,
@ApiParam(value = "商品Id") @RequestParam(value = "productId") String productId) {
return productCmsService.deleteProductById(request,productId);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论