2011-11-28 181 views
123

我必须进行包含自定义标题和查询参数的REST调用。我把我的HttpEntity只用头(无正文)我用的是RestTemplate.exchange()方法如下:Spring RestTemplate GET参数

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暂时无法在客户端解析请求到处理程序。 Havinf调试它,它看起来像请求参数没有被发送。

当我使用请求体某条信息的交流,并没有查询参数它工作得很好。

有没有人有任何想法?

回答

30

OK,所以我是一个傻瓜,我使用的网址参数混乱的查询参数。我有点希望有一个更好的方式来填充我的查询参数,而不是一个丑陋的连接字符串,但我们在那里。这只是使用正确的参数构建URL的一种情况。如果你将它作为字符串传递,Spring也会为你编码。

+0

是否适合你?我遵循使用UriComponentsBuilder的相同方法,但在目标URL处,当我执行request.getAttribute()时,我得到null。 – yathirigan

+0

见上:https://stackoverflow.com/a/16676827 – Marc

77

的uriVariables也扩大了查询字符串。例如,下面的调用将扩大这两个值,帐户和名称:

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。

+7

哇这从文档中并不明显。 – Deadron

+0

谢谢 - 非常简单的解决方案 –

15

我试图类似的东西,和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); 
231

轻松地操纵网址/路径/ PARAMS /等,你可以使用Spring的UriComponentsBuilder类。它的清洁器手动连接字符串,它负责将URL编码的你:

HttpHeaders headers = new HttpHeaders(); 
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE); 

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url) 
     .queryParam("msisdn", msisdn) 
     .queryParam("email", email) 
     .queryParam("clientVersion", clientVersion) 
     .queryParam("clientType", clientType) 
     .queryParam("issuerName", issuerName) 
     .queryParam("applicationName", applicationName); 

HttpEntity<?> entity = new HttpEntity<>(headers); 

HttpEntity<String> response = restTemplate.exchange(
     builder.build().encode().toUri(), 
     HttpMethod.GET, 
     entity, 
     String.class); 
+4

伟大的提示。只是把'''exchange'''改成'''getForEntity''':'''restTemplate.getForEntity(builder.build()。encode()。toUri(),String.class);'''为了简单起见。 –

+6

@ FernandoM.Pinheiro:你是对的,但如果你期望在响应中使用泛型类型,那么你需要使用'exchange'并提供'ParameterizedTypeReference'。 这个例子可以进一步简化,用'builder.toUriString()'替换'builder.build()。encode()。toUri()'。 – mirzmaster

+0

@Christophe L你能告诉我怎样才能在服务器端接收这些字符串参数? – KJEjava48

2

我采取不同的方法,你可以同意或没有,但我想控制从的.properties文件的编译后的Java代码,而不是

里面application.properties文件

endpoint.url = https://yourHost/resource?requestParam1= {0} & requestParam2 = {1}

Java代码在这里,你可以,如果或切换条件,如果endpo找出写.properties文件中的int URL包含@PathVariable(包含{})或@RequestParam(yourURL?key = value)等等......然后调用相应的方法......这样它的动态性,而不需要在将来的一站式服务中更改代码...

我想给更多的想法比实际的代码在这里...尝试编写普通的方法对每个@RequestParam和@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(); } 
时调用相应的