По умолчанию, когда набор текста не используется, вы можете сгенерировать полезную нагрузку JSON
, которую впоследствии можно будет десериализовать для любой модели, которая соответствует этому JSON
. Или даже к Map
или / и List
объектам, если вы вообще не хотите создавать модель.
В вашем случае, когда JSON
полезные нагрузки используются двумя разными приложениями с двумя разными моделямиВы не должны прикреплять информацию о классе, потому что она не предоставляет никакой дополнительной информации для другой модели. Один JSON
можно десериализовать разными способами и использовать для разных целей, поэтому его связывание с одной моделью вызывает проблемы, как вы заметили в своем примере. Таким образом, если это возможно, отключите набор текста и предоставьте явно всю информацию, необходимую позже для воссоздания того же объекта из JSON
.
Если это невозможно, просто предоставьте свой пользовательский TypeIdResolver
и сопоставьте один классот одной модели до аналогичного класса в другой модели. Простой пример, который показывает идею:
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.SimpleType;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
SimpleModule model2Module = new SimpleModule("Model2");
model2Module.setMixInAnnotation(PojoA2.class, CustomJsonTypeIdResolverMixIn.class);
model2Module.setMixInAnnotation(PojoB2.class, CustomJsonTypeIdResolverMixIn.class);
model2Module.setMixInAnnotation(PojoC2.class, CustomJsonTypeIdResolverMixIn.class);
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
mapper.registerModule(model2Module);
String json = mapper.writeValueAsString(new PojoA());
System.out.println(json);
System.out.println(mapper.readValue(json, PojoA.class));
System.out.println(mapper.readValue(json, PojoA2.class));
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM)
@JsonTypeIdResolver(value = Model2ClassNameIdResolver.class)
interface CustomJsonTypeIdResolverMixIn { }
class Model2ClassNameIdResolver extends ClassNameIdResolver {
private final Map<String, JavaType> types = new HashMap<>();
public Model2ClassNameIdResolver() {
super(null, null);
types.put("com.celoxity.PojoA", SimpleType.constructUnsafe(PojoA2.class));
types.put("com.celoxity.PojoB", SimpleType.constructUnsafe(PojoB2.class));
types.put("com.celoxity.PojoC", SimpleType.constructUnsafe(PojoC2.class));
}
@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
JavaType javaType = types.get(id);
if (javaType != null) {
return javaType;
}
return super.typeFromId(context, id);
}
}
class PojoA2 {
private PojoB2 b;
}
class PojoB2 {
private List<PojoC2> c;
}
class PojoC2 {
private String s;
private int i;
}
class PojoA {
private PojoB b;
}
class PojoB {
private List<PojoC> c;
}
class PojoC {
private String s;
private int i;
}
Две модели: PojoA
, PojoB
, PojoC
и PojoA2
, PojoB2
, PojoC2
имеют одинаковую структуру и имеют только разныеимена. PojoA
совпадает с PojoA2
и т. Д.
Над отпечатками кода:
["com.celoxity.PojoA",{"b":["com.celoxity.PojoB",{"c":["java.util.ArrayList",[["com.celoxity.PojoC",{"s":"Vika","i":22}]]]}]}]
и позже:
PojoA{b=PojoB{c=[PojoC{s='Vika', i=22}]}}
PojoA2{b=PojoB2{c=[PojoC2{s='Vika', i=22}]}}