RestTemplate:如何一起发送URL和查询参数
RestTemplate: How to send URL and query parameters together
我试图在 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);
我的 url 正在变成 http://test.com/Services/rest/%7Bid%7D/Identifier?name=myName
我应该怎么做才能让它发挥作用。我期待 http://test.com/Services/rest/{id}/Identifier?name=myName
以便参数将 id 添加到 url
请多多指教。提前致谢
我会使用 UriComponentsBuilder
中的 buildAndExpand
来传递所有类型的 URI 参数。
例如:
String url = "http://test.com/solarSystem/planets/{planet}/moons/{moon}";
// URI (URL) parameters
Map<String, String> urlParams = new HashMap<>();
urlParams.put("planet", "Mars");
urlParams.put("moon", "Phobos");
// Query parameters
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
// Add query parameter
.queryParam("firstName", "Mark")
.queryParam("lastName", "Watney");
System.out.println(builder.buildAndExpand(urlParams).toUri());
/**
* Console output:
* http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney
*/
restTemplate.exchange(builder.buildAndExpand(urlParams).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"
*/
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);
使用带参数映射的 TestRestTemplate.exchange 函数的单行代码。
restTemplate.exchange("/someUrl?id={id}", HttpMethod.GET, reqEntity, respType, ["id": id])
像这样初始化的params映射是一个groovy初始化器*
一个简单的方法是:
String url = "http://test.com/Services/rest/{id}/Identifier"
UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();
uriComponents = uriComponents.expand(Collections.singletonMap("id", "1234"));
然后添加查询参数。
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);
The safe way is to expand the path variables first, and then add the query parameters:
对我来说,这导致了重复编码,例如space 被解码为 %2520(space -> %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);
来添加路径参数。文档说:
... In contrast to UriComponents.expand(Map) or buildAndExpand(Map), this method is useful when you need to supply URI variables without building the UriComponents instance just yet, or perhaps pre-expand some shared default values such as host and port. ...
下面是工作代码,我在制作查询参数时必须在各自的占位符中传递两个值。
String queryParam = "Key=Project_{ProdjectCode}_IN_{AccountCode}"
Map<String, String> queryParamMap = new HashMap<>();
queryParamMap.put("ProjectCode","Project1");
queryParamMap.put("AccountCode","Account1");
UriComponents builder = UriComponentsBuilder.fromHttpUrl("http://myservice.com/accountsDetails").query(queryParam).buildAndExpand(queryParamMap);
restTemplate.exchange(builder.toUriString(), HttpMethod.GET,httpEntity,MyResponse.class);
以上代码将对 url 进行 GET 调用
http://myservice.com/accountsDetails?Key=Project_Project1_IN_Account1
从 5.3 版开始,您可以使用此 API 来执行此操作。
RequestEntity.post(urlString, urlParam1, urlParam2).headers(...).body(requestBody);
public static RequestEntity.BodyBuilder post(String uriTemplate,
Object... uriVariables)
Create an HTTP POST builder with the given string base uri template.
或者
template.exchange(..., uriVariables)
我试图在 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);
我的 url 正在变成 http://test.com/Services/rest/%7Bid%7D/Identifier?name=myName
我应该怎么做才能让它发挥作用。我期待 http://test.com/Services/rest/{id}/Identifier?name=myName
以便参数将 id 添加到 url
请多多指教。提前致谢
我会使用 UriComponentsBuilder
中的 buildAndExpand
来传递所有类型的 URI 参数。
例如:
String url = "http://test.com/solarSystem/planets/{planet}/moons/{moon}";
// URI (URL) parameters
Map<String, String> urlParams = new HashMap<>();
urlParams.put("planet", "Mars");
urlParams.put("moon", "Phobos");
// Query parameters
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
// Add query parameter
.queryParam("firstName", "Mark")
.queryParam("lastName", "Watney");
System.out.println(builder.buildAndExpand(urlParams).toUri());
/**
* Console output:
* http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney
*/
restTemplate.exchange(builder.buildAndExpand(urlParams).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"
*/
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);
使用带参数映射的 TestRestTemplate.exchange 函数的单行代码。
restTemplate.exchange("/someUrl?id={id}", HttpMethod.GET, reqEntity, respType, ["id": id])
像这样初始化的params映射是一个groovy初始化器*
一个简单的方法是:
String url = "http://test.com/Services/rest/{id}/Identifier"
UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();
uriComponents = uriComponents.expand(Collections.singletonMap("id", "1234"));
然后添加查询参数。
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);
The safe way is to expand the path variables first, and then add the query parameters:
对我来说,这导致了重复编码,例如space 被解码为 %2520(space -> %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);
来添加路径参数。文档说:
... In contrast to UriComponents.expand(Map) or buildAndExpand(Map), this method is useful when you need to supply URI variables without building the UriComponents instance just yet, or perhaps pre-expand some shared default values such as host and port. ...
下面是工作代码,我在制作查询参数时必须在各自的占位符中传递两个值。
String queryParam = "Key=Project_{ProdjectCode}_IN_{AccountCode}"
Map<String, String> queryParamMap = new HashMap<>();
queryParamMap.put("ProjectCode","Project1");
queryParamMap.put("AccountCode","Account1");
UriComponents builder = UriComponentsBuilder.fromHttpUrl("http://myservice.com/accountsDetails").query(queryParam).buildAndExpand(queryParamMap);
restTemplate.exchange(builder.toUriString(), HttpMethod.GET,httpEntity,MyResponse.class);
以上代码将对 url 进行 GET 调用 http://myservice.com/accountsDetails?Key=Project_Project1_IN_Account1
从 5.3 版开始,您可以使用此 API 来执行此操作。
RequestEntity.post(urlString, urlParam1, urlParam2).headers(...).body(requestBody);
public static RequestEntity.BodyBuilder post(String uriTemplate, Object... uriVariables)
Create an HTTP POST builder with the given string base uri template.
或者
template.exchange(..., uriVariables)