我必须进行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使用follow代码。

URL_EXAMPLE="http://{domain}/Index.php?Username={user}&password={password}";

String domain = "example.com";
String user = "user";
String password = "password";

String data=this.restTemplate.getForObject(URL_EXAMPLE,String.class,domain,user,password);

其他回答

还有一个解决方法:

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

}

为了方便地操作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
);

我真是个白痴,我把查询参数和url参数搞混了。我有点希望有一个更好的方式来填充我的查询参数,而不是一个丑陋的连接字符串,但我们有。这只是一个用正确的参数构建URL的例子。如果你把它作为一个字符串传递,Spring也会为你处理编码。

在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 [])
    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