Вручную десериализовать строку в сущность в Sprint-boot - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть проект sprint-boot среднего размера, который использует spring-boot-web, spring-data-jpa. Некоторые репозитории данных Spring предоставляются как конечные точки REST с аннотацией @RepositoryRestResource.

У меня также есть несколько пользовательских конечных точек REST. В одной из этих пользовательских конечных точек я размещаю простой DTO:

@Data   // Lombok
public class AssignRequest {
    @JsonDeserialize(using=UserModelDeserializer.class)  
    UserModel uriForThatModel;   // e.g. "/users/4711"
    [...]
}

Я хочу, чтобы клиент мог передавать URI для ссылки на UserModel. Это то, что возвращает RepositoryRestResources. Они возвращают URI ссылочным объектам. Я также хочу использовать это в моем собственном контроллере. Поэтому я написал свой собственный JSON Десериализатор Джексона:

import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
[...]
//@JsonComponent  <========= (2.)
public class UserModelDeserializer extends StdDeserializer<UserModel> {
  [...]
  public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    String uri = p.getValueAsString();
    //extract id from uri, e.g. the 4711 from "/users/4711" with some simple RegEx stuff
    Long id = MyRestUtils.getIdFromURI("users", uri); 
    T entity = repo.findById(id).orElseThrow(() -> new RuntimeException("Cannot find entity at uri="+uri));
    return entity;
  }
}

Теперь у меня есть следующая проблема.

  1. Мой UserModelDeserializer вообще не вызывается, несмотря на @JsonDeserialize аннотация
  2. Если I раскомментировать аннотацию @JsonComponent, то My UserModelDeserializer используется везде даже в тех местах, где этого не должно быть. Не только в моем пользовательском RestController, но также, например, для @RepositoryRestResource при создании новых сущностей в вызове POST / l aws (здесь не используется идентификатор).

=> Почему @JsonDeserialize не выбран весенним экземпляром Джексона?

Полный исходный код доступен здесь:

...