首页 > 解决方案 > Spring Framework 3.2.5 - 问题解码 POST API 输出的响应主体

问题描述

我只花了 5 个小时试图解决这个问题,但我的进展为零。我已经尝试了所有我能找到的解决方案,但我被卡住了。

这是我的基本设置和我面临的问题:

基本设置

我有 2 个功能 -

1)调用GetApi(字符串网址)

2) callPostApi(String url, String requestBody)

代码或多或少相同:

调用GetApi:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json");
headers.add("Authorization", "Basic " + apiAuthorizationString);
ResponseEntity<String> entity = null;
try {

    entity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(headers), String.class);
    apiOutput = gson.fromJson(entity.getBody().toString(), ApiOutput.class);
}
....

调用PostApi:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json");
headers.add("Authorization", "Basic " + apiAuthorizationString);
HttpEntity<Object> request = new HttpEntity<Object>(request_body, headers);
ResponseEntity<String> entity = null;
try {

     entity = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
     apiOutput = gson.fromJson(entity.getBody().toString(), ApiOutput.class);
    }
.....

问题

我面临的问题是,在 callGetApi() 函数中,我收到了正确解码的正确响应,但是我在 CallPostApi() 函数中收到了不同编码的响应,我无法解码。这两个都在 PostMan 中使用相同的输入工作得很好。

我在 callPostApi() 函数调用中收到的输出:

调试器输出

在 Postman 中接收到相同输入和标题的输出:

{"SuccessData":"Ticket not saved as no changes madeINC024","ErrorData":null,"AppData":null}

在 callGetApi() 函数中,我总是收到这些标头:

{Transfer-Encoding=[chunked], Content-Type=[text/plain; charset=utf-8], Server=[Kestrel], X-Powered-By=[ASP.NET], Date=[Mon, 15 Oct 2018 13:05:27 GMT]}

在 callPostApi() 函数中,我总是收到这些标头:

 {Transfer-Encoding=[chunked], Content-Type=[text/plain; charset=utf-16], Server=[Kestrel], X-Powered-By=[ASP.NET], Date=[Mon, 15 Oct 2018 13:06:58 GMT]}

同时,callPostApi() 函数的同一个 API 端点正在 Postman 中发送正确的标头(与上面 callGetApi() 的标头相同)

我尝试过的解决方案:

我已经尝试了以下所有 PnC:

1) 分别和一起为 UTF-16 和 UTF-8 添加了 StringHttpMessageConverter:

restTemplate.getMessageConverters().add(0, new  StringHttpMessageConverter(Charset.forName("UTF-16")));

2)删除了所有其他转换器:

restTemplate.getMessageConverters().clear();

3) 在 callPostApi() 中添加了以下头文件:

headers.add("Accept-Encoding", "identity");
headers.add("Cache-Control", "no-cache");
headers.add("Accept-Charset", "utf-8");
headers.add("Accept", "application/json, charset=utf-8");
headers.set("Accept-Language", "en");

4) 使用 HttpHeaders 而不是 MultiValueMap:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Basic " + apiAuthorizationString);
headers.add("Accept-Encoding", "identity");
headers.add("Cache-Control", "no-cache");
headers.add("Accept-Charset", "utf-8");

我尝试过的东西显示了一些进展:

entity = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
//entity has the same data as the debugger screenshot I've attached above
byte[] utf8 = entity.getBody().toString().getBytes("UTF-16");
String string = new String(utf8, "UTF-8");

在运行上述代码时,字符串数组包含正确的输出,但所有字符之间都有空格:

[{,,",,S,,u,,c,,c,,e,,s,,s,,D,,a,,t,,a,,",,:,,",,T ,,i,,c,,k,,e,,t,, ,,n,,o,,t,, ,,s,,a,,v,,e,,d,, ,,a,, s,, ,,n,,o,, ,,c,,h,,a,,n,,g,,e,,s,, ,,m,,a,,d,,e,,I, ,N,,C,,0,,2,,4,”,,,,”,,E,,r,,r,,o,,r,,D,,a,,t,,a ,,",,:,,n,,u,,l,,l,,,,,",,A,,p,,p,,D,,a,,t,,a,,",, :,,无效的,,},]

字节数组包含以下数据:

[123, 0, 34, 0, 83, 0, 117, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 68, 0, 97, 0, 116, 0, 97 , 0, 34, 0, 58, 0, 34, 0, 84, 0, 105, 0, 99, 0, 107, 0, 101, 0, 116, 0, 32, 0, 110, 0, 111, 0 , 116, 0, 32, 0, 115, 0, 97, 0, 118, 0, 101, 0, 100, 0, 32, 0, 97, 0, 115, 0, 32, 0, 110, 0, 111 , 0, 32, 0, 99, 0, 104, 0, 97, 0, 110, 0, 103, 0, 101, 0, 115, 0, 32, 0, 109, 0, 97, 0, 100, 0 , 101, 0, 73, 0, 78, 0, 67, 0, 48, 0, 50, 0, 52, 0, 34, 0, 44, 0, 34, 0, 69, 0, 114, 0, 114 , 0, 111, 0, 114, 0, 68, 0, 97, 0, 116, 0, 97, 0, 34, 0, 58, 0, 110, 0, 117, 0, 108, 0, 108, 0 , 44, 0, 34, 0, 65, 0, 112, 0, 112, 0, 68, 0, 97, 0, 116, 0, 97, 0, 34, 0, 58, 0, 110, 0, 117 , 0, 108, 0, 108, 0, 125, 0]

知道如何解决这个问题吗?感谢所有帮助

标签: javaspringjava-8spring-3spring-web

解决方案


将 ResponseEntity 的类型从 String 更改为 Object 有效。代码是:

ResponseEntity<Object> entity = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);

感谢@HadiJ 为我指明了正确的方向。


推荐阅读