我必须进行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做一个交换时,它工作得很好。

有人有什么想法吗?


当前回答

    String uri = http://my-rest-url.org/rest/account/{account};

    Map<String, String> uriParam = new HashMap<>();
    uriParam.put("account", "my_account");

    UriComponents builder = UriComponentsBuilder.fromHttpUrl(uri)
                .queryParam("pageSize","2")
                        .queryParam("page","0")
                        .queryParam("name","my_name").build();

    HttpEntity<String> requestEntity = new HttpEntity<>(null, getHeaders());

    ResponseEntity<String> strResponse = restTemplate.exchange(builder.toUriString(),HttpMethod.GET, requestEntity,
                        String.class,uriParam);

    //final URL: http://my-rest-url.org/rest/account/my_account?pageSize=2&page=0&name=my_name

RestTemplate:使用UriComponents (URI变量和请求参数)构建动态URI

其他回答

在Spring Web 4.3.6中我也看到了

public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)

这意味着你不必创建一个丑陋的地图

如果你有这个url

http://my-url/action?param1={param1}&param2={param2}

你可以选择

restTemplate.getForObject(url, Response.class, param1, param2)

or

restTemplate.getForObject(url, Response.class, param [])

如果您为RestTemplate传递非参数参数,那么考虑到参数,您将为传递的每个不同URL都有一个Metrics。你想要使用参数化url:

http://my-url/action?param1={param1}&param2={param2}

而不是

http://my-url/action?param1=XXXX&param2=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);

还有一个解决方法:

private String execute(String url, Map<String, String> params) {
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(url)
    // predefined params
            .queryParam("user", "userValue")
            .queryParam("password", "passwordValue");
    params.forEach(uriBuilder::queryParam);
    HttpHeaders headers = new HttpHeaders() {{
        setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        setAccept(List.of(MediaType.APPLICATION_JSON));
    }};
    ResponseEntity<String> request = restTemplate.exchange(uriBuilder.toUriString(), 
                HttpMethod.GET, new HttpEntity<>(headers), String.class);
    return request.getBody();

}
public static void main(String[] args) {
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.set("Accept", MediaType.APPLICATION_JSON_VALUE);
         final String url = "https://host:port/contract/{code}";
         Map<String, String> params = new HashMap<String, String>();
         params.put("code", "123456");
         HttpEntity<?> httpEntity  = new HttpEntity<>(httpHeaders); 
         RestTemplate restTemplate  = new RestTemplate();
         restTemplate.exchange(url, HttpMethod.GET, httpEntity,String.class, params);
    }

将哈希映射转换为查询参数字符串:

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);