升级spring-boot版本,从2.7.16到3.2.5,踩坑记录(一)
·
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;
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)