0

我有以下课程:

data class Thing(val lines: List<String>)

JSON 表示为:

{
    "lines": [
        "something",
        "something else"
    ]
}

Spring WebFlux 可以通过以下方式成功解析:

// Parse the JSON as an object and return it.
request -> ServerResponse.ok().body(request.bodyToMono(Thing::class.java)

但是,使用以下任一技术直接使用 Jackson 会失败:

val mapper = ObjectMapper()
val item = mapper.readValue<Thing>("""{"lines":["something","something else"]}""")
ServerResponse.ok().body(request.bodyToMono(Map::class.java)
        .map { map ->
            val mapper = ObjectMapper()
            val tmp = mapper.convertValue(map, Thing::class.java)
        }

错误是:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `Thing` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

我认为 Spring 正在使用 Jackson 进行转换。而且我认为杰克逊可以应对从 JSON -> POJO 的这种基本转换。使用@JsonDeserialize类显然有效。那么为什么第一个例子有效而第二个无效呢?

4

1 回答 1

2

Spring 使用 Jackson,但它在创建 ObjectMapper 的默认实例时注册自定义处理程序和模块。

Jackson 对采用单个参数的构造函数进行了特殊处理。这样做是为了支持 UUID 和 URI 等类。要指示 Jackson 不要使用此技术,请使用 @JsonCreator 注释您的构造函数。

data class Thing @JsonCreator constructor(val lines: List<String>)

我没有查看 Spring 的响应式代码,所以我不知道它是什么或是否会禁用 Jackson 的特殊处理。

于 2020-01-01T17:43:19.677 回答