我在其中一个项目中使用RestTemplate及其工厂HttpComponentsClientHttpRequestFactory。在这个项目中,我需要对我的服务器进行Http url调用,该服务器运行一个restful服务,它将响应作为JSON字符串返回。
以下是我的代码 -
public class GetUserClientData {
public String getData(KeyHolder keys) {
return new HTTPRequestAccess(keys).makeHttpRequest();
}
}
下面是我的包装HttpClient部分的类 -
public class HTTPRequestAccess {
// should this be static?
private RestTemplate restTemplate;
private KeyHolder keys;
private int timeout;
public HTTPRequestAccess(KeyHolder keys){
this(keys.getTimeoutValue()); // setting timeout to RestTemplate
this.keys = keys;
}
public HTTPRequestAccess(int timeout) {
this.timeout = timeout;
restTemplate = new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
// is this not expensive that every time we are creating this new object?
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(timeout);
factory.setConnectTimeout(timeout);
return factory;
}
public String makeHttpRequest() {
String response = null;
try {
// some logic here
String url = generateURL();
response = restTemplate.getForObject(url, String.class);
// some logic here
} catch (RestClientException ex) {
// log exception and do some stuff
} catch (Exception ex) {
// log exception
}
return response;
}
}
我的RestTemplate
类中HttpComponentsClientHttpRequestFactory
和HTTPRequestAccess
应该是静态的,就像我正确看到它一样,我正在为RestTemplate
中的每个请求重新创建整个连接池。我想是不正确的方法,因为每个工厂都有连接和线程池,我猜它们是非常重的对象。
一般来说,在多线程环境中使用RestTemplate
及其工厂HttpComponentsClientHttpRequestFactory
的最佳方法是什么?我猜RestTemplate
是线程安全的,但我不认为HttpComponentsClientHttpRequestFactory
是线程安全的。如果我错了,请纠正我?我将在重载下运行这个库。
我正在使用spring-web-3.2.8.RELEASE
版本。
答案 0 :(得分:2)
在我的一个项目中,我创建了一个HttpComponentsClientHttpRequestFactory的静态实例,并将其传递给每个RestTemplate。 但是,在here中,建议还有一个RestTemplate的全局实例。
可能无关紧要,但重要的一点是在构造它时将HttpClients.createDefault()传递给你的HttpComponentsClientHttpRequestFactory,因为默认情况下,这个工厂使用系统属性为你的工厂创建HttpClient,这可能会给生产环境带来很多痛苦。 您也可以传递自定义HttpClient。