我正在尝试传递路径参数并在URL中查询参数但我得到一个奇怪的错误。下面是代码
String url = "http://test.com/Services/rest/{id}/Identifier"
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
.queryParam("name", "myName");
String uriBuilder = builder.build().encode().toUriString();
restTemplate.exchange(uriBuilder , HttpMethod.PUT, requestEntity,
class_p, params);
我的网址正变为http://test.com/Services/rest/%7Bid%7D/Identifier?name=myName
我该怎么做才能让它发挥作用。我期待http://test.com/Services/rest/{id}/Identifier?name=myName
以便params将id添加到url
请建议。在此先感谢
答案 0 :(得分:86)
我会使用buildAndExpand
中的UriComponentsBuilder
来传递所有类型的URI参数。
例如:
String url = "http://test.com/solarSystem/planets/{planet}/moons/{moon}";
// URI (URL) parameters
Map<String, String> uriParams = new HashMap<String, String>();
uriParams.put("planets", "Mars");
uriParams.put("moons", "Phobos");
// Query parameters
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
// Add query parameter
.queryParam("firstName", "Mark")
.queryParam("lastName", "Watney");
System.out.println(builder.buildAndExpand(uriParams).toUri());
/**
* Console output:
* http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney
*/
restTemplate.exchange(builder.buildAndExpand(uriParams).toUri() , HttpMethod.PUT,
requestEntity, class_p);
/**
* Log entry:
* org.springframework.web.client.RestTemplate Created PUT request for "http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney"
*/
答案 1 :(得分:3)
使用带有参数映射的TestRestTemplate.exchange函数的单线。
restTemplate.exchange("/someUrl?id={id}", HttpMethod.GET, reqEntity, respType, ["id": id])
像这样初始化的参数映射是 groovy 初始化程序*
答案 2 :(得分:2)
来自 Michal Foksa 的答案的一个问题是它首先添加查询参数,然后扩展路径变量。如果查询参数包含括号,例如{foobar}
,这会导致异常。
安全的方法是先扩展路径变量,然后添加查询参数:
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
URI uri = UriComponentsBuilder.fromUriString(url)
.buildAndExpand(params)
.toUri();
uri = UriComponentsBuilder
.fromUri(uri)
.queryParam("name", "myName")
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
答案 3 :(得分:2)
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
URI uri = UriComponentsBuilder.fromUriString(url)
.buildAndExpand(params)
.toUri();
uri = UriComponentsBuilder
.fromUri(uri)
.queryParam("name", "myName")
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
<块引用>
安全的方法是先展开路径变量,再添加查询参数:
对我来说,这导致了重复的编码,例如空格被解码为 %2520(空格 -> %20 -> %25)。
我通过以下方式解决了:
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(url);
uriComponentsBuilder.uriVariables(params);
Uri uri = uriComponentsBuilder.queryParam("name", "myName");
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
基本上我使用 uriComponentsBuilder.uriVariables(params);
添加路径参数。文档说:
... 与 UriComponents.expand(Map) 或 buildAndExpand(Map) 相比,当您需要提供 URI 变量而不构建 UriComponents 实例时,此方法很有用,或者可能预先扩展一些共享默认值,例如作为主机和端口。 ...
答案 4 :(得分:0)
一种简单的方法是:
String url = "http://test.com/Services/rest/{id}/Identifier"
UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();
uriComponents = uriComponents.expand(Collections.singletonMap("id", "1234"));
,然后添加查询参数。