Nie sądzę, że istnieje proste i czyste rozwiązanie dla tego problemu. Ale tutaj jest kilka myśli w jaki sposób można go rozwiązać (Gist demo obu przypadkach):
Wariant 1: Dodaj @JsonIgnore
powyżej własności i @JsonAnyGetter
na najwyższym poziomie fasoli. Łatwe do wdrożenia, ale nie miło mieć statyczny ObjectMapper w fasoli i będzie musiał skopiować ten kod do każdego był z własności parametru
public class A {
@JsonIgnore
Parameter parameter;
// can put ObjectMapper and most of this code in util class
// and just use JacksonUtils.toMap(parameter) as return of JsonAnyGetter
private static ObjectMapper mapper = new ObjectMapper();
/************************ Serialization ************************/
@JsonAnyGetter
private Map<String, Object> parameterAsMap(){
return mapper.convertValue(parameter, Map.class);
}
/************************ Deserialization **********************/
@JsonAnySetter
private void parameterFromMap(String key, JsonNode value) {
try {
parameter = mapper.readValue(String.format("{\"%s\":%s}", key,value),
Parameter.class);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Opcja 2:@JsonIgnore
nieruchomości i zarejestrować niestandardowe serializatora/Deserializator root A
Klasa
SimpleModule module = new SimpleModule();
module.addSerializer(A.class, new ASerializer());
module.addDeserializer(A.class, new ADeserializer());
mapper.registerModule(module);
nie można użyć @JsonSerialize
powyżej lekcje, bo serializers i deserializers wewnętrzna ObjectMapper będzie również korzystać z tej adnotacji, ale musisz ustawić go u se domyślny serializer/deserializer, a nie sam rekursywnie. Czy można zaimplementować coś podobnego https://stackoverflow.com/a/18405958/1032167 jeśli naprawdę chcesz adnotacji
I serializer + Deserializator będzie wyglądać mniej więcej tak (Niezoptymalizowana i tylko dowodem koncepcji):
/************************ Serialization ************************/
public static class ASerializer extends JsonSerializer<A> {
private static ObjectMapper m = new ObjectMapper();
@Override
public void serialize(A value, JsonGenerator gen,
SerializerProvider serializers) throws IOException {
Map defaults = m.convertValue(value, Map.class);
Map params = m.convertValue(value.getParameter(), Map.class);
defaults.putAll(params);
gen.writeObject(defaults);
}
}
/************************ Deserialization **********************/
public static class ADeserializer extends JsonDeserializer<A> {
private static ObjectMapper m = new ObjectMapper();
private static String[] subtipes = {"integerParam", "comboParam"};
public ADeserializer() {
m.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
@Override
public A deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
TreeNode node = m.readTree(p);
A a = m.convertValue(node, A.class);
// hardcoded , probably can be done dynamically
// with annotations inspection
for (String key : subtipes) {
TreeNode value = node.get(key);
if (value != null) {
String json = String.format("{\"%s\":%s}", key, value);
a.setParameter(m.readValue(json, Parameter.class));
break;
}
}
return a;
}
}
Generic Deserializator byłoby dość trudne do napisania. Ale to pytanie dotyczy serializacji według ciała pytania.
wygląd [Jackson polimorficznej deserializacjia] (http://wiki.fasterxml.com/JacksonPolymorphicDeserialization) – Rembo
można znaleźć przykład [tutaj] (http://stackoverflow.com/a/6543330/1066779) – Rembo
I edycja kwestia być jaśniejsze –