Java 弹簧&x27;s AsyncRestTemplate不处理压缩内容,获取压缩内容而不是json对象
我已经在我的spring boot应用程序上启用了内容压缩,每个API的响应都被压缩了,但如果我使用Java 弹簧&x27;s AsyncRestTemplate不处理压缩内容,获取压缩内容而不是json对象,java,json,spring-boot,spring-web,asyncresttemplate,Java,Json,Spring Boot,Spring Web,Asyncresttemplate,我已经在我的spring boot应用程序上启用了内容压缩,每个API的响应都被压缩了,但如果我使用RestTemplate点击这些API,我会得到如下内容 "\u001F�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000�}��8��¨OtD���1��]�m�mo��v�_LlP\u0014J�4E��(�����C�:\u0012<D\u0010����\b۲��\u0004\u0012@\" 我想建议您不要手动执行压缩,而只是告诉Sprin
RestTemplate
点击这些API,我会得到如下内容
"\u001F�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000�}��8��¨OtD���1��]�m�mo��v�_LlP\u0014J�4E��(�����C�:\u0012<D\u0010����\b۲��\u0004\u0012@\"
我想建议您不要手动执行压缩,而只是告诉Spring为您执行压缩(实际上压缩将由web服务器(例如Tomcat)完成,但Spring将为您执行)。通常在春季,像压缩这样的事情,编码可以只通过一个属性打开
请看一个简单的解决方法是添加一个带有AsyncRestTemplate的ResponseInterceptor,它可以自动解压缩响应。您收到的ListenableFuture将已经有解压缩响应。 下面是一个例子:
AsyncRestTemplate getAsyncRestTemplate() {
final HttpComponentsAsyncClientHttpRequestFactory httpComponentsAsyncClientHttpRequestFactory =
new HttpComponentsAsyncClientHttpRequestFactory();
final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(httpComponentsAsyncClientHttpRequestFactory);
asyncRestTemplate.setInterceptors(Collections.singletonList((httpRequest, bytes, asyncClientHttpRequestExecution) -> {
if (!httpRequest.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) {
httpRequest.getHeaders().set(HttpHeaders.ACCEPT_ENCODING, "gzip");
}
final ListenableFuture<ClientHttpResponse> future = asyncClientHttpRequestExecution.executeAsync(httpRequest, bytes);
return new ListenableFutureAdapter<ClientHttpResponse, ClientHttpResponse>(future) {
@Override
protected ClientHttpResponse adapt(ClientHttpResponse clientHttpResponse) throws ExecutionException {
return new InflatedClientHttpResponse(clientHttpResponse);
}
};
}));
return asyncRestTemplate;
}
public class InflatedClientHttpResponse implements ClientHttpResponse {
private final ClientHttpResponse clientHttpResponse;
private final Boolean isCompressed;
public InflatedClientHttpResponse(ClientHttpResponse clientHttpResponse) {
this.clientHttpResponse = clientHttpResponse;
final HttpHeaders httpHeaders = clientHttpResponse.getHeaders();
final List<String> contentEncoding = httpHeaders.get(HttpHeaders.CONTENT_ENCODING);
if (contentEncoding != null && contentEncoding.contains("gzip")) {
isCompressed = true;
} else {
isCompressed = false;
}
httpHeaders.remove(HttpHeaders.CONTENT_ENCODING);
httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
}
@Override
public HttpStatus getStatusCode() throws IOException {
return clientHttpResponse.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return clientHttpResponse.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return clientHttpResponse.getStatusText();
}
@Override
public void close() {
clientHttpResponse.close();
}
@Override
public InputStream getBody() throws IOException {
if (isCompressed) {
return new GZIPInputStream(clientHttpResponse.getBody());
}
return clientHttpResponse.getBody();
}
@Override
public HttpHeaders getHeaders() {
return clientHttpResponse.getHeaders();
}
}
AsyncRestTemplate getAsyncRestTemplate(){
最终HttpComponents同步客户端前传工厂HttpComponents同步客户端前传工厂=
新的HttpComponentsAsyncClientHttpRequestFactory();
最终AsyncRestTemplate AsyncRestTemplate=新的AsyncRestTemplate(httpComponentsAsyncClientHttpRequestFactory);
asyncRestTemplate.setInterceptors(集合.singletonList((httpRequest,字节,AsyncClientHttPrequesteExecution)->{
如果(!httpRequest.getHeaders().containsKey(HttpHeaders.ACCEPT_编码)){
设置(HttpHeaders.ACCEPT_编码,“gzip”);
}
final ListenableFuture=AsyncClientHttPrequesteExecution.executeAsync(httpRequest,字节);
返回新的ListenableFutureAdapter(未来){
@凌驾
受保护的ClientHttpResponse adapt(ClientHttpResponse ClientHttpResponse)引发ExecutionException{
返回新的充气clientHttpResponse(clientHttpResponse);
}
};
}));
返回asyncRestTemplate;
}
公共类InflatedClientHttpResponse实现ClientHttpResponse{
私人最终客户TTpresponse客户TTpresponse;
私有最终布尔值被压缩;
公共充气ClientHttpResponse(ClientHttpResponse ClientHttpResponse){
this.clientHttpResponse=clientHttpResponse;
final HttpHeaders HttpHeaders=clientHttpResponse.getHeaders();
最终列表contentEncoding=httpHeaders.get(httpHeaders.CONTENT\u编码);
if(contentEncoding!=null&&contentEncoding.contains(“gzip”)){
isCompressed=true;
}否则{
isCompressed=假;
}
删除(httpHeaders.CONTENT\u编码);
httpHeaders.remove(httpHeaders.CONTENT\u LENGTH);
}
@凌驾
公共HttpStatus getStatusCode()引发IOException{
返回clientHttpResponse.getStatusCode();
}
@凌驾
public int getRawStatusCode()引发IOException{
返回clientHttpResponse.getRawStatusCode();
}
@凌驾
公共字符串getStatusText()引发IOException{
返回clientHttpResponse.getStatusText();
}
@凌驾
公众假期结束(){
clientHttpResponse.close();
}
@凌驾
公共InputStream getBody()引发IOException{
如果(已压缩){
返回新的gzip输入流(clientHttpResponse.getBody());
}
返回clientHttpResponse.getBody();
}
@凌驾
公共HttpHeaders getHeaders(){
返回clientHttpResponse.getHeaders();
}
}
是的,我不是手动操作,Spring是为我操作的。我刚刚在application.properties文件server.compression.enabled=true server.compression.mime types=application/javascript、application/x-javascript、application/json、application/xml、text/html、text/xml、text/css、text/plain中编写了这些属性
AsyncRestTemplate getAsyncRestTemplate() {
final HttpComponentsAsyncClientHttpRequestFactory httpComponentsAsyncClientHttpRequestFactory =
new HttpComponentsAsyncClientHttpRequestFactory();
final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(httpComponentsAsyncClientHttpRequestFactory);
asyncRestTemplate.setInterceptors(Collections.singletonList((httpRequest, bytes, asyncClientHttpRequestExecution) -> {
if (!httpRequest.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) {
httpRequest.getHeaders().set(HttpHeaders.ACCEPT_ENCODING, "gzip");
}
final ListenableFuture<ClientHttpResponse> future = asyncClientHttpRequestExecution.executeAsync(httpRequest, bytes);
return new ListenableFutureAdapter<ClientHttpResponse, ClientHttpResponse>(future) {
@Override
protected ClientHttpResponse adapt(ClientHttpResponse clientHttpResponse) throws ExecutionException {
return new InflatedClientHttpResponse(clientHttpResponse);
}
};
}));
return asyncRestTemplate;
}
public class InflatedClientHttpResponse implements ClientHttpResponse {
private final ClientHttpResponse clientHttpResponse;
private final Boolean isCompressed;
public InflatedClientHttpResponse(ClientHttpResponse clientHttpResponse) {
this.clientHttpResponse = clientHttpResponse;
final HttpHeaders httpHeaders = clientHttpResponse.getHeaders();
final List<String> contentEncoding = httpHeaders.get(HttpHeaders.CONTENT_ENCODING);
if (contentEncoding != null && contentEncoding.contains("gzip")) {
isCompressed = true;
} else {
isCompressed = false;
}
httpHeaders.remove(HttpHeaders.CONTENT_ENCODING);
httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
}
@Override
public HttpStatus getStatusCode() throws IOException {
return clientHttpResponse.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return clientHttpResponse.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return clientHttpResponse.getStatusText();
}
@Override
public void close() {
clientHttpResponse.close();
}
@Override
public InputStream getBody() throws IOException {
if (isCompressed) {
return new GZIPInputStream(clientHttpResponse.getBody());
}
return clientHttpResponse.getBody();
}
@Override
public HttpHeaders getHeaders() {
return clientHttpResponse.getHeaders();
}
}