Java записывает (JEP359) как DTO запроса и ответа контроллера Spring

#java #spring-boot #java-14 #java-record

#java #spring-boot #java-14 #java-запись

Вопрос:

Я просто экспериментирую с этими новыми записями Java, и мне интересно, могу ли я использовать их в качестве DTO для моих типов запросов / ответов в приложении Spring boot.

Поэтому я просто изменил некоторый код (класс с большим количеством шаблонов для получения / установки записей), скомпилировал и запустил свое приложение. Пытаюсь использовать некоторые конечные точки rest, и все, что я получил, — это исключение, сообщающее мне:

No serializer found for class x.y.CreateNewShopListeCommand$Item and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS

Ну, хорошо, записи не создают методы получения с префиксом ‘get’. Теперь мне интересно: возможно ли использовать записи в качестве типов запросов / ответов для контроллера загрузки Spring?

РЕДАКТИРОВАТЬ: Пример приложения (https://github.com/kaipaysen/playground-jdk14-records-as-dto)

 // HelloController.java
@RestController
@RequestMapping("/hello")
public class HelloController {
    
    public record HelloRequest(
        @JsonProperty("name") String name
    ) {}

    public record HelloResponse(
        @JsonProperty("message") String message
    ) {}

    @RequestMapping(method = RequestMethod.POST)
    public HelloResponse hello(@RequestBody @Valid HelloRequest query) {
        return new HelloResponse("Hello "   query.name());
    }
    
}
  

curl -X POST -H "Content-Type: application/json" -d '{"name":"Max"}' http://localhost:8080/hello Возвращает {"message":"Hello null"} вызов. Отладка hello показывает, что запрос не десериализован должным образом. Есть идеи на этот счет?

РЕДАКТИРОВАТЬ # 2: только что обнаружена эта проблема с поддержкой типов записей JDK 14 # 2709 в репозитории FasterXML. Они работают над этим для jackson 2.12.

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

1. Как предлагает эта статья , посмотрите, может ли помочь добавление @JsonProperty .

2. Ну, это помогло для сериализации, но не для десериализации. Я добавил минимальный образец выше.

Ответ №1:

Вам нужно добавить эту аннотацию уровня класса к вашим записям.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

В версии Jackson 1.12 он должен быть доступен без аннотаций.

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

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

1. Я попытался добавить аннотацию следующим образом: @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) public record HelloRequest( @JsonProperty("name") String name ) {} но это не работает.

2. попробуйте удалить @JsonProperty («имя»)

3. Все то же самое. Не могли бы вы поделиться рабочим примером?

4. Я думаю, что это ошибка в Jackson, вам нужно добавить второе поле в вашу запись. Это не работает для записи, которая имеет только одно поле.

5. Артем, ты прав. Добавление второго поля в мой запрос HelloRequest позволяет десериализацию (даже без аннотаций). Аннотация в HelloResponse по-прежнему требуется, иначе мы получим ошибку «Конвертер не найден».