#java #json #serialization #jackson #jackson2
Вопрос:
Я использую Jackson
для сериализации a POJO
. Этот POJO
класс состоит из некоторых полей и a Map<String,Object> others
. Я использую во Custom Serializer
время написания JSON
для этого MAP
поля. Я хочу избежать получения Map field name "others"´ in my
. Hence, I am using the
карты JSON on the
@ field but using the
JsonValue@JsonValue is conflicting with
@JsonTypeInfo’. Мне нужны обе аннотации в моем классе, как я могу этого достичь?
На данный момент я получаю JSON
следующее: (С обоими @JsonValue
и @JsonTypeInfo
)
[ "Customer", {
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
} ]
Я хотел бы получить JSON
следующее с обоими @JsonValue
и @JsonTypeInfo
: (Как вы можете видеть others
, ключ зафиксирован, но его значения добавляются непосредственно в JSON)
{
"isA" : "Customer",
"name" : "Batman",
"google:sub" : "MyValue-1",
"age" : "2008"
}
Я могу получить вывод, но мне нужно удалить аннотацию из моего класса:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
Но если я удалю это, то я не получу isA
свойство в своем JSON. Я хочу знать, как заставить Jackson Json Serializer
работать и с @JsonTypeInfo
и @JsonValue
.
Вывод без @JsonTypeInfo
, но с @JsonValue
:
{
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
}
Вывод без @JsonValue
, но с @JsonTypeInfo
{
"isA" : "Customer",
"name" : "",
"age" : "",
"others" : {
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
}
}
Following is my Customer
class Pojo:
@XmlRootElement(name = "Customer")
@XmlType(name = "Customer", propOrder = {"name", "age", "others"})
@XmlAccessorType(XmlAccessType.FIELD)
@NoArgsConstructor
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@JsonIgnoreType
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, visible = true, property = "isA")
public class Customer {
@XmlElement(name = "name", required = true)
private String name;
@XmlElement(name = "age", required = true)
private String age;
@JsonSerialize(using = CustomExtensionsSerializer.class)
@XmlJavaTypeAdapter(TestAdapter.class)
@XmlPath(".")
@JsonValue
private Map<String, Object> others = new HashMap<>();
@JsonAnySetter
public void setOthers(String key, Object value) {
others.put(key, value);
}
public Map<String, Object> getOthers() {
return others;
}
}
Ниже приведен мой » Пользовательский сериализатор:
public class CustomExtensionsSerializer extends JsonSerializer<Map<String, Object>> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
recusiveSerializer(value, gen, serializers);
gen.writeEndObject();
}
public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
for (Map.Entry<String, Object> extension : value.entrySet()) {
if (extension.getValue() instanceof Map) {
//If instance is MAP then call the recursive method
recusiveSerializer((Map) extension.getValue(), gen, serializers);
} else if (extension.getValue() instanceof String) {
//If instance is String directly add it to the JSON
gen.writeStringField(extension.getKey(), (String) extension.getValue());
} else if (extension.getValue() instanceof ArrayList) {
//If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
for (Object dupItems : (ArrayList<String>) extension.getValue()) {
if (dupItems instanceof Map) {
recusiveSerializer((Map) dupItems, gen, serializers);
} else {
gen.writeStringField(extension.getKey(), (String) extension.getValue());
}
}
gen.writeEndObject();
}
}
}
}
Ответ №1:
Попробуйте установить @JsonTypeInfo.include
в JsonTypeInfo.As.EXISTING_PROPERTY
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true, property = "isA")
Комментарии:
1. Привет, спасибо, что нашли время и ответили. Я действительно пробовал это. Добавление этого приведет к созданию того же JSON, что и в первом JSON, указанном в вопросе. Он добавляет в
Array
качестве оболочки в мой JSON, а также значения полностью перепутались примерно так:[ "Customer", { "google:main" : { "google:sub" : "MyValue-1" }, "name" : "BATMAN", "age" : "2008" } ]