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

如何仅对特定Endpoint记录RestTemplate请求与响应日志?

RestTemplate特定Endpoint日志记录解决方案

1. 自定义拦截器实现Endpoint过滤

基于你已实现的日志逻辑,在拦截器中添加目标Endpoint的匹配判断,仅对符合条件的请求/响应输出日志:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Set;

public class TargetEndpointLoggingInterceptor implements ClientHttpRequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(TargetEndpointLoggingInterceptor.class);
    // 定义需要记录日志的Endpoint集合
    private final Set<String> targetEndpoints = Set.of("/api/v1/payments", "/api/v1/notifications");

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        String requestUri = request.getURI().getPath();
        boolean needLog = targetEndpoints.stream().anyMatch(requestUri::startsWith);

        // 仅匹配目标Endpoint时记录请求日志
        if (needLog) {
            logRequestDetails(request, body);
        }

        ClientHttpResponse response = execution.execute(request, body);

        // 仅匹配目标Endpoint时记录响应日志
        if (needLog) {
            logResponseDetails(response);
        }

        return response;
    }

    private void logRequestDetails(HttpRequest request, byte[] body) {
        logger.info("Request URI: {}, Method: {}, Headers: {}, Body: {}",
                request.getURI(), request.getMethod(), request.getHeaders(),
                new String(body, StandardCharsets.UTF_8));
    }

    private void logResponseDetails(ClientHttpResponse response) throws IOException {
        String responseBody = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
        logger.info("Response Status: {}, Headers: {}, Body: {}",
                response.getStatusCode(), response.getHeaders(), responseBody);
    }
}

2. 注册自定义拦截器到RestTemplate

在RestTemplate配置类中替换原日志拦截器,使用上述自定义拦截器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class RestTemplateConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new TargetEndpointLoggingInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
}

3. 动态配置目标Endpoint(可选)

若需要灵活调整目标Endpoint,可从配置文件读取,避免硬编码:

拦截器修改

import org.springframework.beans.factory.annotation.Value;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class TargetEndpointLoggingInterceptor implements ClientHttpRequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(TargetEndpointLoggingInterceptor.class);
    private final Set<String> targetEndpoints;

    // 从配置文件注入目标Endpoint列表
    public TargetEndpointLoggingInterceptor(@Value("#{'${rest.log.target.endpoints}'.split(',')}") List<String> endpoints) {
        this.targetEndpoints = new HashSet<>(endpoints);
    }

    // 后续intercept、日志方法逻辑同前
}

配置文件添加参数

# application.properties
rest.log.target.endpoints=/api/v1/payments,/api/v1/notifications,/api/v1/orders

4. 多RestTemplate实例隔离日志(可选)

若部分请求无需日志,可创建两个RestTemplate实例,分别对应日志/非日志场景:

@Configuration
public class RestTemplateConfiguration {

    // 带日志拦截的实例,用于特定Endpoint请求
    @Bean("loggingRestTemplate")
    public RestTemplate loggingRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new TargetEndpointLoggingInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }

    // 普通实例,不记录日志
    @Bean
    public RestTemplate defaultRestTemplate() {
        return new RestTemplate();
    }
}

使用时指定注入对应实例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.client.RestTemplate;

// 注入带日志的实例处理需要日志的请求
@Autowired
@Qualifier("loggingRestTemplate")
private RestTemplate loggingRestTemplate;

// 注入普通实例处理无需日志的请求
@Autowired
@Qualifier("defaultRestTemplate")
private RestTemplate defaultRestTemplate;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:50:11