Spring Boot - postForEntity():响应的内容类型是什么?



我正在尝试在一组通过HTTP REST进行通信的Spring Boot微服务上设置和运行集成测试。我正在使用柑橘框架作为集成测试框架。

我有一个测试场景,涉及一个"主"服务调用另外两个服务来执行工作。我的测试具有启动流程和"模拟"辅助角色服务的调用。我将在下面包括来源。

我遇到了一个问题,我收到一个异常,似乎表明测试期望接收的消息(如application/json(正在text/plain通过,并且找不到要使用的消息转换器。奇怪的是,收到的消息应该是JSON(或者至少看起来像JSON(。

我在发送端(POSTer(遇到了类似的问题,Citrus 在接收消息时遇到问题。我将其追溯到我没有设置任何HTTP标头的事实,特别是AcceptContent-Type。一旦我适当地设置了这些,柑橘对它收到的东西很满意。

服务代码:

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 请求中发送的实体将AcceptContent-Type标头设置为application/json。我想我在那里没事。上面的堆栈跟踪似乎在说响应消息要么没有设置标头(或设置为错误的值(,并且由于测试用例需要 JSON,因此测试失败。

当这些服务"正常"运行时(即不通过Citrus驱动(,一切正常。没有我能够辨别的问题。

我最近在尝试解码 REST Respones 时两次遇到过 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

相关内容

  • 没有找到相关文章

最新更新