需要使用 ObjectMapper 对非静态内部 Class 进行 MixIn 解析 - Java 6
Need MixIn Resolution for non-static Inner Class using ObjectMapper - Java 6
我在将 ObjectMapper 用于非静态内部 class 时遇到问题。我需要创建 MixIn 才能使其工作但无法找到解决方案。下面是我的 class(我无法更改)和 MixIn,我试过了。创建此类 MixIn 需要帮助。
基础Class
public class NestedClass implements Serializable{
private static final long serialVersionUID = -4509619645418618657L;
private NestedInnerClass innerClass;
public NestedClass() {
innerClass = null;
setInnerClass(new NestedInnerClass(new NestedInnerClass2(), new NestedInnerClass3()));
}
public NestedClass(NestedClass nestedCls) {
innerClass = null;
setInnerClass(nestedCls.getInnerClass());
}
public class NestedInnerClass implements Serializable{
private static final long serialVersionUID = 9099474732768960830L;
NestedClass.NestedInnerClass2 nestedInnerClass2;
NestedClass.NestedInnerClass3 nestedInnerClass3;
public NestedInnerClass() {
super();
}
public NestedInnerClass(NestedInnerClass2 nestedInnerClass2, NestedInnerClass3 nestedInnerClass3) {
super();
this.nestedInnerClass2 = nestedInnerClass2;
this.nestedInnerClass3 = nestedInnerClass3;
}
public NestedClass.NestedInnerClass2 getNestedInnerClass2() {
return nestedInnerClass2;
}
public void setNestedInnerClass2(NestedClass.NestedInnerClass2 nestedInnerClass2) {
this.nestedInnerClass2 = nestedInnerClass2;
}
public NestedClass.NestedInnerClass3 getNestedInnerClass3() {
return nestedInnerClass3;
}
public void setNestedInnerClass3(NestedClass.NestedInnerClass3 nestedInnerClass3) {
this.nestedInnerClass3 = nestedInnerClass3;
}
}
public class NestedInnerClass2 implements Serializable{
private static final long serialVersionUID = -3451502802923307744L;
String nestedString;
HashMap<String, String> nestedHashMap = new HashMap<String, String>();
public NestedInnerClass2() {
super();
}
public NestedInnerClass2(String nestedString, HashMap<String, String> nestedHashMap) {
super();
this.nestedString = nestedString;
this.nestedHashMap = nestedHashMap;
}
public NestedInnerClass2(String nestedString) {
this.nestedString = nestedString;
}
public String getNestedString() {
return nestedString;
}
public void setNestedString(String nestedString) {
this.nestedString = nestedString;
}
public HashMap<String, String> getNestedHashMap() {
return nestedHashMap;
}
public void setNestedHashMap(HashMap<String, String> nestedHashMap) {
this.nestedHashMap = nestedHashMap;
}
}
public class NestedInnerClass3 implements Serializable{
private static final long serialVersionUID = 1799737022784300052L;
String nestedString;
public NestedInnerClass3() {
super();
}
public NestedInnerClass3(String nestedString) {
super();
this.nestedString = nestedString;
}
public String getNestedString() {
return nestedString;
}
public void setNestedString(String nestedString) {
this.nestedString = nestedString;
}
}
public NestedInnerClass getInnerClass() {
return innerClass;
}
public void setInnerClass(NestedInnerClass innerClass) {
this.innerClass = innerClass;
}
}
嵌套 Class 的子 Class :
public class NestedClassChild extends NestedClass implements Serializable, Cloneable{
private static final long serialVersionUID = 7022339501842754692L;
public NestedClassChild() {}
}
辅助Class:
public class NestedClassAssist {
public static void setNestedValues(NestedClass nestedClass, String key, String value, String nestedString)
{
if(nestedClass != null && nestedClass.getInnerClass() != null && nestedClass.getInnerClass().getNestedInnerClass2() != null)
{
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put(key, value);
nestedClass.getInnerClass().getNestedInnerClass2().setNestedHashMap(hashMap);
nestedClass.getInnerClass().getNestedInnerClass2().setNestedString(nestedString);
}
}
public static void setValue(NestedClass nestedClass, String value){
setNestedValues(nestedClass, "keyStr", value, "ABC");
}
}
转换为JSON有效载荷:
public class NestedClassToJson {
public static void main(String[] args) {
NestedClassChild nestedClassChild = new NestedClassChild();
NestedClassAssist.setValue(nestedClassChild, "12345");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
try {
mapper.writeValue(new File("json/testNested.json"),nestedClassChild);
} catch (Exception e) {
e.printStackTrace();
}
}
}
从上方生成 JSON 有效载荷 class :
{
"innerClass" : {
"nestedInnerClass2" : {
"nestedString" : "ABC",
"nestedHashMap" : {
"keyStr" : "12345"
}
},
"nestedInnerClass3" : {
"nestedString" : null
}
}
}
Class 从 JSON 反序列化:
public class NestedClassFromJson {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
NestedClass objectNested = mapper.readValue(getPostBodyAsJSON(), NestedClassChild.class);
System.out.println(mapper.writeValueAsString(objectNested));
}
private static String getPostBodyAsJSON() {
StringBuffer postBody = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("json/testNested.json")));
while ((line = reader.readLine()) != null)
postBody.append(line);
} catch (IOException e) {
throw new RuntimeException("Issue Occured While Reading POST Body", e);
}
return postBody.toString();
}
}
但是我遇到异常(虽然我有默认构造函数) :
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.test.jackson.NestedClass$NestedInnerClass]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: { "innerClass" : { "nestedInnerClass2" : { "nestedString" : "ABC", "nestedHashMap" : { "keyStr" : "12345" } }, "nestedInnerClass3" : { "nestedString" : null } }}; line: 1, column: 24] (through reference chain: com.test.jackson.NestedClassChild["innerClass"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1106)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:296)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
at com.test.jackson.NestedClassFromJson.main(NestedClassFromJson.java:21)
我试过但没有用的嵌套 MixIn:
public abstract class NestedMixIn {
@JsonCreator
public NestedMixIn(@JsonProperty("innerClass") NestedInnerClass innerClass ) {
}
public static class SourceIdInnerMixin{
@JsonCreator
public SourceIdInnerMixin(@JsonProperty("nestedInnerClass2") NestedInnerClass2 nestedInnerClass2,
@JsonProperty("nestedInnerClass3") NestedInnerClass3 nestedInnerClass3) {
}
}
}
如果我使内部 classes static ,它可以工作,但由于它是第 3 方 class,我无法更改它。
感谢您的帮助!!!
在您的示例中,我没有注意到父 class 和嵌套 class 之间的任何关系。你还提到你可以将它更改为静态并且它可以工作,所以我们需要做的就是为反序列化过程提供一个内部 class 的实例。默认情况下 Jackson
使用 com.fasterxml.jackson.databind.deser.BeanDeserializer
将 JSON Object
映射到给定的 class。我们可以扩展它并注册供应商来实例化对象。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Supplier;
public class JsonNestedApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule nestedModule = new SimpleModule();
nestedModule.setDeserializerModifier(new NestedBeanDeserializerModifier());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(nestedModule);
// other configuration
NestedClass nestedClass = mapper.readValue(jsonFile, NestedClass.class);
System.out.println(nestedClass);
}
}
class NestedBeanDeserializerModifier extends BeanDeserializerModifier {
private final NestedClass parent = new NestedClass();
private final Map<Class, Supplier> availableSuppliers = new HashMap<>();
public NestedBeanDeserializerModifier() {
availableSuppliers.put(NestedClass.NestedInnerClass2.class, () -> parent.new NestedInnerClass2());
availableSuppliers.put(NestedClass.NestedInnerClass3.class, () -> parent.new NestedInnerClass3());
}
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
final Supplier supplier = availableSuppliers.get(beanDesc.getBeanClass());
if (supplier != null) {
return new NestedBeanDeserializer((BeanDeserializerBase) deserializer, supplier);
}
return deserializer;
}
}
class NestedBeanDeserializer extends BeanDeserializer {
private final Supplier supplier;
protected NestedBeanDeserializer(BeanDeserializerBase src, Supplier supplier) {
super(src);
this.supplier = Objects.requireNonNull(supplier);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return super.deserialize(p, ctxt, supplier.get());
}
}
以上代码应成功反序列化 JSON
有效载荷。
如上建议:解决方案是扩展 BeanDeserializer class。
======================
供应商界面:
public interface Supplier<T> {
T get();
}
======================
BeanDeserializerModifier :
public class NestedBeanDeserializerModifier extends BeanDeserializerModifier {
private NestedClass parent = new NestedClass();
private Map<Class<?>, Supplier<?>> availableSuppliers = new HashMap<Class<?>, Supplier<?>>();
public NestedBeanDeserializerModifier() {
availableSuppliers.put(NestedClass.NestedInnerClass.class, new Supplier<NestedClass.NestedInnerClass>() {
public NestedClass.NestedInnerClass get() {
return parent.new NestedInnerClass();
}
});
availableSuppliers.put(NestedClass.NestedInnerClass2.class, new Supplier<NestedClass.NestedInnerClass2>() {
public NestedClass.NestedInnerClass2 get() {
return parent.new NestedInnerClass2();
}
});
availableSuppliers.put(NestedClass.NestedInnerClass3.class, new Supplier<NestedClass.NestedInnerClass3>() {
public NestedClass.NestedInnerClass3 get() {
return parent.new NestedInnerClass3();
}
});
}
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
final Supplier<?> supplier = availableSuppliers.get(beanDesc.getBeanClass());
if (supplier != null) {
return new NestedBeanDeserializer((BeanDeserializerBase) deserializer, supplier);
}
return deserializer;
}
}
======================
BeanDeserializer :
public class NestedBeanDeserializer extends BeanDeserializer {
private static final long serialVersionUID = 1L;
private Supplier<?> supplier;
protected NestedBeanDeserializer(BeanDeserializerBase src, Supplier<?> supplier) {
super(src);
this.supplier = requireNonNull(supplier);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return super.deserialize(p, ctxt, supplier.get());
}
private static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
}
====================
使用上面的反序列化器输出 class :
public class NestedClassFromJson {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
SimpleModule nestedModule = new SimpleModule();
nestedModule.setDeserializerModifier(new NestedBeanDeserializerModifier());
mapper.registerModule(nestedModule);
NestedClass objectNested = mapper.readValue(getPostBodyAsJSON(), NestedClassChild.class);
System.out.println(mapper.writeValueAsString(objectNested));
}
private static String getPostBodyAsJSON() {
StringBuffer postBody = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("json/testNested.json")));
while ((line = reader.readLine()) != null)
postBody.append(line);
} catch (IOException e) {
throw new RuntimeException("Issue Occured While Reading POST Body", e);
}
return postBody.toString();
}
}
我在将 ObjectMapper 用于非静态内部 class 时遇到问题。我需要创建 MixIn 才能使其工作但无法找到解决方案。下面是我的 class(我无法更改)和 MixIn,我试过了。创建此类 MixIn 需要帮助。
基础Class
public class NestedClass implements Serializable{
private static final long serialVersionUID = -4509619645418618657L;
private NestedInnerClass innerClass;
public NestedClass() {
innerClass = null;
setInnerClass(new NestedInnerClass(new NestedInnerClass2(), new NestedInnerClass3()));
}
public NestedClass(NestedClass nestedCls) {
innerClass = null;
setInnerClass(nestedCls.getInnerClass());
}
public class NestedInnerClass implements Serializable{
private static final long serialVersionUID = 9099474732768960830L;
NestedClass.NestedInnerClass2 nestedInnerClass2;
NestedClass.NestedInnerClass3 nestedInnerClass3;
public NestedInnerClass() {
super();
}
public NestedInnerClass(NestedInnerClass2 nestedInnerClass2, NestedInnerClass3 nestedInnerClass3) {
super();
this.nestedInnerClass2 = nestedInnerClass2;
this.nestedInnerClass3 = nestedInnerClass3;
}
public NestedClass.NestedInnerClass2 getNestedInnerClass2() {
return nestedInnerClass2;
}
public void setNestedInnerClass2(NestedClass.NestedInnerClass2 nestedInnerClass2) {
this.nestedInnerClass2 = nestedInnerClass2;
}
public NestedClass.NestedInnerClass3 getNestedInnerClass3() {
return nestedInnerClass3;
}
public void setNestedInnerClass3(NestedClass.NestedInnerClass3 nestedInnerClass3) {
this.nestedInnerClass3 = nestedInnerClass3;
}
}
public class NestedInnerClass2 implements Serializable{
private static final long serialVersionUID = -3451502802923307744L;
String nestedString;
HashMap<String, String> nestedHashMap = new HashMap<String, String>();
public NestedInnerClass2() {
super();
}
public NestedInnerClass2(String nestedString, HashMap<String, String> nestedHashMap) {
super();
this.nestedString = nestedString;
this.nestedHashMap = nestedHashMap;
}
public NestedInnerClass2(String nestedString) {
this.nestedString = nestedString;
}
public String getNestedString() {
return nestedString;
}
public void setNestedString(String nestedString) {
this.nestedString = nestedString;
}
public HashMap<String, String> getNestedHashMap() {
return nestedHashMap;
}
public void setNestedHashMap(HashMap<String, String> nestedHashMap) {
this.nestedHashMap = nestedHashMap;
}
}
public class NestedInnerClass3 implements Serializable{
private static final long serialVersionUID = 1799737022784300052L;
String nestedString;
public NestedInnerClass3() {
super();
}
public NestedInnerClass3(String nestedString) {
super();
this.nestedString = nestedString;
}
public String getNestedString() {
return nestedString;
}
public void setNestedString(String nestedString) {
this.nestedString = nestedString;
}
}
public NestedInnerClass getInnerClass() {
return innerClass;
}
public void setInnerClass(NestedInnerClass innerClass) {
this.innerClass = innerClass;
}
}
嵌套 Class 的子 Class :
public class NestedClassChild extends NestedClass implements Serializable, Cloneable{
private static final long serialVersionUID = 7022339501842754692L;
public NestedClassChild() {}
}
辅助Class:
public class NestedClassAssist {
public static void setNestedValues(NestedClass nestedClass, String key, String value, String nestedString)
{
if(nestedClass != null && nestedClass.getInnerClass() != null && nestedClass.getInnerClass().getNestedInnerClass2() != null)
{
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put(key, value);
nestedClass.getInnerClass().getNestedInnerClass2().setNestedHashMap(hashMap);
nestedClass.getInnerClass().getNestedInnerClass2().setNestedString(nestedString);
}
}
public static void setValue(NestedClass nestedClass, String value){
setNestedValues(nestedClass, "keyStr", value, "ABC");
}
}
转换为JSON有效载荷:
public class NestedClassToJson {
public static void main(String[] args) {
NestedClassChild nestedClassChild = new NestedClassChild();
NestedClassAssist.setValue(nestedClassChild, "12345");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
try {
mapper.writeValue(new File("json/testNested.json"),nestedClassChild);
} catch (Exception e) {
e.printStackTrace();
}
}
}
从上方生成 JSON 有效载荷 class :
{
"innerClass" : {
"nestedInnerClass2" : {
"nestedString" : "ABC",
"nestedHashMap" : {
"keyStr" : "12345"
}
},
"nestedInnerClass3" : {
"nestedString" : null
}
}
}
Class 从 JSON 反序列化:
public class NestedClassFromJson {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
NestedClass objectNested = mapper.readValue(getPostBodyAsJSON(), NestedClassChild.class);
System.out.println(mapper.writeValueAsString(objectNested));
}
private static String getPostBodyAsJSON() {
StringBuffer postBody = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("json/testNested.json")));
while ((line = reader.readLine()) != null)
postBody.append(line);
} catch (IOException e) {
throw new RuntimeException("Issue Occured While Reading POST Body", e);
}
return postBody.toString();
}
}
但是我遇到异常(虽然我有默认构造函数) :
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.test.jackson.NestedClass$NestedInnerClass]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: { "innerClass" : { "nestedInnerClass2" : { "nestedString" : "ABC", "nestedHashMap" : { "keyStr" : "12345" } }, "nestedInnerClass3" : { "nestedString" : null } }}; line: 1, column: 24] (through reference chain: com.test.jackson.NestedClassChild["innerClass"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1106)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:296)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
at com.test.jackson.NestedClassFromJson.main(NestedClassFromJson.java:21)
我试过但没有用的嵌套 MixIn:
public abstract class NestedMixIn {
@JsonCreator
public NestedMixIn(@JsonProperty("innerClass") NestedInnerClass innerClass ) {
}
public static class SourceIdInnerMixin{
@JsonCreator
public SourceIdInnerMixin(@JsonProperty("nestedInnerClass2") NestedInnerClass2 nestedInnerClass2,
@JsonProperty("nestedInnerClass3") NestedInnerClass3 nestedInnerClass3) {
}
}
}
如果我使内部 classes static ,它可以工作,但由于它是第 3 方 class,我无法更改它。
感谢您的帮助!!!
在您的示例中,我没有注意到父 class 和嵌套 class 之间的任何关系。你还提到你可以将它更改为静态并且它可以工作,所以我们需要做的就是为反序列化过程提供一个内部 class 的实例。默认情况下 Jackson
使用 com.fasterxml.jackson.databind.deser.BeanDeserializer
将 JSON Object
映射到给定的 class。我们可以扩展它并注册供应商来实例化对象。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Supplier;
public class JsonNestedApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule nestedModule = new SimpleModule();
nestedModule.setDeserializerModifier(new NestedBeanDeserializerModifier());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(nestedModule);
// other configuration
NestedClass nestedClass = mapper.readValue(jsonFile, NestedClass.class);
System.out.println(nestedClass);
}
}
class NestedBeanDeserializerModifier extends BeanDeserializerModifier {
private final NestedClass parent = new NestedClass();
private final Map<Class, Supplier> availableSuppliers = new HashMap<>();
public NestedBeanDeserializerModifier() {
availableSuppliers.put(NestedClass.NestedInnerClass2.class, () -> parent.new NestedInnerClass2());
availableSuppliers.put(NestedClass.NestedInnerClass3.class, () -> parent.new NestedInnerClass3());
}
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
final Supplier supplier = availableSuppliers.get(beanDesc.getBeanClass());
if (supplier != null) {
return new NestedBeanDeserializer((BeanDeserializerBase) deserializer, supplier);
}
return deserializer;
}
}
class NestedBeanDeserializer extends BeanDeserializer {
private final Supplier supplier;
protected NestedBeanDeserializer(BeanDeserializerBase src, Supplier supplier) {
super(src);
this.supplier = Objects.requireNonNull(supplier);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return super.deserialize(p, ctxt, supplier.get());
}
}
以上代码应成功反序列化 JSON
有效载荷。
如上建议:解决方案是扩展 BeanDeserializer class。
======================
供应商界面:
public interface Supplier<T> {
T get();
}
======================
BeanDeserializerModifier :
public class NestedBeanDeserializerModifier extends BeanDeserializerModifier {
private NestedClass parent = new NestedClass();
private Map<Class<?>, Supplier<?>> availableSuppliers = new HashMap<Class<?>, Supplier<?>>();
public NestedBeanDeserializerModifier() {
availableSuppliers.put(NestedClass.NestedInnerClass.class, new Supplier<NestedClass.NestedInnerClass>() {
public NestedClass.NestedInnerClass get() {
return parent.new NestedInnerClass();
}
});
availableSuppliers.put(NestedClass.NestedInnerClass2.class, new Supplier<NestedClass.NestedInnerClass2>() {
public NestedClass.NestedInnerClass2 get() {
return parent.new NestedInnerClass2();
}
});
availableSuppliers.put(NestedClass.NestedInnerClass3.class, new Supplier<NestedClass.NestedInnerClass3>() {
public NestedClass.NestedInnerClass3 get() {
return parent.new NestedInnerClass3();
}
});
}
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
final Supplier<?> supplier = availableSuppliers.get(beanDesc.getBeanClass());
if (supplier != null) {
return new NestedBeanDeserializer((BeanDeserializerBase) deserializer, supplier);
}
return deserializer;
}
}
======================
BeanDeserializer :
public class NestedBeanDeserializer extends BeanDeserializer {
private static final long serialVersionUID = 1L;
private Supplier<?> supplier;
protected NestedBeanDeserializer(BeanDeserializerBase src, Supplier<?> supplier) {
super(src);
this.supplier = requireNonNull(supplier);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return super.deserialize(p, ctxt, supplier.get());
}
private static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
}
====================
使用上面的反序列化器输出 class :
public class NestedClassFromJson {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.writerWithDefaultPrettyPrinter();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
SimpleModule nestedModule = new SimpleModule();
nestedModule.setDeserializerModifier(new NestedBeanDeserializerModifier());
mapper.registerModule(nestedModule);
NestedClass objectNested = mapper.readValue(getPostBodyAsJSON(), NestedClassChild.class);
System.out.println(mapper.writeValueAsString(objectNested));
}
private static String getPostBodyAsJSON() {
StringBuffer postBody = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("json/testNested.json")));
while ((line = reader.readLine()) != null)
postBody.append(line);
} catch (IOException e) {
throw new RuntimeException("Issue Occured While Reading POST Body", e);
}
return postBody.toString();
}
}