首页 > 解决方案 > 内容长度分隔的消息正文过早结束(不重复)

问题描述

(不是Content-Length 分隔消息正文的过早结束(预期:)
设置了 3 个相互通信的应用程序,每个应用程序都位于以下格式的 apache http 服务器后面
App A(Monolithic Spring 应用程序)
App B(Spring boot微服务 - 充当中间人)
App C(Spring Boot 微服务 - 提供一些数据)

App AGET向 App B 发出请求,App B 读取GET请求并向 App C 调用请求,App C 获取数据并将 a 发送ResponseEntity给 App B,然后最后,App B 将其发送ResponseEntity给 App A,如下面的代码所示。

//Service A making a request to Service B.
public static Response executeGetMethod(CustomRestTemplate restTemplate, String microServiceURL) {
    Response returnedResponse = null;
    ResponseEntity<?> msResponse = null;
    try {
        // special handling for octet-stream
        if (restTemplate.getAccepts().stream().anyMatch(accept -> MediaType.APPLICATION_OCTET_STREAM_TYPE.equals(accept))) {
            msResponse = restTemplate.getRestTemplate().getForEntity(microServiceURL, byte[].class);
        } else {
            msResponse = restTemplate.getRestTemplate().getForEntity(microServiceURL, Object.class);
        }

        returnedResponse = Response.status(msResponse.getStatusCode().value()).entity(msResponse.getBody()).build();
        //Just reading the headers from msResponse and adding it to returnedResponse.
        addHeaderToReturnedResponse(returnedResponse.getHeaders(), msResponse.getHeaders());

    } catch (HttpClientErrorException ex) {
        returnedResponse = Response.serverError().status(ex.getStatusCode().value()).entity(ex.getResponseBodyAsString()).build();
    } catch (HttpServerErrorException ex) {
        returnedResponse = Response.serverError().status(ex.getStatusCode().value()).entity(ex.getResponseBodyAsString()).build();
    }
    return returnedResponse;
}
    

// Service B making request to Service C
@GetMapping(value = "/templates", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> getReportTemplate() throws Exception {
    validateUser();

    // route to reporting-microservices
    Map<String, String> headers = new HashMap<>();
    headers.put(RestServiceConstants.CONTENT_TYPE, RestServiceConstants.APPLICATION_JSON);
    ResponseEntity<?> response = restService.invokeGetApi(headers,
            REPORT_MS_URL.concat(REPORT_TEMPLATE_URL));

    return response;
}


// Service C get the data and returning it to Service B
@GetMapping(value = "/templates", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<ReportTemplate>> getReportTemplate() throws Exception {
    List<ReportTemplate> reportTemplates = reportService.getAllReportTemplates();

    return ResponseEntity.ok(reportTemplates);
}
// Advice in Service C to add Content-Length and Connection headers before sending response
@Slf4j
@ControllerAdvice
public class ResponseFilter implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        if(mediaType.equals(MediaType.APPLICATION_JSON)){
            ObjectMapper mapper = new ObjectMapper();
            try {
                String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(o);
                log.info("===========================================================================");
                log.info(String.valueOf(json.length()));

                serverHttpResponse.getHeaders().add("Content-Length", String.valueOf(json.length()));
                serverHttpResponse.getHeaders().add("Connection", "keep-alive");
                log.info(serverHttpResponse.getHeaders().toSingleValueMap().toString());

                log.info("===========================================================================");
            } catch (JsonProcessingException e) {
                log.error(e.getOriginalMessage());
            }
        }

        return o;
    }
}
    

现在的问题是,当我尝试运行它时出现以下错误当 Error while extracting response for type [class java.lang.Object] and content type [application/json;charset=UTF-8]; nested exception is org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 1,493; received: 1,111)"
我让三个应用程序直接一起交谈而不使用 httpd 作为代理时,它工作正常,但是一旦我启用它,我就会收到该错误。
非常感谢任何帮助。

标签: springspring-boothttpsmicroservices

解决方案


推荐阅读