Десериализатор Джексона не регистрируется в webflux с помощью сопрограмм kotlin

#java #spring #kotlin #jackson #spring-webflux

#java #весна #котлин #джексон #spring-webflux #kotlin

Вопрос:

У меня небольшая проблема с десериализатором Jackson. Когда я добавляю аннотацию в класс:

         @NotNull
        @JsonDeserialize(using = JsonPointDeserializer::class)
        val pharmLocation: Point,
  

он десериализуется правильно. Но я не хочу добавлять его везде в свой код, потому что я ленив, поэтому я добавил в конфигурации:

 @Bean
    fun jacksonCustomizer(): Jackson2ObjectMapperBuilderCustomizer {
        return Jackson2ObjectMapperBuilderCustomizer { builder: Jackson2ObjectMapperBuilder ->
            builder
                    .serializerByType(Point::class.java, JsonPointSerializer())
                    .deserializerByType(Point::class.java, JsonPointDeserializer())
        }

    }
  

А теперь забавный момент. Сериализатор работает правильно, а десериализатор — нет. Я получаю сообщение об ошибке, json из запроса выглядит правильно "pharmLocation":{"lat":20.0,"lng":20.0}, , но в стеке я вижу:

 org.springframework.core.codec.CodecException: Type definition error: [simple type, class org.springframework.data.geo.Point]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.data.geo.Point` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.core.io.buffer.DefaultDataBuffer$DefaultDataBufferInputStream); line: 1, column: 74] (through reference chain: *.backend.advert.request.NewAdvert["pharmLocation"])```
  

Я думаю, что использование awaitBodyOrNull может быть причиной, но понятия не имею, как с этим бороться.

Комментарии:

1. В сообщении об ошибке четко указана проблема, нет? У вас нет конструктора по умолчанию. Вы можете использовать @JsonCreator для решения этой проблемы

2. Но десериализатор работает корректно, когда я добавляю его с помощью аннотации. Я могу десериализовать поле с помощью аннотации, но не тогда, когда я регистрирую десериализатор в bean.

3. Не могли бы вы показать Point класс, пожалуйста?

4. мой класс point import org.springframework.data.geo.Point и мой код десериализатора: class JsonPointDeserializer: JsonDeserializer<Point>() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): Point { val jsonNode = p.codec.readTree<TreeNode>(p) val x = jsonNode["lat"].toString().toDouble() val y = jsonNode["lng"].toString().toDouble() return Point(x, y) } }

5. Не могли бы вы также показать код, который десериализует этот json? Или это какие-то внутренние компоненты spring?