需要使用ObjectMapper-Java6对非静态内部类进行MixIn解析
我在为非静态内部类使用ObjectMapper时遇到了一个问题。我需要创建MixIn使其工作,但无法找到解决方案。下面是我的课程(我无法更改)和我尝试过的混音。创建这样的MixIn需要帮助 ============================ 基类需要使用ObjectMapper-Java6对非静态内部类进行MixIn解析,java,json,jackson,mixins,objectmapper,Java,Json,Jackson,Mixins,Objectmapper,我在为非静态内部类使用ObjectMapper时遇到了一个问题。我需要创建MixIn使其工作,但无法找到解决方案。下面是我的课程(我无法更改)和我尝试过的混音。创建这样的MixIn需要帮助 ============================ 基类 public class NestedClass implements Serializable{ private static final long serialVersionUID = -450961964541861865
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;
}
}
=================================
助教班:
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负载:
{
"innerClass" : {
"nestedInnerClass2" : {
"nestedString" : "ABC",
"nestedHashMap" : {
"keyStr" : "12345"
}
},
"nestedInnerClass3" : {
"nestedString" : null
}
}
}
=================================
要从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();
}
}
=================================
但我得到以下例外(尽管我有默认构造函数):
=================================
我尝试过但不起作用的嵌套混音器:
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) {
}
}
}
==========================
如果我将内部类设置为静态,它可以工作,但是因为它是第三方类,所以我无法更改它
谢谢你的帮助 在您的示例中,我没有注意到父类和嵌套类之间的任何关系。您还提到,您可以将其更改为静态,并且可以正常工作,所以我们需要做的就是为反序列化过程提供一个内部类的实例。默认情况下,
Jackson
使用com.fasterxml.Jackson.databind.desr.beandSerializer
将JSON对象
映射到给定的类。我们可以扩展它并注册供应商来实例化对象
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());
}
}
import com.fasterxml.jackson.core.JsonParser;
导入com.fasterxml.jackson.databind.BeanDescription;
导入com.fasterxml.jackson.databind.DeserializationConfig;
导入com.fasterxml.jackson.databind.DeserializationContext;
导入com.fasterxml.jackson.databind.JsonDeserializer;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.desr.beand序列化程序;
导入com.fasterxml.jackson.databind.desr.beanderbase;
导入com.fasterxml.jackson.databind.desr.beandSerializerModifier;
导入com.fasterxml.jackson.databind.module.SimpleModule;
导入java.io.File;
导入java.io.IOException;
导入java.io.Serializable;
导入java.util.HashMap;
导入java.util.Map;
导入java.util.Objects;
导入java.util.StringJoiner;
导入java.util.function.Supplier;
公共类JsonNestedApp{
公共静态void main(字符串[]args)引发异常{
File jsonFile=新文件(“./resource/test.json”).getAbsoluteFile();
SimpleModule nestedModule=新SimpleModule();
setDeserializerModifier(新的NestedBeandSerializerModifier());
ObjectMapper mapper=新的ObjectMapper();
映射器注册表模块(嵌套模块);
//其他配置
NestedClass NestedClass=mapper.readValue(jsonFile,NestedClass.class);
System.out.println(嵌套类);
}
}
类NestedBeandSerializerModifier扩展了BeanDeserializerModifier{
私有最终NestedClass父级=新NestedClass();
private final Map AvailablesSuppliers=新HashMap();
公共嵌套BeanDeserializerModifier(){
AvailablesSuppliers.put(NestedClass.NestedInnerClass2.class,()->parent.new NestedInnerClass2());
AvailablesSuppliers.put(NestedClass.NestedInnerClass3.class,()->parent.new NestedInnerClass3());
}
@凌驾
公共JsonDeserializer modifyDeserializer(反序列化配置、BeanDescription BeanDeserializer、JsonDeserializer反序列化程序){
final Supplier suppliers=availableSuppliers.get(beanDesc.getBeanClass());
如果(供应商!=空){
返回新的嵌套BeanDeserializer((BeanDeserializerBase)反序列化程序,供应商);
}
返回反序列化器;
}
}
类NestedBeandSerializer扩展了BeanDeserializer{
私人最终供应商;
受保护的嵌套BeanDeserializer(BeanDeserializerBase src,供应商){
超级(src);
this.supplier=Objects.requirennull(供应商);
}
@凌驾
公共对象反序列化(JSONP,反序列化上下文ctxt)引发IOException{
返回super.deserialize(p,ctxt,supplier.get());
}
}
上面的代码应该成功地反序列化
JSON
有效负载。如上所述:解决方案是扩展BeanDeserializer类
======================
供应商接口:
public interface Supplier<T> {
T get();
}
您还可以显示您想要反序列化的
JSON
负载吗?@MichałZiober:谢谢您的回复。请注意,我创建了这个伪JSON和上面的java来解释这个场景,因为我无法共享我面临此类问题的实际代码。我已经为你的问题编辑了这个问题。“嵌套的非静态内部”是一个双重重言式。”“内部”就足够了。@user207421:谢谢。更新的问题,你能建议解决方案吗?非常感谢。因为您发布了Java8代码,所以我将其转换为Java6并进行了尝试,结果成功了。
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) {
}
}
}
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());
}
}
public interface Supplier<T> {
T get();
}
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;
}
}
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;
}
}
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();
}
}