diff --git a/backend-single/src/main/java/com/emotion/config/RestTemplateConfig.java b/backend-single/src/main/java/com/emotion/config/RestTemplateConfig.java index 26329c8..3ad4d55 100644 --- a/backend-single/src/main/java/com/emotion/config/RestTemplateConfig.java +++ b/backend-single/src/main/java/com/emotion/config/RestTemplateConfig.java @@ -1,13 +1,52 @@ package com.emotion.config; +import com.emotion.interceptor.WechatApiLoggingInterceptor; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.web.client.RestTemplate; +import java.nio.charset.StandardCharsets; +import java.time.Duration; + +/** + * 统一 RestTemplate Bean + * + *

设计要点: + *

    + *
  1. 用 BufferingClientHttpRequestFactory 包装 SimpleClientHttpRequestFactory, + * 响应体被缓存到字节数组,可被 Interceptor / ErrorHandler / Converter 多次读取 + * (避免破坏其他 7 个 RestTemplate 使用点:DifyProviderAdapter、 + * CozeProviderAdapter、HttpTtsEngineClient、AsrServiceImpl、 + * ApiEndpointServiceImpl、AiChatServiceImpl、ApiTestProxyController)
  2. + *
  3. 显式设置 User-Agent 为 Mozilla/5.0,绕过 WAF / CloudFlare 对 Java/* 默认 UA 的拦截
  4. + *
  5. 显式设置连接 / 读取超时,避免线程被 hang 住
  6. + *
  7. 加 StringHttpMessageConverter(UTF_8) 支持 text/plain 响应
  8. + *
  9. 加 WechatApiLoggingInterceptor 记录请求 / 响应(脱敏)
  10. + *
  11. 加 WechatResponseErrorHandler 4xx/5xx 不抛异常
  12. + *
+ */ @Configuration public class RestTemplateConfig { + @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); + public RestTemplate restTemplate(RestTemplateBuilder builder) { + SimpleClientHttpRequestFactory simpleFactory = new SimpleClientHttpRequestFactory(); + simpleFactory.setConnectTimeout((int) Duration.ofSeconds(5).toMillis()); + simpleFactory.setReadTimeout((int) Duration.ofSeconds(10).toMillis()); + BufferingClientHttpRequestFactory bufferingFactory = + new BufferingClientHttpRequestFactory(simpleFactory); + + return builder + .requestFactory(() -> bufferingFactory) + .defaultHeader("User-Agent", "Mozilla/5.0 (compatible; EmotionMuseum/1.0)") + .defaultHeader("Accept", "application/json, text/plain, */*") + .additionalMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8)) + .additionalInterceptors(new WechatApiLoggingInterceptor()) + .errorHandler(new WechatResponseErrorHandler()) + .build(); } -} \ No newline at end of file +}