1、HttpClientConfig改造,OkHttp3ClientHttpRequestFactory被移除,AsyncClientHttpRequestFactory、AsyncRestTemplate已被删除:

改造前得代码:

import brave.http.HttpTracing;
import brave.okhttp3.TracingInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xmair.common.configuration.JsonHeaderInterceptor;
import com.xmair.common.configuration.ProtobufHeaderInterceptor;
import com.xmair.common.configuration.ProtostuffHttpMessageConverter;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.client.AsyncClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * resttemplate使用okhttp连接池
 * */
@Configuration
public class HttpClientConfig {

    @Autowired
    HttpTracing httpTracing;
    @Autowired
    public MappingJackson2HttpMessageConverter jsonConverter;

    /**
     * 注入okhttp客户端工具类,全局唯一,共享连接池,线程安全
     */
    @Bean
    public OkHttpClient okHttpClient() {
        //注意:只有明确知道服务端支持H2C协议的时候才能使用。添加H2C支持,
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .protocols(Collections.singletonList(Protocol.H2_PRIOR_KNOWLEDGE));
        Dispatcher dispatcher=new Dispatcher(
                httpTracing.tracing().currentTraceContext()
                        .executorService(new Dispatcher().executorService())
        );
        //设置连接池大小
        dispatcher.setMaxRequests(1000);
        dispatcher.setMaxRequestsPerHost(200);
       ConnectionPool pool = new ConnectionPool(20, 30, TimeUnit.MINUTES);


        builder.connectTimeout(250, TimeUnit.MILLISECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .connectionPool(pool)

                .dispatcher(dispatcher)
               //链路监控埋点
                .addNetworkInterceptor(TracingInterceptor.create(httpTracing))
                //.addInterceptor(new OkHttpInterceptor())
                .retryOnConnectionFailure(true);
        return builder.build();
    }

    @Primary
    @Bean
    public ClientHttpRequestFactory OkHttp3Factory() {

        return new OkHttp3ClientHttpRequestFactory(okHttpClient());
    }


    private AsyncClientHttpRequestFactory AsyncClientHttpRequestFactory() {

        return new OkHttp3ClientHttpRequestFactory(okHttpClient());
    }

    @LoadBalanced
    @Bean
    public AsyncRestTemplate asyncRestTemplate(){
        AsyncRestTemplate restTemplate=new AsyncRestTemplate(AsyncClientHttpRequestFactory());
        return  restTemplate;

    }
    @Autowired
    private ObjectMapper objectMapper;

    /*
    * 服务内部交互默认用protobuf格式,通过拦截器添加accept header字段
    * */
    @Primary
    @LoadBalanced
    @Bean
    public RestTemplate restTemplateLB() {

        RestTemplate restTemplate= new RestTemplate(OkHttp3Factory());
       // RestTemplate restTemplate= new RestTemplate(nettyFactory());

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        messageConverters.add(new FormHttpMessageConverter());
        messageConverters.add(new StringHttpMessageConverter());

        MappingJackson2XmlHttpMessageConverter xmlConverter=new MappingJackson2XmlHttpMessageConverter();
        xmlConverter.setDefaultCharset(Charset.forName("utf-8"));
        List<MediaType> list = new ArrayList<MediaType>();
        list.add(MediaType.APPLICATION_XML);
        xmlConverter.setSupportedMediaTypes(list);

        messageConverters.add(0,xmlConverter);
        messageConverters.add(0,new ProtostuffHttpMessageConverter());
        messageConverters.add(0,jsonConverter);
        restTemplate.setMessageConverters(messageConverters);
        // 把自定义的ClientHttpRequestInterceptor添加到RestTemplate,可添加多个
        restTemplate.setInterceptors(Collections.singletonList(new ProtobufHeaderInterceptor()));

        return  restTemplate;
    }

    /*
   * 不通过ribbon调的服务,默认使用json,通过拦截器添加accept header字段
   * */
    @Bean(name = "signleTemplate")
    public RestTemplate restTemplate() {

        RestTemplate restTemplate= new RestTemplate(OkHttp3Factory());

        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        stringConverter.setDefaultCharset(Charset.forName("utf-8"));
        List<MediaType> list1 = new ArrayList<MediaType>();
        list1.add(MediaType.TEXT_PLAIN);
        stringConverter.setSupportedMediaTypes(list1);

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        messageConverters.add(new FormHttpMessageConverter());
        messageConverters.add(stringConverter);

        MappingJackson2XmlHttpMessageConverter xmlConverter=new MappingJackson2XmlHttpMessageConverter();
        xmlConverter.setDefaultCharset(Charset.forName("utf-8"));
        List<MediaType> list = new ArrayList<MediaType>();
        list.add(MediaType.APPLICATION_XML);
        xmlConverter.setSupportedMediaTypes(list);

        messageConverters.add(0,xmlConverter);
        messageConverters.add(0,new ProtostuffHttpMessageConverter());
        messageConverters.add(0,jsonConverter);

        restTemplate.setMessageConverters(messageConverters);
// 把自定义的ClientHttpRequestInterceptor添加到RestTemplate,可添加多个
        restTemplate.setInterceptors(Collections.singletonList(new JsonHeaderInterceptor()));


        return restTemplate;
    }


}

改造后得代码:


import brave.http.HttpTracing;
import brave.okhttp3.TracingInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xmair.common.configuration.JsonHeaderInterceptor;
import com.xmair.common.configuration.ProtobufHeaderInterceptor;
import com.xmair.common.configuration.ProtostuffHttpMessageConverter;
import io.micrometer.observation.ObservationRegistry;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * resttemplate使用okhttp连接池
 * */
@Configuration
public class HttpClientConfig {

