Spring 启动 - postForEntity():响应的内容类型是什么?
Spring Boot - postForEntity(): what is content type of the response?
我正在尝试对一组 Spring 通过 HTTP REST 通信的启动微服务进行设置和 运行 集成测试。我正在使用 Citrus Framework 作为集成测试框架。
我有一个测试场景,其中一个 "master" 服务调用另外两个服务来完成工作。我的测试调用了启动流程和 "mock" 工作人员服务。我将在下面包含来源。
我正在 运行 遇到一个问题,我得到一个异常,似乎表明测试期望收到的消息(如 application/json
)正在通过 [=14] =] 并且找不到要使用的消息转换器。奇怪的是,正在接收的消息 应该 是 JSON(或者至少 看起来 像 JSON)。
我在发送端(POSTer)遇到了类似的问题,Citrus 在接收消息时遇到了问题。我追查到我没有设置任何 HTTP headers,特别是 Accept
和 Content-Type
。一旦我适当地设置了这些,Citrus 就会对收到的结果感到满意。
服务代码:
HttpEntity<GenerateRouteCommand> entity =
(HttpEntity<GenerateRouteCommand>) HttpEntityBuilder.createHttpEntity(...);
ResponseEntity<GenerateRouteStatus> response =
rgTemplate.postForEntity(url, entity, GenerateRouteStatus.class);
异常:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class edu.mit.ll.mission_services.messages.GenerateRouteStatus] and content type [text/plain;charset=utf-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:121)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:994)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:977)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:445)
at edu.mit.ll.mission_services.service.mission_planner.service.MissionPlanner.postGenerateRoute(MissionPlanner.java:214)
at edu.mit.ll.mission_services.service.mission_planner.service.MissionPlanner.planMission(MissionPlanner.java:144)
at edu.mit.ll.mission_services.service.mission_planner.controller.MissionPlannerController$Runner.executeTask(MissionPlannerController.java:51)
at edu.mit.ll.mission_services.common.util.ITask.run(ITask.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
在 POST 请求中发送的实体将 Accept
和 Content-Type
headers 设置为 application/json
。我觉得我在那里很好。上面的堆栈跟踪似乎在说响应消息没有设置 headers(或设置为错误的值),并且由于测试用例需要 JSON,因此测试失败。
当这些服务 运行 "normally"(即不是通过 Citrus 驱动)时,一切正常。我没有发现任何问题。
我最近 运行 在尝试解码 REST 响应时用 spring-boot 解决了这个问题。我通过在 RestTemplate
上显式设置 HttpMessageConverters
解决了这个问题。
如果我是你,我会调试并查看响应的内容实际是什么样子。如果它是 JSON 尝试使用 GsonHttpMessageConverter
或者如果它真的只是文本,请尝试 StringHttpMessageConverter
。或者通过以下方式将两者添加到 RestTemplate
:
private final RestTemplate restTemplate = new RestTemplateBuilder()
.messageConverters(Lists.newArrayList(new GsonHttpMessageConverter(GsonHelper.getInstance()), new StringHttpMessageConverter()))
.build();
如果这些转换器似乎都无法解决您的异常,请查看 HttpMessageConverter
接口的所有不同实现,并推断出哪一个适合您的特定情况。有相当多的实现实现了这个接口。
弄清楚我需要做什么来为从 Citrus 中的模拟服务器返回的消息设置 application/json
的预期内容类型。我遗漏了以下声明:
.contentType(ContentType.APPLICATION_JSON.getMimeType())
一些上下文:
// Set route assessor to return response.
runner.http(builder -> builder
.server(raServer)
.send()
.response(HttpStatus.OK)
.messageType(MessageType.JSON)
.contentType(ContentType.APPLICATION_JSON.getMimeType())
.payload(new ClassPathResource("templates/assess-route-status.json")));
显然,如果不指定,默认为text/plain
。
我正在尝试对一组 Spring 通过 HTTP REST 通信的启动微服务进行设置和 运行 集成测试。我正在使用 Citrus Framework 作为集成测试框架。
我有一个测试场景,其中一个 "master" 服务调用另外两个服务来完成工作。我的测试调用了启动流程和 "mock" 工作人员服务。我将在下面包含来源。
我正在 运行 遇到一个问题,我得到一个异常,似乎表明测试期望收到的消息(如 application/json
)正在通过 [=14] =] 并且找不到要使用的消息转换器。奇怪的是,正在接收的消息 应该 是 JSON(或者至少 看起来 像 JSON)。
我在发送端(POSTer)遇到了类似的问题,Citrus 在接收消息时遇到了问题。我追查到我没有设置任何 HTTP headers,特别是 Accept
和 Content-Type
。一旦我适当地设置了这些,Citrus 就会对收到的结果感到满意。
服务代码:
HttpEntity<GenerateRouteCommand> entity =
(HttpEntity<GenerateRouteCommand>) HttpEntityBuilder.createHttpEntity(...);
ResponseEntity<GenerateRouteStatus> response =
rgTemplate.postForEntity(url, entity, GenerateRouteStatus.class);
异常:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class edu.mit.ll.mission_services.messages.GenerateRouteStatus] and content type [text/plain;charset=utf-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:121)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:994)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:977)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:445)
at edu.mit.ll.mission_services.service.mission_planner.service.MissionPlanner.postGenerateRoute(MissionPlanner.java:214)
at edu.mit.ll.mission_services.service.mission_planner.service.MissionPlanner.planMission(MissionPlanner.java:144)
at edu.mit.ll.mission_services.service.mission_planner.controller.MissionPlannerController$Runner.executeTask(MissionPlannerController.java:51)
at edu.mit.ll.mission_services.common.util.ITask.run(ITask.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
在 POST 请求中发送的实体将 Accept
和 Content-Type
headers 设置为 application/json
。我觉得我在那里很好。上面的堆栈跟踪似乎在说响应消息没有设置 headers(或设置为错误的值),并且由于测试用例需要 JSON,因此测试失败。
当这些服务 运行 "normally"(即不是通过 Citrus 驱动)时,一切正常。我没有发现任何问题。
我最近 运行 在尝试解码 REST 响应时用 spring-boot 解决了这个问题。我通过在 RestTemplate
上显式设置 HttpMessageConverters
解决了这个问题。
如果我是你,我会调试并查看响应的内容实际是什么样子。如果它是 JSON 尝试使用 GsonHttpMessageConverter
或者如果它真的只是文本,请尝试 StringHttpMessageConverter
。或者通过以下方式将两者添加到 RestTemplate
:
private final RestTemplate restTemplate = new RestTemplateBuilder()
.messageConverters(Lists.newArrayList(new GsonHttpMessageConverter(GsonHelper.getInstance()), new StringHttpMessageConverter()))
.build();
如果这些转换器似乎都无法解决您的异常,请查看 HttpMessageConverter
接口的所有不同实现,并推断出哪一个适合您的特定情况。有相当多的实现实现了这个接口。
弄清楚我需要做什么来为从 Citrus 中的模拟服务器返回的消息设置 application/json
的预期内容类型。我遗漏了以下声明:
.contentType(ContentType.APPLICATION_JSON.getMimeType())
一些上下文:
// Set route assessor to return response.
runner.http(builder -> builder
.server(raServer)
.send()
.response(HttpStatus.OK)
.messageType(MessageType.JSON)
.contentType(ContentType.APPLICATION_JSON.getMimeType())
.payload(new ClassPathResource("templates/assess-route-status.json")));
显然,如果不指定,默认为text/plain
。