|
|
不羁的投影仪 · 阿富汗国王_百度百科· 8 月前 · |
|
|
无邪的煎饼 · 7号线地铁规划图 - 抖音· 1 年前 · |
|
|
严肃的煎饼 · 【魅力50人 明星】王宝强 本色之魅 | 南方周末· 1 年前 · |
|
|
有爱心的香槟 · LEFT JOIN, RIGHT JOIN ...· 1 年前 · |
|
|
玉树临风的眼镜 · 吴敬琏:一个经济学家和他的复杂时代· 2 年前 · |
我必须进行一个包含自定义头和查询参数的
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);
这在客户端失败,
dispatcher servlet
无法将请求解析到处理程序。调试过后,看起来请求参数没有被发送。
当我使用请求体而不使用查询参数与
POST
进行交换时,它工作得很好。
有谁有什么想法吗?
好吧,我是个笨蛋,我把查询参数和url参数搞混了。我有点希望有一种更好的方法来填充我的查询参数,而不是一个丑陋的连接字符串,但我们就是这样。这只是一个用正确的参数构建URL的例子。如果您将其作为字符串传递,Spring还将为您处理编码。
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。
我也在尝试类似的方法,而 the RoboSpice example helped me work it out
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);
要轻松操作URL /路径/参数等,您可以使用Spring类创建一个带有参数占位符的
UriComponentsBuilder
模板,然后在
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
);
我采取了不同的方法,你可能同意或不同意,但我希望从.properties文件而不是编译的Java代码进行控制
application.properties文件内部
endpoint.url = https://yourHost/resource?requestParam1= {0}&requestParam2={1}
你可以写if或switch条件来找出.properties文件中的端点URL是否有@PathVariable (包含{})或@RequestParam (yourURL?key=value)等……然后相应地调用方法...这样它是动态的,并且不需要在未来的一站式商店中更改代码……
我试图在这里给出比实际代码更多的想法,为@ ...try和@PathVariable等编写泛型方法。然后在需要时进行相应的调用
@Value("${endpoint.url}")
private String endpointURL;
// you can use variable args feature in Java
public String requestParamMethodNameHere(String value1, String value2) {
RestTemplate restTemplate = new RestTemplate();
restTemplate
.getMessageConverters()
.add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> entity = new HttpEntity<>(headers);
try {
String formatted_URL = MessageFormat.format(endpointURL, value1, value2);
ResponseEntity<String> response = restTemplate.exchange(
formatted_URL ,
HttpMethod.GET,
entity,
String.class);
return response.getBody();
} catch (Exception e) { e.printStackTrace(); }
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);
}
如果您为RestTemplate传递非参数化的参数,那么考虑到参数,您将为您传递的每个不同的URL使用一个指标。您希望使用参数化的urls:
http://my-url/action?param1={param1}¶m2={param2}
而不是
http://my-url/action?param1=XXXX¶m2=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);
在Spring Web 4.3.6中,我还看到
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
这意味着你不必创建一个丑陋的地图
所以如果你有这个url
http://my-url/action?param1={param1}¶m2={param2}
你可以这样做
restTemplate.getForObject(url, Response.class, param1, param2)
或
restTemplate.getForObject(url, Response.class, param [])
将散列映射转换为查询参数字符串:
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);
如果您的url是
http://localhost:8080/context path?msisdn={msisdn}&email={email}
然后
Map<String,Object> queryParams=new HashMap<>();
queryParams.put("msisdn",your value)
queryParams.put("email",your value)
适用于您所描述的resttemplate交换方法
我提供了一个带有路径参数示例的RestTemplate GET方法的代码片段
public ResponseEntity<String> getName(int id) {
final String url = "http://localhost:8080/springrestexample/employee/name?id={id}";
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
|
|
不羁的投影仪 · 阿富汗国王_百度百科 8 月前 |
|
|
无邪的煎饼 · 7号线地铁规划图 - 抖音 1 年前 |
|
|
严肃的煎饼 · 【魅力50人 明星】王宝强 本色之魅 | 南方周末 1 年前 |
|
|
玉树临风的眼镜 · 吴敬琏:一个经济学家和他的复杂时代 2 年前 |