    @Autowired
    HttpTracing httpTracing;

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    public MappingJackson2HttpMessageConverter jsonConverter;

    @Autowired
    private ObservationRegistry observationRegistry; // 新的监控体系

    /**
     * 注入okhttp客户端工具类,全局唯一,共享连接池,线程安全
     */
    @Bean
    public OkHttpClient okHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .protocols(List.of(Protocol.H2_PRIOR_KNOWLEDGE))
                .connectTimeout(Duration.ofMillis(250))
                .readTimeout(Duration.ofSeconds(10))
                .writeTimeout(Duration.ofSeconds(10))
                .connectionPool(new ConnectionPool(20, 30, TimeUnit.MINUTES))
                .retryOnConnectionFailure(true);

        // 条件式链路追踪(兼容无Tracing的环境)
        if (httpTracing != null) {
            Dispatcher dispatcher = new Dispatcher(
                    httpTracing.tracing().currentTraceContext()
                            .executorService(new Dispatcher().executorService())
            );
            dispatcher.setMaxRequests(1000);
            dispatcher.setMaxRequestsPerHost(200);
            builder.dispatcher(dispatcher)
                    .addNetworkInterceptor(TracingInterceptor.create(httpTracing));
        }

        return builder.build();
    }

    // ==================== 同步客户端配置 ====================
    @Primary
    @Bean
    public RestClient restClient(OkHttpClient okHttpClient) {
        return RestClient.builder()
                .requestFactory(new OkHttp3ClientHttpRequestFactory(okHttpClient))
                .observationRegistry(observationRegistry) // 集成新监控
                .build();
    }

    @LoadBalanced
    @Bean
    public RestClient loadBalancedRestClient(OkHttpClient okHttpClient) {
        return RestClient.builder()
                .requestFactory(new OkHttp3ClientHttpRequestFactory(okHttpClient))
                .build();
    }

    // ==================== 响应式客户端配置 ====================
// ==================== 兼容性配置 ====================
    @Primary
    @LoadBalanced
    @Bean
    public RestTemplate restTemplateLB(OkHttpClient okHttpClient) {
        RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory(okHttpClient));
        configureMessageConverters(restTemplate);
        restTemplate.setInterceptors(List.of(new ProtobufHeaderInterceptor()));
        return restTemplate;
    }

    @Bean(name = "signleTemplate")
    public RestTemplate restTemplate(OkHttpClient okHttpClient) {
        RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory(okHttpClient));
        configureMessageConverters(restTemplate);
        restTemplate.setInterceptors(List.of(new JsonHeaderInterceptor()));
        return restTemplate;
    }

    // ==================== 公共方法 ====================
    private void configureMessageConverters(RestTemplate restTemplate) {
        List<HttpMessageConverter<?>> converters = new ArrayList<>();

        // XML
        MappingJackson2XmlHttpMessageConverter xmlConverter = new MappingJackson2XmlHttpMessageConverter();
        xmlConverter.setDefaultCharset(StandardCharsets.UTF_8);
        xmlConverter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_XML));

        // Text
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        stringConverter.setSupportedMediaTypes(List.of(MediaType.TEXT_PLAIN));

        // 组装
        converters.add(new FormHttpMessageConverter());
        converters.add(stringConverter);
        converters.add(xmlConverter);
        converters.add(new ProtostuffHttpMessageConverter());
        converters.add(jsonConverter);

        restTemplate.setMessageConverters(converters);
    }
}

2、javax.validation.constraints.NotNull 改为 jakarta.validation.constraints.NotNull;

3、javax.annotation.Resource; 改为 jakarta.annotation.Resource;

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