如何通过 RequestFactory 高效使用 RestTemplate?
How to use RestTemplate efficiently with RequestFactory?
我正在做一个项目,我需要对我的服务器进行 HTTP URL 调用,该服务器是 运行 Restful 服务,returns 返回响应作为 JSON 字符串。我在这里使用 RestTemplate
和 HttpComponentsClientHttpRequestFactory
来执行 url.
我在 RestTemplate
上使用 HttpComponentsClientHttpRequestFactory
.
设置了一个 http 请求超时(READ 和 CONNECTION 超时)
下面是我的界面:
public interface Client {
// for synchronous
public String getSyncData(String key, long timeout);
// for asynchronous
public String getAsyncData(String key, long timeout);
}
下面是我对客户端接口的实现-
public class DataClient implements Client {
private final RestTemplate restTemplate = new RestTemplate();
private ExecutorService executor = Executors.newFixedThreadPool(10);
// for synchronous call
@Override
public String getSyncData(String key, long timeout) {
String response = null;
try {
Task task = new Task(key, restTemplate, timeout);
// direct call, implementing sync call as async + waiting is bad idea.
// It is meaningless and consumes one thread from the thread pool per a call.
response = task.call();
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return response;
}
// for asynchronous call
@Override
public Future<String> getAsyncData(String key, long timeout) {
Future<String> future = null;
try {
Task task = new Task(key, restTemplate, timeout);
future = executor.submit(task);
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return future;
}
}
下面是我的简单任务class
class Task implements Callable<String> {
private RestTemplate restTemplate;
private String key;
private long timeout; // in milliseconds
public Task(String key, RestTemplate restTemplate, long timeout) {
this.key = key;
this.restTemplate = restTemplate;
this.timeout = timeout;
}
public String call() throws Exception {
String url = "some_url_created_by_using_key";
// does this looks right the way I am setting request factory?
// or is there any other effficient way to do this?
restTemplate.setRequestFactory(clientHttpRequestFactory());
String response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
return response;
}
private static ClientHttpRequestFactory clientHttpRequestFactory() {
// is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(timeout); // setting timeout as read timeout
factory.setConnectTimeout(timeout); // setting timeout as connect timeout
return factory;
}
}
现在我的问题是 - 我每次在任务 class 的调用方法中使用 RestTemplate
和 setRequestFactory
的方式是否有效?由于 RestTemplate
的创建非常繁重,所以不确定我是否做对了。
并且每次都创建一个 HttpComponentsClientHttpRequestFactory
的新实例可以吗?会贵吗?
如果我们需要在其上设置读取和连接超时,那么使用 RestTemplate
的正确有效方法是什么。
这个库会这样使用 -
String response = DataClientFactory.getInstance().getSyncData(keyData, 100);
据我所知,您重复使用同一个 RestTemplate
对象,但每个 Task
都在执行这一行:restTemplate.setRequestFactory(clientHttpRequestFactory());
。这似乎可以有竞争条件,例如一个 Task
可以设置另一个 Task
会意外使用的 RequestFactory
。
否则,您似乎在正确使用 RestTemplate
。
您的超时设置多久更改一次?如果您主要使用一个或两个超时,则可以使用具有预加载超时的 RequestFactory
构造函数创建一个或两个 RestTemplate
。如果您是效率的坚持者,请创建一个 HashMap<Integer, RestTemplate>
,每次请求新的超时时缓存 RestTemplate
和特定的超时。
否则,查看 RestTemplate's constructor, and for HttpComponentsClientHttpRequestFactory's constructor 的代码,它们看起来并不特别重,因此重复调用它们可能不会成为太大的瓶颈。
我正在做一个项目,我需要对我的服务器进行 HTTP URL 调用,该服务器是 运行 Restful 服务,returns 返回响应作为 JSON 字符串。我在这里使用 RestTemplate
和 HttpComponentsClientHttpRequestFactory
来执行 url.
我在 RestTemplate
上使用 HttpComponentsClientHttpRequestFactory
.
下面是我的界面:
public interface Client {
// for synchronous
public String getSyncData(String key, long timeout);
// for asynchronous
public String getAsyncData(String key, long timeout);
}
下面是我对客户端接口的实现-
public class DataClient implements Client {
private final RestTemplate restTemplate = new RestTemplate();
private ExecutorService executor = Executors.newFixedThreadPool(10);
// for synchronous call
@Override
public String getSyncData(String key, long timeout) {
String response = null;
try {
Task task = new Task(key, restTemplate, timeout);
// direct call, implementing sync call as async + waiting is bad idea.
// It is meaningless and consumes one thread from the thread pool per a call.
response = task.call();
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return response;
}
// for asynchronous call
@Override
public Future<String> getAsyncData(String key, long timeout) {
Future<String> future = null;
try {
Task task = new Task(key, restTemplate, timeout);
future = executor.submit(task);
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return future;
}
}
下面是我的简单任务class
class Task implements Callable<String> {
private RestTemplate restTemplate;
private String key;
private long timeout; // in milliseconds
public Task(String key, RestTemplate restTemplate, long timeout) {
this.key = key;
this.restTemplate = restTemplate;
this.timeout = timeout;
}
public String call() throws Exception {
String url = "some_url_created_by_using_key";
// does this looks right the way I am setting request factory?
// or is there any other effficient way to do this?
restTemplate.setRequestFactory(clientHttpRequestFactory());
String response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
return response;
}
private static ClientHttpRequestFactory clientHttpRequestFactory() {
// is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(timeout); // setting timeout as read timeout
factory.setConnectTimeout(timeout); // setting timeout as connect timeout
return factory;
}
}
现在我的问题是 - 我每次在任务 class 的调用方法中使用 RestTemplate
和 setRequestFactory
的方式是否有效?由于 RestTemplate
的创建非常繁重,所以不确定我是否做对了。
并且每次都创建一个 HttpComponentsClientHttpRequestFactory
的新实例可以吗?会贵吗?
如果我们需要在其上设置读取和连接超时,那么使用 RestTemplate
的正确有效方法是什么。
这个库会这样使用 -
String response = DataClientFactory.getInstance().getSyncData(keyData, 100);
据我所知,您重复使用同一个 RestTemplate
对象,但每个 Task
都在执行这一行:restTemplate.setRequestFactory(clientHttpRequestFactory());
。这似乎可以有竞争条件,例如一个 Task
可以设置另一个 Task
会意外使用的 RequestFactory
。
否则,您似乎在正确使用 RestTemplate
。
您的超时设置多久更改一次?如果您主要使用一个或两个超时,则可以使用具有预加载超时的 RequestFactory
构造函数创建一个或两个 RestTemplate
。如果您是效率的坚持者,请创建一个 HashMap<Integer, RestTemplate>
,每次请求新的超时时缓存 RestTemplate
和特定的超时。
否则,查看 RestTemplate's constructor, and for HttpComponentsClientHttpRequestFactory's constructor 的代码,它们看起来并不特别重,因此重复调用它们可能不会成为太大的瓶颈。