Обработка записей ассоциаций в пользовательских запросах POST PUT и PATCH при весеннем отдыхе данных - PullRequest
0 голосов
/ 28 октября 2019

У меня есть требование, при котором я должен иметь собственную бизнес-логику в конечных точках POST, PATCH и PUT. Использование событий SDR невозможно, так как мне нужно выполнить несколько транзакционных операций в запросе. Итак, я решил создать свою пользовательскую конечную точку для объекта, который присоединен к хранилищу с помощью класса обслуживания.

@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
    @PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
    public ResponseEntity postResult(@RequestBody Entity entity) {
        // my logic
    }
}

Теперь я столкнулся с проблемой, когда мой запрос POST может иметь ссылки на связь с другими объектами. Реализация SDR по умолчанию обрабатывает это изящно, но я сталкиваюсь с ошибкой отображения Джексона.

JSON parse error: Cannot construct instance of `com.foo.bar.Entity` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('/api/v1/entity/12345678-1234-1234-1234-123456789012')

Таким образом, я посмотрел, как реализация Spring, и я нашел следующий метод

@ResponseBody
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.POST)
public ResponseEntity<ResourceSupport> postCollectionResource(RootResourceInformation resourceInformation,
        PersistentEntityResource payload, PersistentEntityResourceAssembler assembler,
        @RequestHeader(value = ACCEPT_HEADER, required = false) String acceptHeader)

и я обнаружил, что PersistentEntityResource payload заполняется выбранной ассоциированной сущностью, а основная сущность сохраняется посредством обычного вызова сохранения в хранилище.

Итак, я попробовал автопроводку PersistentEntityResource, но по сути это не удалось, потому что инициатор PersistentEntityResource ожидает, что URL-адрес сопоставления будет иметь вид /{repository}/<optional id> и, как я уже знаю, каков мой путь, PersistentEntityResourceне может инициализироваться. Также не помогает то, что PersistentEntityResource не является универсальным (до SDR 2.0.0.M1, после которого он был удален). Возможность использования PersistentEntityResource также значительно упростила бы реализацию PATCH и PUT.

Есть ли способ справиться с этим?

1 Ответ

0 голосов
/ 06 ноября 2019

Я нашел ответ после некоторого копания. Оглядываясь назад, это довольно тривиально. Просто используйте Resource<Entity> вместо Entity в параметрах метода.

@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
    @PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
    public ResponseEntity postResult(@RequestBody Resource<Entity> entity) {
        // my logic. Fetch the entity with entity.getContent()
    }
}

Вы можете получить сам объект, используя entity.getContent()

...