You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中如何审计端点通信?获取交互JSON并存储至数据库

Capturing Endpoint Interaction Data for Javers Auditing

Hey there! Let's walk through how to capture that JSON data from endpoint interactions and feed it into Javers for auditing. I'll focus on practical, actionable steps—especially since Javers is commonly used in Java/Spring ecosystems, I'll use that as the primary example.

Step 1: Capture Request/Response Data

First, you need a way to intercept incoming requests and outgoing responses to extract their JSON payloads. Here are the most reliable approaches:

Option 1: Spring Interceptors + Content Caching

Spring provides built-in wrappers to cache request/response bodies (since they can only be read once by default). Create a custom interceptor to handle this:

@Component
public class EndpointAuditInterceptor implements HandlerInterceptor {

    private final ObjectMapper objectMapper;
    private final Javers javers;

    // Inject dependencies via constructor
    public EndpointAuditInterceptor(ObjectMapper objectMapper, Javers javers) {
        this.objectMapper = objectMapper;
        this.javers = javers;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // Wrap request to cache body for later reading
        ContentCachingRequestWrapper cachedRequest = new ContentCachingRequestWrapper(request);
        request.setAttribute("cachedRequest", cachedRequest);
        // Wrap response to capture its output
        ContentCachingResponseWrapper cachedResponse = new ContentCachingResponseWrapper(response);
        request.setAttribute("cachedResponse", cachedResponse);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ContentCachingRequestWrapper cachedRequest = (ContentCachingRequestWrapper) request.getAttribute("cachedRequest");
        ContentCachingResponseWrapper cachedResponse = (ContentCachingResponseWrapper) request.getAttribute("cachedResponse");

        // Extract request/response bodies as strings
        String requestBody = new String(cachedRequest.getContentAsByteArray(), cachedRequest.getCharacterEncoding());
        String responseBody = new String(cachedResponse.getContentAsByteArray(), cachedResponse.getCharacterEncoding());

        // Critical: Copy cached response back to original so clients receive the actual response
        cachedResponse.copyBodyToResponse();

        // Create an audit record entity to store interaction details
        EndpointAuditRecord auditRecord = new EndpointAuditRecord();
        auditRecord.setRequestUrl(request.getRequestURI());
        auditRecord.setHttpMethod(request.getMethod());
        auditRecord.setRequestBody(requestBody);
        auditRecord.setResponseBody(responseBody);
        auditRecord.setTimestamp(LocalDateTime.now());
        auditRecord.setStatus(response.getStatus());

        // Commit the record to Javers—this stores a full snapshot of the entity
        javers.commit("system-auditor", auditRecord);
    }
}

Don't forget to register the interceptor in your Spring config:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    private final EndpointAuditInterceptor auditInterceptor;

    public WebConfig(EndpointAuditInterceptor auditInterceptor) {
        this.auditInterceptor = auditInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(auditInterceptor)
                .addPathPatterns("/**"); // Adjust paths to target only your desired endpoints
    }
}

Option 2: API Gateway Level Interception

If you're using an API gateway (like Spring Cloud Gateway), intercept all traffic at the gateway layer—this is cleaner for multi-service setups, since you don't need to add interceptors to each individual service. Use a GlobalFilter to capture request/response bodies similarly to the interceptor approach.

Option 3: AOP Aspect

For granular control (e.g., auditing only specific controller methods), use a Spring AOP aspect with @Around advice to wrap controller method calls and capture input/output directly.

Step 2: Integrate with Javers

Once you have the interaction data, Javers simplifies storing and querying audit snapshots. Here's what you need:

  1. Define an Audit Entity: Create a simple POJO to represent your endpoint interaction (like EndpointAuditRecord in the example above). Javers will handle storing its full state in your database.
  2. Configure Javers: Set up Javers to use your target database (e.g., JPA for SQL databases):
@Bean
public Javers javers(EntityManager entityManager) {
    return JaversBuilder.javers()
            .registerJaversRepository(JpaJaversRepository.builder().entityManager(entityManager).build())
            .withObjectAccessHook(new JpaAccessHook())
            .build();
}
  1. Commit Records: Use javers.commit() to save each audit record. Javers will store a snapshot of the entity, including all fields like request body, response body, and timestamp.

Key Considerations

  • Sensitive Data: Always filter or mask sensitive fields (passwords, tokens, PII) before storing. Use Jackson annotations like @JsonIgnore or custom serializers to scrub data.
  • Performance: For high-traffic systems, use async processing (e.g., @Async on audit logic or a message queue like Kafka) to avoid blocking request processing.
  • Querying History: Later, use Javers' query API to retrieve audit history—e.g., find all interactions for a specific endpoint, or track changes in response payloads over time.

内容的提问来源于stack exchange,提问作者Rodolfo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:38:32