我必须进行REST调用,其中包括自定义头和查询参数。我设置我的HttpEntity只有头(没有正文),我使用RestTemplate.exchange()方法如下:
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");
Map<String, String> params = new HashMap<String, String>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);
HttpEntity entity = new HttpEntity(headers);
HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);
这在客户端失败,因为调度程序servlet无法将请求解析到处理程序。调试之后,似乎没有发送请求参数。
当我使用请求体和没有查询参数的POST做一个交换时,它工作得很好。
有人有什么想法吗?
如果您为RestTemplate传递非参数参数,那么考虑到参数,您将为传递的每个不同URL都有一个Metrics。你想要使用参数化url:
http://my-url/action?param1={param1}¶m2={param2}
而不是
http://my-url/action?param1=XXXX¶m2=YYYY
第二种情况是使用UriComponentsBuilder类得到的结果。
实现第一个行为的方法如下:
Map<String, Object> params = new HashMap<>();
params.put("param1", "XXXX");
params.put("param2", "YYYY");
String url = "http://my-url/action?%s";
String parametrizedArgs = params.keySet().stream().map(k ->
String.format("%s={%s}", k, k)
).collect(Collectors.joining("&"));
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> entity = new HttpEntity<>(headers);
restTemplate.exchange(String.format(url, parametrizedArgs), HttpMethod.GET, entity, String.class, params);
我也尝试过类似的东西,RoboSpice的例子帮助我解决了这个问题:
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");
HttpEntity<String> request = new HttpEntity<>(input, createHeader());
String url = "http://awesomesite.org";
Uri.Builder uriBuilder = Uri.parse(url).buildUpon();
uriBuilder.appendQueryParameter(key, value);
uriBuilder.appendQueryParameter(key, value);
...
String url = uriBuilder.build().toString();
HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request , String.class);
将哈希映射转换为查询参数字符串:
Map<String, String> params = new HashMap<>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.queryParam(entry.getKey(), entry.getValue());
}
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");
HttpEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, new HttpEntity(headers), String.class);
为了方便地操作URL / path / params /等等,您可以使用Spring的UriComponentsBuilder类创建一个URL模板,其中包含参数占位符,然后在RestOperations.exchange(…)调用中提供这些参数的值。它比手动连接字符串更干净,它会为你处理URL编码:
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
HttpEntity<?> entity = new HttpEntity<>(headers);
String urlTemplate = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("msisdn", "{msisdn}")
.queryParam("email", "{email}")
.queryParam("clientVersion", "{clientVersion}")
.queryParam("clientType", "{clientType}")
.queryParam("issuerName", "{issuerName}")
.queryParam("applicationName", "{applicationName}")
.encode()
.toUriString();
Map<String, ?> params = new HashMap<>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);
HttpEntity<String> response = restOperations.exchange(
urlTemplate,
HttpMethod.GET,
entity,
String.class,
params
);
我采取不同的方法,你可能同意或不同意,但我想从.properties文件控制,而不是编译的Java代码
内部应用程序。属性文件
endpoint。url = https://host/resource?
Java代码在这里,你可以写if或切换条件,以找出端点URL在.properties文件中是否有@PathVariable(包含{})或@RequestParam (yourURL?key=value)等…然后调用相应的方法…这样它是动态的,不需要在未来的一站式商店更改代码…
我试图在这里给出比实际代码更多的想法……试着为@RequestParam和@PathVariable等编写泛型方法…然后在需要时进行相应的调用
@Value("${endpoint.url}")
private String endpointURL;
// you can use variable args feature in Java
public String requestParamMethodNameHere(String value1, String value2) {
RestTemplate restTemplate = new RestTemplate();
restTemplate
.getMessageConverters()
.add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> entity = new HttpEntity<>(headers);
try {
String formatted_URL = MessageFormat.format(endpointURL, value1, value2);
ResponseEntity<String> response = restTemplate.exchange(
formatted_URL ,
HttpMethod.GET,
entity,
String.class);
return response.getBody();
} catch (Exception e) { e.printStackTrace(); }