为什么 Jersey 客户端响应提供垃圾数据?
Why is Jersey Client response giving garbage data?
我不明白为什么我的代码在读取 Http Response 实体时会给我垃圾数据。只有当我向一个特定的 URL 发出请求并导致 400 响应的数据时,才会发生这种情况。我的代码尝试读取响应实体,但如下所示,它是垃圾。
这是一个简化的测试用例:
import org.junit.Test;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
public class Sandbox {
@Test
public void jaguarTestCase() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://www.jaguarusa.com/owners/vin-recall.html?view=vinRecallQuery&vin=xxxxxxxxxxxxxxxxx");
Invocation.Builder builder = target.request();
Response response = builder.get(Response.class);
System.out.println("Response Code:");
System.out.println("\t" + response.getStatus() + " - " + response.getStatusInfo().getReasonPhrase());
System.out.println("\nResponse Headers:");
for (Map.Entry<String, List<String>> entry : response.getStringHeaders().entrySet()) {
System.out.print("\t" + entry.getKey() + ": ");
for (String value : entry.getValue()) {
System.out.println(value);
}
}
String responseEntity = response.readEntity(String.class);
System.out.println("\nResponse Entity: ");
System.out.println(responseEntity);
}
}
以及该测试用例的输出:
Response Code:
400 - Bad Request
Response Headers:
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, no-store, must-revalidate
Server: Apache-Coyote/1.1
Connection: keep-alive
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Length: 135
Date: Tue, 08 Nov 2016 00:03:23 GMT
Content-Language: en-US
Content-Type: application/json;charset=UTF-8
Response Entity:
� \�1
�@E��:H
���B��C2����X�wנ��z�{%1�vw��:ga�����4$ ������k�Q�-i�����y��T��!f��� c� ��iK-��?z� ���dW��
这就是实体 body 应该是的样子(将 URL 粘贴到任何浏览器中并亲自查看):
{
"errorMessage" : "Please check your details and try again.",
"error" : 400,
"errorTitle" : "Sorry, that is not a valid VIN.",
"vin" : "XXXXXXXXXXXXXXXXX"
}
我正在使用 JDK 版本 1.8.0_102。我认为问题是在解析响应实体时发生的,因为报告的 content-length 135 是正确的值,运行 此请求在 Chrome 浏览器调试 window 中确认.
Content-Type 响应 header 显示 charset=UTF-8,这就是我的 JVM 运行。是什么赋予了?弄了一个下午,我完全被难住了。
如果您检查您的回复 headers,您会发现
Content-Encoding: gzip
乱码其实是压缩过的
您可以解压缩该响应。
WebTarget target = ...
target.register(GZipEncoder.class);
此更改后,您正在做的 readEntity
应该可以正常工作。
这适用于 Jersey 2.26。
对于早期版本,解决方案略有不同。参考
我不明白为什么我的代码在读取 Http Response 实体时会给我垃圾数据。只有当我向一个特定的 URL 发出请求并导致 400 响应的数据时,才会发生这种情况。我的代码尝试读取响应实体,但如下所示,它是垃圾。
这是一个简化的测试用例:
import org.junit.Test;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
public class Sandbox {
@Test
public void jaguarTestCase() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://www.jaguarusa.com/owners/vin-recall.html?view=vinRecallQuery&vin=xxxxxxxxxxxxxxxxx");
Invocation.Builder builder = target.request();
Response response = builder.get(Response.class);
System.out.println("Response Code:");
System.out.println("\t" + response.getStatus() + " - " + response.getStatusInfo().getReasonPhrase());
System.out.println("\nResponse Headers:");
for (Map.Entry<String, List<String>> entry : response.getStringHeaders().entrySet()) {
System.out.print("\t" + entry.getKey() + ": ");
for (String value : entry.getValue()) {
System.out.println(value);
}
}
String responseEntity = response.readEntity(String.class);
System.out.println("\nResponse Entity: ");
System.out.println(responseEntity);
}
}
以及该测试用例的输出:
Response Code:
400 - Bad Request
Response Headers:
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, no-store, must-revalidate
Server: Apache-Coyote/1.1
Connection: keep-alive
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Length: 135
Date: Tue, 08 Nov 2016 00:03:23 GMT
Content-Language: en-US
Content-Type: application/json;charset=UTF-8
Response Entity:
� \�1
�@E��:H
���B��C2����X�wנ��z�{%1�vw��:ga�����4$ ������k�Q�-i�����y��T��!f��� c� ��iK-��?z� ���dW��
这就是实体 body 应该是的样子(将 URL 粘贴到任何浏览器中并亲自查看):
{
"errorMessage" : "Please check your details and try again.",
"error" : 400,
"errorTitle" : "Sorry, that is not a valid VIN.",
"vin" : "XXXXXXXXXXXXXXXXX"
}
我正在使用 JDK 版本 1.8.0_102。我认为问题是在解析响应实体时发生的,因为报告的 content-length 135 是正确的值,运行 此请求在 Chrome 浏览器调试 window 中确认.
Content-Type 响应 header 显示 charset=UTF-8,这就是我的 JVM 运行。是什么赋予了?弄了一个下午,我完全被难住了。
如果您检查您的回复 headers,您会发现
Content-Encoding: gzip
乱码其实是压缩过的
您可以解压缩该响应。
WebTarget target = ...
target.register(GZipEncoder.class);
此更改后,您正在做的 readEntity
应该可以正常工作。
这适用于 Jersey 2.26。
对于早期版本,解决方案略有不同。参考