如何将 JSON 请求解析为 FlightOfferSearch[] 对象?

How do I parse a JSON request into a FlightOfferSearch[] object?

在将 here 中的 FlightOfferSearch 的响应示例 JSON 传递给我的测试 REST 控制器时,我无法对其进行反序列化:

@RestController
public class MyController {

  @PostMapping("/search")
  String searchHandler(@RequestBody FlightOfferSearch[] flightOfferSearches) {
    return flightOfferSearches[0].toString();
  }
}

(仅 Spring Boot Starter App 与 "Web" 依赖项以及 gson 2.8.5amadeus-java 4.1.0 添加到 pom.xml 的最小示例)

我在 IntelliJ 中得到这个:

2020-04-20 17:05:59.392  WARN 47240 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Conflicting setter definitions for property "fixedLengthStreamingMode": java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params) vs java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property "fixedLengthStreamingMode": java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params) vs java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params)
 at [Source: (PushbackInputStream); line: 1, column: 1]]

Process finished with exit code -1

在 Postman 中是这样的:

"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Conflicting setter definitions for property \"fixedLengthStreamingMode\": java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params) vs java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property \"fixedLengthStreamingMode\": java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params) vs java.net.HttpURLConnection#setFixedLengthStreamingMode(1 params)\n at [Source: (PushbackInputStream); line: 1, column: 1]"

感谢所有评论,谢谢!

您可能没有为参数 class 的某些字段创建设置器,但问题更深层次 - 您处理此问题的方式不正确。 Spring 的 @RestController 默认将传入的 payload 从 JSON 转换为控制器方法的对象参数,并将 return 对象转换为 JSON。

spring-boot-starter-web 外,您不需要包含任何额外的依赖项,其中包含默认的 Jackson JSON 映射器。

但即使您使用 gson 代替,Spring 仍然会以这种方式工作,只是它会使用 gson 代替。

你需要做的就是创建一个 class,它正确地代表你传入的 json 并使用那个 class 作为参数,它必须有一个空的构造函数,如果将此对象用作请求主体,则为 setter;如果将该对象用作响应主体,则为 getter。

更新: 如果您不拥有用作控制器方法参数的对象 - 我建议无论如何创建自定义 POJO,使用非封装的第三方库至少被认为是一种气味,它违反了封装并与第三方建立紧密耦合 -派对图书馆。