前言
上篇文件主要是讲了如何使用aop记录用户操作日志,这篇文件将介绍如何使用拦截器记录操作日志
导入依赖
在处理请求参数时需要用到Json,其他依赖请查看源码
<!-- Json解析 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
部分配置文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/log
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
创建实体类
@Entity
@Data
@Table(name = "zj_syslog")
public class SysLog implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String url;
private Integer time;
private String method;
private String params;
private String ip;
/**
* ip地址来源
*/
private String location;
@CreationTimestamp
private Timestamp createTime;
}
创建 repository
@Repository
public interface SysLogRepo extends JpaRepository<SysLog,Long>{
}
自定义日志拦截器
public class LogInterceptor implements HandlerInterceptor {
//请求开始时间标识
private static final String LOGGER_SEND_TIME = "_send_time";
//请求日志实体标识
private static final String LOGGER_ENTITY = "_logger_entity";
/**
* 进入SpringMVC的Controller之前开始记录日志实体
* @param request 请求对象
* @param response 响应对象
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
//创建日志实体
SysLog sysLog = new SysLog();
//获取请求参数信息
String param = JSON.toJSONString(request.getParameterMap(),
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue);
//设置请求参数
sysLog.setParams(param);
// 设置IP地址
sysLog.setIp(AddressUtils.getIpAddr(request));
sysLog.setLocation(AddressUtils.getCityInfo(sysLog.getIp()));
//设置请求方法,GET,POST...
sysLog.setMethod(request.getMethod());
//设置请求路径
sysLog.setUrl(request.getRequestURI());
//设置请求开始时间
request.setAttribute(LOGGER_SEND_TIME,System.currentTimeMillis());
//设置请求实体到request内,方便afterCompletion方法调用
request.setAttribute(LOGGER_ENTITY,sysLog);
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
int status = httpServletResponse.getStatus();
//根据不同状态码,跳转不同页面,如
if(status==404){
modelAndView.setViewName("/404");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
//得到bean
SysLogRepo sysLogRepo = SpringContextUtils.getBean("sysLogRepo",SysLogRepo.class);
//获取请求错误码,根据需求存入数据库,这里不保存
int status = response.getStatus();
//当前时间
long currentTime = System.currentTimeMillis();
//请求开始时间
long time = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString());
//获取本次请求日志实体
SysLog sysLog = (SysLog) request.getAttribute(LOGGER_ENTITY);
//设置访问者
sysLog.setUsername("admin");
//设置请求时间差
sysLog.setTime(Integer.valueOf((currentTime - time)+""));
//执行将日志写入数据库,可以根据实际需求进行保存
if(!sysLog.getMethod().equals("GET")){
}
sysLogRepo.save(sysLog);
}
}
新增ConfigurerAdapter
新增ConfigurerAdapter类,实现WebMvcConfigurer接口
重写addInterceptors方法,添加我们的拦截器
@Configuration
public class ConfigurerAdapter implements WebMvcConfigurer {
//设置排除路径,spring boot 2.*,注意排除掉静态资源的路径,不然静态资源无法访问
private final String[] excludePath = {"/list"};
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 添加日志的拦截器
*/
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**").excludePathPatterns(excludePath);
}
}
项目结构如下
测试
编写TestController
@RestController
public class TestController {
@Autowired
private SysLogRepo sysLogRepo;
@GetMapping(value = "/test")
public String test1(String test){
return test;
}
@GetMapping(value = "/list")
public ModelAndView list(Model model){
List<SysLog> sysLogs = sysLogRepo.findAll();
model.addAttribute("sysLogs",sysLogs);
return new ModelAndView("/index");
}
}
依次访问:
项目源码
github:https://github.com/dqjdda/SpringBoot_All
码云:https://gitee.com/hgpt/SpringBoot_All
开源后台管理系统
欢迎体验Aurora
github: https://github.com/dqjdda/Aurora