Spring Boot 使用拦截器记录用户操作日志

xiaoxiao2023-03-25  36

导入依赖

在处理请求参数时需要用到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"); } }

依次访问:

localhost:8080/test?test=123

localhost:8080/list

转载请注明原文地址: https://www.6miu.com/read-4988142.html
最新回复(0)