- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个客户正在使用的库,他们正在传递 DataRequest
对象,该对象具有 userid
、timeout
和其他一些字段它。现在我使用这个 DataRequest
对象来创建一个 URL,然后我使用 RestTemplate
进行 HTTP 调用,我的服务返回一个 JSON 响应,我用它来创建一个 DataResponse
对象并将这个 DataResponse
对象返回给他们。
下面是客户通过将 DataRequest
对象传递给我的 DataClient
类。如果在 getSyncData
方法中花费太多时间,我将使用客户在 DataRequest
中传递的超时值来超时请求。
public class DataClient implements Client {
private final RestTemplate restTemplate = new RestTemplate();
private final ExecutorService service = Executors.newFixedThreadPool(10);
// this constructor will be called only once through my factory
// so initializing here
public DataClient() {
try {
restTemplate.setRequestFactory(clientHttpRequestFactory());
} catch (Exception ex) {
// log exception
}
}
@Override
public DataResponse getSyncData(DataRequest key) {
DataResponse response = null;
Future<DataResponse> responseFuture = null;
try {
responseFuture = getAsyncData(key);
response = responseFuture.get(key.getTimeout(), key.getTimeoutUnit());
} catch (TimeoutException ex) {
response = new DataResponse(DataErrorEnum.CLIENT_TIMEOUT, DataStatusEnum.ERROR);
responseFuture.cancel(true);
// logging exception here
}
return response;
}
@Override
public Future<DataResponse> getAsyncData(DataRequest key) {
DataFetcherTask task = new DataFetcherTask(key, restTemplate);
Future<DataResponse> future = service.submit(task);
return future;
}
// how to set socket timeout value by using `key.getSocketTimeout()` instead of using hard coded 400
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
RequestConfig requestConfig =
RequestConfig.custom().setConnectionRequestTimeout(400).setConnectTimeout(400)
.setSocketTimeout(400).setStaleConnectionCheckEnabled(false).build();
SocketConfig socketConfig =
SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setMaxTotal(300);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(200);
CloseableHttpClient httpClientBuilder =
HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig).setDefaultSocketConfig(socketConfig).build();
requestFactory.setHttpClient(httpClientBuilder);
return requestFactory;
}
}
DataFetcherTask
类:
public class DataFetcherTask implements Callable<DataResponse> {
private final DataRequest key;
private final RestTemplate restTemplate;
public DataFetcherTask(DataRequest key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() throws Exception {
// In a nutshell below is what I am doing here.
// 1. Make an url using DataRequest key.
// 2. And then execute the url RestTemplate.
// 3. Make a DataResponse object and return it.
}
}
我们公司的客户将通过在他们的代码库中使用我的工厂来使用我的库,如下所示 -
// if they are calling `getSyncData()` method
DataResponse response = DataClientFactory.getInstance().getSyncData(key);
// and if they want to call `getAsyncData()` method
Future<DataResponse> response = DataClientFactory.getInstance().getAsyncData(key);
我将 sync 调用实现为异步 + 等待
,因为我想用线程数限制它们,否则它们可以在没有任何控制的情况下轰炸我们的服务。
问题陈述:-
我将在我的 DataRequest
类中添加另一个名为 socket timeout
的超时变量,并且我想使用该变量值 (key.getSocketTimeout())
在我的 clientHttpRequestFactory()
方法中,而不是使用硬编码的 400 值。最好和最有效的方法是什么?
现在我正在使用 Inversion of Control
并在构造函数中传递 RestTemplate
以在我的所有 Task 对象之间共享 RestTemplate
。我现在很困惑如何在我的 clientHttpRequestFactory()
方法中使用 key.getSocketTimeout()
值。我认为这主要是如何在这里有效地使用 RestTemplate
的设计问题,以便我可以在 clientHttpRequestFactory()
中使用 key.getSocketTimeout()
值> 方法。
我已经简化了代码,以便清楚我想要做什么并且我在 Java 7 上。使用 ThreadLocal
是我在这里唯一的选择,或者有任何更好和优化的方法?
最佳答案
作为 Peter explains ,在这里使用 ThreadLocal 不是一个好主意。但我也找不到“将值传递到方法调用链”的方法。
如果你使用普通的“Apache HttpClient”,你可以创建一个 HttpGet/Put/etc。并简单地调用httpRequest.setConfig(myRequestConfig)
。换句话说:为每个请求设置一个请求配置(如果请求中没有设置任何内容,则使用执行请求的 HttpClient
中的请求配置)。
相比之下,RestTemplate
调用 createRequest(URI, HttpMethod)
(定义在 HttpAccessor
中)它使用 ClientHttpRequestFactory
。换句话说:没有为每个请求设置请求配置的选项。
我不确定为什么 Spring 忽略了这个选项,这似乎是一个合理的功能要求(或者我可能仍然缺少一些东西)。
关于“他们可以在没有任何控制的情况下轰炸我们的服务”的一些说明:
PoolingHttpClientConnectionManager
的原因之一:通过设置适当的最大值,同时使用的连接数永远不会超过指定的最大连接数(因此请求正在运行)。这里的假设是您为每个请求重复使用相同的 RestTemplate
实例(以及连接管理器)。workQueue
和 handler
)。关于java - 如何使用 RestTemplate 为每个请求设置 RequestConfiguration?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37125694/
我编写了以下代码来测试同步 RestTemplate 和 AsyncRestTemplate 的性能。我只是在 POSTMAN 上手动运行了几次。 我们只是将 10 个引用传递给 GET 调用,以便我
这种方式创建RestTemplate有什么区别 RestTemplate restTemplate = restTemplateBuilder .setConnectT
这个问题已经有答案了: IllegalArgumentException: Not enough variable values available with RestTemplate? (2 个回答
这是我的应用程序的主类 @SpringBootApplication (scanBasePackages = { "com.xyz.*" }) @EnableAsync @EnableAspectJA
我当前的代码: RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new
我将开发一个简单的 Spring MVC Web 应用程序,它将使用 Heroku 上的远程 RESTful 服务。 我希望 MVC Web 应用程序根据 Controller 调用 REST 服务。
项目场景: Spring 的 RestTemplate 是一个健壮的、流行的基于 Java 的 Http客户端。 RestTemplate实现request param参数传送,如果如下所示,直接传一
我想通过 RestTemplate 发送请求。但是我的网址有大括号('{','}'),因此我有异常(exception):“没有足够的变量值可用于扩展......”。 我尝试通过 uri UriCom
有一个 RestFull 方法返回一个菜单对象列表 public ResponseEntity> getMenus() { .. } 但我不知道如何从 RestTemplate 中获取它们,从 Res
摘要: RestTemplate与REST资源交互的方法涵盖了HTTP请求方法,包括get, post, put, delete。 本文分享自华为云社区《Springboot RestTemplate
我有一个 springboot 休息服务 A 使用 restTemplate 调用休息服务 B。休息服务 A 的 restTemplate bean 创建如下,超时设置如下面的代码片段所示。 @Bea
我有一个 @Service有几种方法,每种方法使用不同的 web api。每个调用都应该有一个自定义的读取超时。 拥有一个 RestTemplate 实例并在每个方法中通过工厂更改超时是否是线程安全的
这是我的休息模板配置, @Bean @Qualifier("myRestService") public RestTemplate createRestTemplate(@Va
是否可以使用 RestTemplateBuilder 创建仅带有不记名 header 和 token 的 RestTemplate 实例? 我知道我可以使用 RestTemplate 交换并在 Htt
我正在尝试对请求正文执行 DELETE,但我不断收到 400(错误请求)错误。当我在 swagger/postman 中这样做时,它成功地删除了记录。但是从 Java 代码我不能这样做 外部 API
我需要创建 RestTemplate 请求,它将发送图像以通过 PHP 应用程序上传。 我的代码是: Resource resource = new FileSystemResource("/User
我正在使用 swagger codegen ( on this Zoura swagger ) 创建 Java/rest 模板客户端。我正在使用 swagger Gradle 插件: id "org.
我有Restful API,当找不到某个项目时会响应404错误,但是根据未找到该项目的原因(未知,不可用等),会有不同的消息,可以使用Spring MVC通过以下方式完成: response.send
我正在使用 Spring 中的 RestTemplate 来查询搜索服务。我在进行正确的序列化方面遇到了一些困难。如果我使用此方法,restTemplate 将返回一个列表。我不明白如何传递参数化类型
我们有这样的代码,它使用 OData 来指定资源(为简单起见,在此处使用公司代码进行硬编码): String uri = "[my_endpoint]/companyprofiles.read?$fi
我是一名优秀的程序员,十分优秀!