已解决 [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31))

问题描述

这是我的应用日志中的完整错误消息

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR,code 31)): only regular white space (\r,\n,\t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL -CHAR,\t) is allowed between tokens

我使用邮递员向我的网络应用程序发送 POST 请求,并带有以下标头 输入是一个带有 json 的 gzip。在邮递员上,它返回 400 Bad Request

 Content-Type: application/json
 content-encoding: gzip

This is how I upload my gzip file

这是我的 POST 方法我有一个自定义的 gzip 拦截器类。

@RequestMapping(
   method = RequestMethod.POST,value = "/post"
)
public WekaPredictResp prediction(HttpServletRequest request,HttpServletResponse response,@RequestBody Customrequest gzipInputs) throws Exception {
   postMethod(gzipInputs);
}
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.httpentity;
import org.springframework.web.client.RestTemplate;

public static Customresponse postMethod(Customrequest gzipInputs) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    httpentity<Map<String,Object>> entity = new httpentity<>(gzipInputs.getInputs(),headers);

    RestTemplate gzipRestTemplate = new RestTemplateBuilder()
       .requestFactory(HttpComponentsClientHttpRequestFactory.class)
       .additionalInterceptors(new GzipInterceptor())
       .build();

    ResponseEntity<Map> responseEntity = gzipRestTemplate.postForEntity(externalUrl,entity,Map.class);

    Map<String,Object> outputs = (Map<String,Object>) responseEntity.getBody();

    Customresponse response = new Customresponse();
    response.setoutputs(outputs);

    return outputs;

}
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

public class GzipHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest,byte[] bytes,ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
        HttpHeaders httpHeaders = httpRequest.getHeaders();
        httpHeaders.add(HttpHeaders.CONTENT_ENCODING,"gzip");
        httpHeaders.add(HttpHeaders.ACCEPT_ENCODING,"gzip");
        httpHeaders.set(HttpHeaders.CONTENT_TYPE,"gzip"); // Override for compatibility
        return clientHttpRequestExecution.execute(httpRequest,compress(bytes));
    }

}

解决方法

通过包含一个过滤器来跟踪 gzip 输入并解压缩它, 可以找到示例解决方案 here