据我所知,RestTemplateBuilder
是RestTemplate
的某种工厂。我有一些关于使用它的问题:
在@Configuration
类:
@Bean
public RestTemplate getRestClient() {
RestTemplate restClient = new RestTemplate();
...
return restClient;
}
不应该RestTemplate
每个@Service
类实例化RestTemplateBuilder
吗?如果是这样,如何定制它?
Spring引用说RestTemplateCustomizer
应该通过BasicAuthentication
进行自定义。如何使用一个构建器从多个IP地址管理多个URI?
如何通过RestTemplates
向所有RestTemplateBuilder
添加RestTemplates
全球,这是一个好习惯吗?
感谢您的帮助。
更新:
我的应用程序调用来自不同IP和网址的许多服务器的休息服务 - 所以对我来说逻辑上就是我有很多RestTemplateBuilder
的情况。
我试图为每台服务器建立一个工厂(RestTemplateBuilder
) - 让我们说服务器A,B,C。我知道如何添加基本身份验证。但是,例如,当我想要服务器A的基本身份验证而不是服务器B的基本身份验证时呢?
我认为每台服务器有一个{
"_id": {
"$oid": "5654a8f0d487dd1434571a6e"
},
"ValidationDate": {
"$date": "2015-11-24T13:06:19.363Z"
},
"DataRaw": " WL 00100100012015-08-28 02:44:17+0000+ 16.81 8.879 1084.00",
"ReadingsAreValid": true,
"locationID": " WL 001",
"Readings": {
"pH": {
"value": 8.879
},
"SensoreDate": {
"value": {
"$date": "2015-08-28T02:44:17.000Z"
}
},
"temperature": {
"value": 16.81
},
"Conductivity": {
"value": 1084
}
},
"HMAC":"ecb98d73fcb34ce2c5bbcc9c1265c8ca939f639d791a1de0f6275e2d0d71a801"
}
。我不想手动执行此操作 - 我更愿意使用Spring机制。
任何帮助?
答案 0 :(得分:6)
不,您不需要,通常您将拥有休息模板实例,并且您将传递不同的网址,并且每次都会相应地请求参数。
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class, vars);
Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class);
来自spring doc的描述性示例,您可以向构建器添加任意数量的自定义程序
public class ProxyCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
HttpHost proxy = new HttpHost("proxy.example.com");
HttpClient httpClient = HttpClientBuilder.create()
.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
@Override
public HttpHost determineProxy(HttpHost target,
HttpRequest request, HttpContext context)
throws HttpException {
if (target.getHostName().equals("192.168.0.5")) {
return null;
}
return super.determineProxy(target, request, context);
}
}).build();
restTemplate.setRequestFactory(
new HttpComponentsClientHttpRequestFactory(httpClient));
}
}
任何RestTemplateCustomizer bean都会自动添加到 自动配置的RestTemplateBuilder。此外,一个新的 可以创建具有其他自定义程序的RestTemplateBuilder 调用additionalCustomizers(RestTemplateCustomizer ...)
@Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder()
.rootUri(rootUri)
.basicAuthorization(username, password);
}
答案 1 :(得分:2)
我已经设置了这样的配置:
@Bean
public RestTemplateCustomizer restTemplateCustomizer() {
return restTemplate -> {
restTemplate.setRequestFactory(clientHttpRequestFactory());
};
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(connectionTimeoutMs);
clientHttpRequestFactory.setReadTimeout(connectionTimeoutMs);
clientHttpRequestFactory.setBufferRequestBody(false);
return clientHttpRequestFactory;
}
每当Spring注入RestTemplateBuilder时,它将使用此RestTemplateCustomizer配置它以使用ClientHttpRequestFactory。您可能需要进行一些不同的自定义,或者在这种情况下不需要声明bean。
要添加身份验证标头,您需要知道用户名和密码,在运行时可能无法知道。所以我创建了一个Authenticator bean:
@Component
public class Authenticator {
@Autowired
private RestTemplateBuilder restTemplateBuilder;
public void withAuthenticationHeader(String username, String password, Consumer<RestTemplate> doAuthenticated) {
RestTemplate restTemplate =
restTemplateBuilder
.basicAuthorization(username, password)
.build();
try {
doAuthenticated.accept(restTemplate);
} catch (HttpClientErrorException exception) {
// handle the exception
}
}
}
这使我能够以标准方式处理所有请求的身份验证失败,这正是我在我的应用程序中所需要的。
它被注入其他bean并像这样使用:
@Autowired
private Authenticator authenticator;
public void transmit() {
authenticator.withAuthenticationHeader(username, password, restTemplate ->
restTemplate.postForLocation(url, request));
}
所以你要使用Authenticator而不是直接使用RestTemple。 我找不到任何这种标准的模式,但这似乎有效。