2017-06-15 50 views
0

下面是我的REST API代碼:通過resttemplate.exchange傳遞PARAM在服務端沒有解碼自動

@RequestMapping(value = "/get", method = RequestMethod.POST, produces = { "application/json" }) 
     @ApiOperation(value = "get data by key.", notes = "return json string value.") 
     public JsonObjectResponse<String> get(
      @ApiParam(required = true, name = "regionName", value = "region name") @RequestParam("regionName") String regionName, 
      @ApiParam(required = true, name = "key", value = "region key,Default is uuid") @RequestParam("key") String key) throws UnsupportedEncodingException 
     { 
     JsonObjectResponse<String> jr = new JsonObjectResponse<String>(); 
     //key = decodeJsonString(key); // added for junit 
     String val = adfService.onPath(regionName).get(key); 
     jr.setState(StateCode.SUCCESS); 
     jr.setData(JsonObject.create().append(key,val).toJson()); 

     return jr; 
     } 

我試圖傳遞參數:regionName = /融合/表1 &鍵= { 「fusionTbl1DetailNo」: 「fusionNo001」, 「PK」: 「PK0001」}

  1. 如果我通過招搖-UI上調用它,它叫這樣的:http://localhost:8080/service/basic/get?regionName=%2Ffusion%2Ftable1&key=%7B%22fusionTbl1DetailNo%22%3A%22fusionNo001%22%2C%22pk%22%3A%22PK0001%22%7D&token=8652493a-4147-43f4-af3a-bcb117fb7d42 用電子郵件對參數進行編碼,這些參數也可以在服務器端正確自動解碼;

  2. 當我要添加測試用例這個API,我用restTemplate.exchange方法,如下面的代碼:

    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); 
    for (Entry<String, String> entry : queryParamMap.entrySet()) { 
        builder.queryParam(entry.getKey(), entry.getValue()); 
    } 
    if (uriParamMap != null) { 
    
        url = builder.buildAndExpand(uriParamMap).toUriString(); 
    } else { 
        url = builder.toUriString(); 
    } 
    if (StringUtils.isEmpty(requestBody)) { 
        if (bodyParamMap != null) { 
         requestBody = parseMapToParams(bodyParamMap); 
        } else { 
         requestBody = ""; 
        } 
    } 
    HttpHeaders headers = new HttpHeaders(); 
    MediaType mediaType = new MediaType("application", "json", Charset.forName("UTF-8")); 
    headers.setContentType(MediaType.APPLICATION_JSON_UTF8); 
    // headers.add(HttpHeaders.CONTENT_TYPE, "application/json"); 
    // headers.add("Accept", "application/json"); 
    // headers.set(HttpHeaders.ACCEPT, "application/json"); 
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); 
    // headers.add("Accept-Encoding", "gzip, deflate, br"); 
    headers.set("Accept-Charset", "utf-8"); 
    headers.set("Accept-Encoding", "gzip"); 
    headers.add("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6"); 
    headers.add("User-Agent", 
         "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); 
    
    headers.add(TestBase.TOKEN_HEADER, TestBase.getTokenId()); 
    HttpEntity<String> request = new HttpEntity<>(body, headers); 
    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); 
    ResponseEntity<String> response = restTemplate.exchange(url, httpMethod, request, String.class); 
    localresponse.set(response); 
    System.out.println("response:" + response); 
    return response; 
    

我用UriComponentsBuilder追加的參數,它會格式化的URL http://localhost:8080/service/basic/get?regionName=/fusion/table1&key=%7B%22fusionTbl1DetailNo%22:%22fusionNo001%22,%22pk%22:%22PK0001%22%7D方法exchange。但是,當服務器端收到呼叫時,它沒有解碼參數key,其值仍然是%7B%22fusionTbl1DetailNo%22:%22fusionNo001%22,%22pk%22:%22PK0001%22%7D。這就是爲什麼?我相比,從招搖調用標題設置,增加了額外的設置,沒有效果:(

回答

0

嘗試像下面這樣:

ResponseEntity<String> res = restTemplate.exchange("http://localhost:8080/service/basic/get?regionName={arg1}&key={arg2}", HttpMethod.POST, null, String.class,"/fusion/table1", "{\"fusionTbl1DetailNo\":\"fusionNo001\",\"pk\":\"PK0001\"}"); 

arg1arg2

"/fusion/table1""{\"fusionTbl1DetailNo\":\"fusionNo001\",\"pk\":\"PK0001\"}"

被替換

我發送nullrequestEntity因爲沒有請求正文和請求參數在uriVariables中。

+0

非常感謝,你救了我。 – Shihong

0

上RestTemplate Spring文檔讀取:

對於每個HTTP方法有三種變體:二接受URI 模板字符串和URI的變量(陣列或地圖),而第三接受 一個URI。請注意,對於URI模板,假定編碼是必要的,例如 。 restTemplate.getForObject(「http://example.com/hotel list」)變成「http://example.com/hotel%20list」。這也意味着,如果 URI模板或URI變量已經被編碼,將會出現雙編碼 ,

看起來你正在使用需要一個URI模板字符串RestTemplate交換法,因此,你不應該編碼URL字符串。

的URL字符串首先編碼上

builder.toUriString() 

,然後再打開交換呼叫。所以,問題似乎是在客戶端雙編碼,而不是在服務器端

0

代替toUriString()使用缺乏解碼,UriComponentsBuilder.fromUriString(url).queryParam("name","John Doe").build().toString();

相關問題