Добавьте вычисляемое виртуальное свойство к каждому полю с помощью jackson

#java #json #jackson

#java #json #джексон

Вопрос:

Я хотел бы добавить вычисляемые свойства к каждому полю моего DTO.

Например, мой POJO выглядит так:

 @Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class UserInfoDto {
    
    private String firstName;
    private String lastName;
    private String secondLastName;

}
 

Результирующий json выглядит следующим образом:

 {
    "firstName": "foo",
    "lastName": "bar",
    "secondLastName": "foobar"
}
 

Моя цель — сообщить вызывающей стороне моего API о конкретных свойствах каждого поля (т.е. «редактируемом»)
И я бы хотел, чтобы это выглядело примерно так:

 {
    "firstName": {
        "editable": false,
        "value": "foo"
    },
    "lastName": {
        "editable": false,
        "value": "bar"
    },
    "secondLastName": {
        "editable": true,
        "value": "foobar"
    }
}
 

В настоящее время я изменил класс DTO, чтобы он выглядел так:

 @Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class UserInfoClientDto {

    private Field<String> firstName;
    private Field<String> lastName;
    private Field<String> secondLastName;
}

@Data
@Builder
public class Field<T> {
    @Builder.Default
    private boolean editable = true;
    private T value;
    
}
 

Но таким образом требуется много работы для поддержания. Я использую функцию «toUserInfoDto», которая выполняет какой-то уродливый код, подобный этому:

 userInfoClientDto.getFirstName().setEditable(isFirstNameEditable);
userInfoClientDto.getLastName().setEditable(isLastNameEditable);
 

Кто-нибудь может объяснить лучший подход для достижения того, что мне нужно?

Комментарии:

1. Существуют и другие, менее громоздкие подходы к такого рода вещам, например, схема JSON.

Ответ №1:

Создайте свою собственную аннотацию @Field с именем attribute editable , затем создайте пользовательский сериализатор с именем FieldSerializer (см., Например, Здесь ), который использует атрибут annotation .

Они будут использоваться следующим образом:

 @JsonSerialize(using = FieldSerializer.class)
public class UserInfoClientDto {

    @Field(editable = false)
    private String firstName;

    @Field(editable = false)
    private String lastName;

    @Field(editable = true)
    private String secondLastName;

}
 

Поскольку вы просили только лучший подход, а не полное решение, я оставлю вам фактическое написание пользовательского сериализатора.