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

有人有什么想法吗?


当前回答

我也尝试过类似的东西,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);

其他回答

我也尝试过类似的东西,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);

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

如果您的url是http://localhost:8080/context path?msisdn = {msisdn}电子邮件= {email}

然后

Map<String,Object> queryParams=new HashMap<>();
queryParams.put("msisdn",your value)
queryParams.put("email",your value)

适用于您所描述的resttemplate交换方法

uriVariables也在查询字符串中展开。例如,下面的调用将展开account和name的值:

restTemplate.exchange("http://my-rest-url.org/rest/account/{account}?name={name}",
    HttpMethod.GET,
    httpEntity,
    clazz,
    "my-account",
    "my-name"
);

实际的请求url是

http://my-rest-url.org/rest/account/my-account?name=my-name

查看HierarchicalUriComponents.expandInternal(UriTemplateVariables)了解更多细节。 Spring的版本是3.1.3。

如果您为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);