我正在开发一个项目,我需要对运行Restful Service的服务器进行HTTP URL调用,该服务将响应作为JSON字符串返回。我在这里使用RestTemplate
和HttpComponentsClientHttpRequestFactory
来执行网址。
我已使用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 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;
}
}
现在我的问题是 - 每次在Task类的调用方法中使用RestTemplate
和setRequestFactory
的方式是否有效?由于RestTemplate
非常重要,所以不确定我是否做对了。
每次都可以创建HttpComponentsClientHttpRequestFactory
的新实例吗?它会贵吗?
如果我们需要在其上设置读取和连接超时,那么使用RestTemplate
的正确有效方法是什么。
这个库将像这样使用 -
String response = DataClientFactory.getInstance().getSyncData(keyData, 100);
答案 0 :(得分:2)
据我所知,您重复使用相同的RestTemplate
对象,但每个Task
正在执行此行:restTemplate.setRequestFactory(clientHttpRequestFactory());
。这似乎可能有竞争条件,例如:一个Task
可以设置另一个RequestFactory
意外使用的Task
。
否则,您似乎正确使用RestTemplate
。
您的超时多久更改一次?如果您大多使用一次或两次超时,则可以使用带有预加载超时的RestTemplate
构造函数创建一个或两个RequestFactory
。如果您是提高效率的人,请在每次请求新的超时时创建一个HashMap<Integer, RestTemplate>
缓存RestTemplate
特定超时。
否则,查看RestTemplate's constructor和HttpComponentsClientHttpRequestFactory's constructor的代码,它们看起来并不特别重,因此重复调用它们可能不会成为瓶颈。