Как различить нулевые и не предоставленные значения для частичных обновлений в Spring Rest Controller
=====================================================================================================

Я пытаюсь различить нулевые значения и не предоставленные значения при частичном обновлении сущности с помощью метода запроса PUT в Spring Rest Controller.

Рассмотрим в качестве примера следующую сущность:

Мой личный репозиторий (Spring Data):

Я использую DTO:

Мой Spring RestController:

**Запрос с отсутствующим свойством**

Ожидаемое поведение: обновление`firstName= "John"` (Покидать`lastName` без изменений).

**Запрос с нулевым свойством**

Ожидаемое поведение: обновление`firstName="John"` и установить`lastName=null`.

Я не могу различить эти два случая, так как`lastName` в DTO всегда установлен`null` Джексон.

Примечание: я знаю, что лучшие практики REST (RFC 6902) рекомендуют использовать PATCH вместо PUT для частичных обновлений, но в моем конкретном сценарии мне нужно использовать PUT.

 если игнорировать проверку, вы можете решить вашу проблему следующим образом.

Во-первых, напишите суперкласс для вашего dto, например BusDto.Во-вторых, измените dto, чтобы расширить суперкласс, и измените метод set dto, чтобы присвоить имя и значение атрибута для ChangeAttrs (поскольку пружина будет вызывать набор, когда атрибут имеет значение независимо от нуля или не равно нулю).В-третьих, обход карты.

По умолчанию не сбрасывайте «нулевые» значения. Предоставьте явный список через параметры запроса, какие поля вы хотите сбросить. Таким образом, вы все равно можете отправлять JSON, который соответствует вашей сущности, и иметь гибкость для отмены полей при необходимости.

В зависимости от вашего варианта использования некоторые конечные точки могут явно обрабатывать все нулевые значения как неустановленные операции. Немного опасно для исправления, но в некоторых случаях может быть вариант.



зовании`JsonNode` как DTO. Таким образом, вы получите только то, что представлено.

Вам нужно будет написать`MergeService` Вы сами делаете настоящую работу, похожую на BeanWrapper. Я не нашел существующую структуру, которая может делать именно то, что нужно. (Если вы используете только запросы Json, вы можете использовать Jacksons`readForUpdate` Метод.)

На самом деле мы используем другой тип узла, так как нам нужны те же функциональные возможности, что и в «стандартных отправках форм» и других вызовах службы. Кроме того, изменения должны применяться в транзакции внутри чего-то, называемого`EntityService`.

это`MergeService` к сожалению, станет довольно сложным, так как вам придется самостоятельно обрабатывать свойства, списки, наборы и карты :)

Самым проблемным для меня было провести различие между изменениями в элементе списка / набора и модификациями или заменами списков / наборов.

А также проверка будет нелегкой, так как вам нужно проверить некоторые свойства по другой модели (в моем случае сущности JPA)

РЕДАКТИРОВАТЬ - Некоторый код сопоставления (псевдокод):



Используйте логические флаги как[Автор Джексона рекомендует](https://github.com/FasterXML/jackson-databind/issues/578#issuecomment-58443025).