java 使用 spring RestTemplate 在休息客户端上的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47388545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practices on rest client using spring RestTemplate
提问by Chamly Idunil
I have read some tutorials about implementing REST client in java web application that use SPRING to manage beans.
我已经阅读了一些关于在使用 SPRING 管理 bean 的 Java Web 应用程序中实现 REST 客户端的教程。
Every example I found, every time doing a REST request it creates new RestTemplate.
我发现的每个示例,每次执行 REST 请求时都会创建新的 RestTemplate。
Normally web applications use singleton spring bean.
通常 Web 应用程序使用单例 spring bean。
So I want to know when what is the best practice to use RestTemplate in Spring configures application ?
Use singleton RestTemplate ?
Create RestTemplate in every request. ?
所以我想知道什么时候在 Spring 配置应用程序中使用 RestTemplate 的最佳实践是什么?
使用单例 RestTemplate ?
在每个请求中创建 RestTemplate。?
Please advise and describe all situations.
请告知并描述所有情况。
回答by pvpkiran
One of the best ways to do this is to create a bean which would return a RestTemplate and then Autowire it in which ever class you need.
最好的方法之一是创建一个 bean,它会返回一个 RestTemplate,然后在您需要的任何类中自动装配它。
Something like this.
像这样的东西。
@Configuration
public class ProductServiceConfig {
@Value("${product.username}")
private String productServiceUsername;
@Value("${product.password}")
private String productServicePassword;
@Bean(name = "restTemplateForProductService")
public RestTemplate prepareRestTemplateForProductService() {
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(productServiceUsername, productServicePassword));
RequestConfig.Builder requestBuilder = RequestConfig.custom();
requestBuilder = requestBuilder.setConnectTimeout(1000);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
httpClientBuilder.setDefaultRequestConfig(requestBuilder.build());
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(rf);
}
}
This way you can set different parameters that you want for your rest call, like timeouts or credentials etc. And when you want to use, you can just do
这样你就可以为你的休息调用设置不同的参数,比如超时或凭据等。当你想使用时,你可以这样做
@Autowired
RestTemplate restTemplateForProductService;
restTemplateForProductService.......
Another advantage of this over using new RestTemplate ()
is if you have to call different services through REST, then you can define multiple beans (with different configuration) which returns RestTemplates and autowire it using the name
与 using 相比的另一个优点new RestTemplate ()
是,如果您必须通过 REST 调用不同的服务,那么您可以定义多个 bean(具有不同的配置),它返回 RestTemplates 并使用名称自动装配它
回答by Johnny.Minty
You should take one of the following approaches when using RestTemplate.
在使用 RestTemplate 时,您应该采用以下方法之一。
Static instance:
静态实例:
/**
* Rest template client
*/
private static final RestTemplate TEMPLATE = new RestTemplate(new RestClientRequestFactory());
static{
//Set your options here
Hymanson2ObjectMapperBuilder builder = new Hymanson2ObjectMapperBuilder();
builder.featuresToEnable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
MappingHymanson2HttpMessageConverter jsonMessageConverter = new MappingHymanson2HttpMessageConverter();
jsonMessageConverter.setObjectMapper(builder.build());
TEMPLATE.setMessageConverters(Arrays.asList(jsonMessageConverter));
}
Or delcare a Spring Bean in a @Configuration class:
或者在 @Configuration 类中 delcare 一个 Spring Bean:
@Bean
public RestTemplate restTemplate(){
RestTemplate template = new RestTemplate(new RestClientRequestFactory())
//customize
return template;
}
If you look at the RestTemplate class the you want to avoid hitting the default Constructor too many times:
如果您查看 RestTemplate 类,您会希望避免多次使用默认构造函数:
public RestTemplate() {
this.messageConverters = new ArrayList();
this.errorHandler = new DefaultResponseErrorHandler();
this.uriTemplateHandler = new DefaultUriTemplateHandler();
this.headersExtractor = new RestTemplate.HeadersExtractor();
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter());
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (Hymanson2XmlPresent) {
this.messageConverters.add(new MappingHymanson2XmlHttpMessageConverter());
} else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (Hymanson2Present) {
this.messageConverters.add(new MappingHymanson2HttpMessageConverter());
} else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
}
}