Напишите полу-нестандартный десериализатор - PullRequest
1 голос
/ 16 апреля 2019

Я хотел бы написать компонент пользовательской десериализации, который по-прежнему будет использовать некоторые возможности по умолчанию:

Представьте себе эти классы:

class Category {
    private Long id;
    private String name;
}

class Article {
    private Long id;
    private String title;
    private Category category;
}

И эту полезную нагрузку JSON:

{
  "id": 1,
  "title": "Pray for Notre Dame",
  "category_id": 5
}

С моим пониманием различных статей, которые я читаю онлайн, я должен написать собственный десериализатор для обработки моего поля category_id:

@JsonComponent
public class ArticleJsonDeserializer extends JsonDeserializer<Article> {

    @Override
    public Article deserialize(JsonParser jsonParser, 
      DeserializationContext deserializationContext) throws IOException, 
      JsonProcessingException {

        TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
        TextNode category = this.entityManager.getReference(Category.class, treeNode.get("category_id"));

        // The following lines bother me
        String title = treeNode.get("title");
        Long id = treeNode.get("id");

        return new Article(id, title, category);
    }
}

Однако на самом деле мне бы очень хотелосьиспользовать возможности десериализатора по умолчанию для полей title и id без перезаписи этой логики.

Как я могу это сделать?

1 Ответ

1 голос
/ 16 апреля 2019

Краткий ответ

Предполагая, что у вас есть конструктор по умолчанию в классе Article, должно работать следующее:

Article article = jsonParser.getCodec().treeToValue(treeNode, Article.class);

Затем установите category в article.

немного более длинный ответ

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

В качестве альтернативы вы можете использовать @JsonIdentityInfo вместе с ObjectIdResolver. Вы можете получить некоторые идеи из подхода, описанного в этом ответе .

Вместо того, чтобы показывать ваши сущности JPA в вашем веб-API, вы могли бы использовать DTO. См. Причины, которые я описал в моем предыдущем ответе для справки. И тогда у вас может быть слой отображения, чтобы сопоставить ваши сущности с вашими DTO и наоборот. Например, если вы используете MapStruct , в документации приведен пример о том, как разрешать объекты по их идентификатору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...