2011-11-28 129 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(); } 
時調用相應的