使用@RepositoryRestResource时如何自动记录请求响应日志?
Spring Data REST没有内置专门用于自动记录入站请求的注解,但可以通过以下3种成熟方案实现需求,无需修改自动生成的控制器代码,也不用改动你现有的OrganizationRepository定义:
方案1:使用Spring Boot内置请求日志工具(配置最简单)
直接通过配置开启全局请求日志即可覆盖所有Spring Data REST生成的接口:
- 第一步在
application.properties中添加日志级别配置:
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
- 如果需要自定义日志内容(打印请求参数、请求体、客户端IP等),手动注册Bean即可:
@Configuration public class RequestLogConfig { @Bean public CommonsRequestLoggingFilter requestLoggingFilter() { CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); filter.setIncludeClientInfo(true); filter.setIncludeQueryString(true); filter.setIncludePayload(true); filter.setMaxPayloadLength(10000); filter.setAfterMessagePrefix("入站请求内容:"); return filter; } }
方案2:AOP切面定制化日志(灵活度最高)
如果需要只针对标注了@RepositoryRestResource的Repository做日志采集,可以用Spring AOP实现:
- 先引入AOP依赖:
<!-- Maven依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 编写切面类:
@Aspect @Component public class RestRepositoryLogAspect { private static final Logger log = LoggerFactory.getLogger(RestRepositoryLogAspect.class); // 切点匹配所有@RepositoryRestResource标注的Repository类 @Pointcut("within(@org.springframework.data.rest.core.annotation.RepositoryRestResource *)") public void restRepositoryPointcut() {} @Before("restRepositoryPointcut()") public void logBeforeInvoke(JoinPoint joinPoint) { log.info("调用Repository接口:方法名={},入参={}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs())); } @AfterReturning(pointcut = "restRepositoryPointcut()", returning = "result") public void logAfterInvoke(JoinPoint joinPoint, Object result) { log.info("Repository接口返回:方法名={},返回值={}", joinPoint.getSignature().getName(), result); } }
方案3:监听Spring Data REST生命周期事件(和业务操作绑定最紧密)
Spring Data REST提供了全套实体操作生命周期事件,可直接监听这些事件来记录对应操作的日志:
@Component @RepositoryEventHandler public class RepositoryOperationListener { private static final Logger log = LoggerFactory.getLogger(RepositoryOperationListener.class); // 监听创建实体前事件 @HandleBeforeCreate public void beforeCreate(Object entity) { log.info("即将创建实体:{}", entity); } // 监听创建实体后事件 @HandleAfterCreate public void afterCreate(Object entity) { log.info("实体创建完成:{}", entity); } // 还可根据需求添加@HandleBeforeSave、@HandleAfterSave、@HandleBeforeDelete等监听方法 }
内容的提问来源于stack exchange,提问作者Ethan Miller
相关产品推荐
相关产品推荐

