#java #json #serialization #jackson #objectmapper
#java #json #сериализация #Джексон #objectmapper
Вопрос:
У меня есть класс Person:
public class Person {
private String name;
private String address;
}
Теперь этот класс Person используется в другом классе как:
public class Group {
private Person nicePerson;
private Person badPerson;
private Person secretPerson;
}
Теперь я хочу сериализовать свой групповой объект в JSON с помощью Jackson ObjectMapper. Я использую пользовательский сериализатор, основанный на некоторой аннотации.
Когда я сериализую объект Group, я ищу следующий вывод:
{
"nicePerson": {
"name": "John",
"address": "usa"
},
"badPerson": {
"name": "Harold",
"address": "canada"
},
"secretPerson": {
"name": "XXXXXXX",
"address": "london"
}
}
Здесь я хочу изменить имя ‘secretPerson’ на «XXXXXXX».
Но у меня возникли некоторые проблемы.
Я сделал следующую аннотацию:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface SecretInfo {
String maskedValue = "XXXXXXX";
String value() default maskedValue;
}
Я аннотировал свой класс Person следующим образом:
public class Person {
@SecretInfo
private String name;
private String address;
}
Я создал следующий сериализатор, который ищет эту аннотацию, а затем изменяет значение. Теперь для удобства используются некоторые обобщения.
public class SecretInfoSerializer<T> extends StdSerializer<T> implements ContextualSerializer {
private SecretInfo secretInfo;
public SecretInfoSerializer() {
super((Class<T>) String.class);
}
public SecretInfoSerializer(SecretInfo secretInfo,
JavaType clazz) {
super(clazz);
this.secretInfo = secretInfo;
}
@Override
public void serialize(T value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (secretInfo != null amp;amp; value != null) {
jsonGenerator.writeString(secretInfo.value());
} else jsonGenerator.writeString(getValue(value));
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
if (property != null) {
return new SecretInfoSerializer<>(
property.getAnnotation(SecretInfo.class),
property.getType());
} else {
return new SecretInfoSerializer<>();
}
}
private String getValue(T value) {
if (value == null) {
return "null";
} else {
return value.toString();
}
}
}
Я связал это с аннотацией Introspector и создал ObjectMapper.
Затем я сериализовал свой класс ‘Group’ выше. Но я получаю следующий вывод:
{
"nicePerson": {
"name": "XXXXXXX",
"address": "usa"
},
"badPerson": {
"name": "XXXXXXX",
"address": "canada"
},
"secretPerson": {
"name": "XXXXXXX",
"address": "london"
}
}
Как вы можете видеть, поскольку я аннотировал поле ‘name’ в классе Person, я получаю «XXXXXXX» для каждого существующего класса Person. Но это не то, чего я хотел. Я просто хочу изменить значение только для ‘secretPerson’.
Я не знаю, что делать:
Может быть, есть какой-то способ, например, следующий:
public class Group {
private Person nicePerson;
private Person badPerson;
@HasSecretInfo
private Person secretPerson;
}
Затем сериализатор будет проверять, если это @HasSecretInfo
так, только затем искать @SecretInfo
… и т.д. что-то вроде этого.
Итак, я ищу решение этой проблемы. Если у вас есть какое-либо решение, это было бы здорово.