需要使用ObjectMapper-Java6对非静态内部类进行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

我在为非静态内部类使用ObjectMapper时遇到了一个问题。我需要创建MixIn使其工作,但无法找到解决方案。下面是我的课程(我无法更改)和我尝试过的混音。创建这样的MixIn需要帮助

============================

基类

    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();
    }
}