Spring Boot Jackson - выборочная сериализация свойств встроенных объектов на основе их глубины - PullRequest
0 голосов
/ 10 февраля 2020

Я отредактировал вопрос для большей ясности.

Моя формулировка проблемы как я могу настроить способ, которым Джексон сериализует сущность, отправленную в моем ответе REST, таким образом, что мой JSON не делает не стал слишком большим / нечитаемым?

Предположим, у меня есть следующие сущности (или ресурсы / модели и т. д. c)

public class Department
{
    private Long id;
    private String name;
    private Employee head;
    /***
     * Other fields, getters and setters
     */
}

И еще одна, как эта

public class Employee {
    private Long id;
    private String name;
    private Department department;
    /***
     * Other fields, getters and setters
     */    
}

У меня есть REST API, который получает Сотрудника по его / ее идентификатору, и вот ответ, когда я звоню, что

GET /api/employees/2
{
  "id":"2",
  "name":"John Doe",
  "department":{
    "id":3,
    "name":"Product Support",
    "head":{
      "id":1,
      "name":"The Chairman",
      "department":{
        "id":1,
        "name":"Executive",
        "head":null
      }
    }
  }
}

Ответ, как вы можете видеть, большой (и может стать действительно большим в зависимости от модели данных). Я хочу, чтобы сериализация не углублялась во вложенные объекты.

Мой предпочтительный JSON ответ будет:

GET /api/employees/2
{
  "id":"2",
  "name":"John Doe",
  "department":{
    "id":3,
    "name":"Product Support",
  }
}

Я уже знаю, что могу использовать аннотацию @JsonIgnore на Department.head, вот так:

public class Department
{
    private Long id;
    private String name;

    @JsonIgnore
    private Employee head;
    /***
     * Other fields, getters and setters
     */
}

Но это будет пропускать сериализацию свойства head навсегда. Например, см. Приведенный ниже вызов API REST, после добавления @ JsonIgnore

GET /api/departments/3
{
   "id":3,
   "name":"Product Support",
}

// Here, I want the Full serialized form of the Department Object

Итак, как вы можете видеть, вот вопрос: я хочу, чтобы объект Department был полностью сериализован, когда я звоню GET /api/departments/3. Но я хочу пропустить свойство head при вызове GET /api/employees/2. Как мне добиться этого в Джексоне, когда он используется в Spring Boot?

Я также натолкнулся на библиотеку под названием Squiggly , которая использует язык запросов, подобный GraphQL, для ответов API, но я бы хотел чтобы узнать, смогу ли я обойтись без необходимости изучать новую библиотеку.

Большое спасибо

Правка После ответа Аббина Варгезе Я изменил свою модель Employee на модель ниже:

public class Employee {
    private Long id;
    private String name;

    @JsonIgnoreProperties({"head"})
    private Department department;
    /***
     * Other fields, getters and setters
     */    
}

После сериализации это дало мне следующий JSON вывод:

{
  "id":"2",
  "name":"John Doe",
  "department":{
    "id":3,
    "name":"Product Support",
  }
}

pro здесь, это то, что это решает мою проблему, без необходимости писать отдельный класс DTO для моих моделей.

Однако con таков: В этом случае я пытаюсь пропустить сериализацию только для свойства head, поэтому имеет смысл включить это в аннотацию @JsonIgnoreProperties. Что если список пропускаемых свойств длиннее, чем список сериализуемых свойств? Например, если у моего отдела 15 свойств, а я sh сериализую только 3 из них, то будет трудно включить 12 свойств, которые нужно пропустить, в аннотацию @JsonIgnoreProperties.

Есть ли аннотация, которая делает обратное (Включить только эти поля и т. Д. c.) ??

1 Ответ

0 голосов
/ 10 февраля 2020

JsonProperty.Access.WRITE_ONLY - хороший способ избежать элементов.

Например ..

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToOne
@JoinColumn(name = "MODIFIED_BY")
private User lastUpdatedBy;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...