java - 使用 Jackson 将 Json 反序列化为其他类层次结构

标签 java json serialization jackson deserialization

现在我正在与 Jackson 合作,我对此有一些疑问。

首先。我有两个服务,第一个是数据收集和发送服务,第二个是接收这些数据,例如,将其记录到一个文件中。

所以,第一个服务的类层次结构如下:

         +----ConcreteC
         |
Base ----+----ConcreteA
         |
         +----ConcreteB

第二个服务的类层次结构如下:

ConcreteAAdapter extends ConcreteA implements Adapter {}
ConcreteBAdapter extends ConcreteB implements Adapter {}
ConcreteCAdapter extends ConcreteC implements Adapter {}

第一个服务对ConcreteXAdapter一无所知。

我在第一个服务上发送数据的方式:

Collection<Base> data = new LinkedBlockingQueue<Base>()
JacksonUtils utils = new JacksonUtils();
data.add(new ConcreteA());
data.add(new ConcreteB());
data.add(new ConcreteC());
...
send(utils.marshall(data));
...

public class JacksonUtils {

    public byte[] marshall(Collection<Base> data) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream() {
            @Override
            public byte[] toByteArray() {
                return buf;
            }
        };

        getObjectMapper().writeValue(out, data);
        return out.toByteArray();
    }
    protected ObjectMapper getObjectMapper() {
        return new ObjectMapper();
    }

    public Object unmarshall(byte[] json) throws IOException {
        return getObjectMapper().readValue(json, Object.class);
    }

    public <T> T unmarshall(InputStream source, TypeReference<T> typeReference) throws IOException {
        return getObjectMapper().readValue(source, typeReference);
    }

    public <T> T unmarshall(byte[] json, TypeReference<T> typeReference) throws IOException {
        return getObjectMapper().readValue(json, typeReference);
    }
}

所以,我想将 json 反序列化为 ConcreteXAdapter 的集合,而不是 ConcreteX 的集合(ConcreteA -> ConcreteAAdapter, ConcreteB -> ConcreteBAdapter, ConcreteC -> 具体CAdapter)。在我描述的情况下,我想得到:

Collection [ConcreteAAdapter, ConcreteBAdapter, ConcreteCAdapter]

我该怎么做?

最佳答案

为此,您需要在 JSON 中传递附加信息:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, 
      include=JsonTypeInfo.As.PROPERTY, property="@type")
class Base {
...
}

然后在序列化时会添加@type 字段:

objectMapper.registerSubtypes(
            new NamedType(ConcreteAAdapter.class, "ConcreteA"),
            new NamedType(ConcreteBAdapter.class, "ConcreteB"),
            new NamedType(ConcreteCAdapter.class, "ConcreteC")
            );

// note, that for lists you need to pass TypeReference explicitly
objectMapper.writerWithType(new TypeReference<List<Base>>() {})
     .writeValueAsString(someList);


    {
      "@type" : "ConcreteA",
      ...
    }

在反序列化时它将是:

    objectMapper.registerSubtypes(
            new NamedType(ConcreteA.class, "ConcreteA"),
            new NamedType(ConcreteB.class, "ConcreteB"),
            new NamedType(ConcreteC.class, "ConcreteC")
            );
    objectMapper.readValue(....)

More info here

关于java - 使用 Jackson 将 Json 反序列化为其他类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10329706/

相关文章:

java - Java 上的 256 位输出哈希函数

java - Apache CXF 客户端解码响应

C# Xml-使用 IXmlSerializable 序列化派生类

C++ json反序列化器

json - 未调用 WebApi 自定义 JsonConverter

c++ - 使用什么作为缓冲区流的分隔符

java - 如何获取日期时间选择器的值?

java - ArrayList for 循环迭代器导致无限循环

java - 如何在activiti中设置 boolean 字段

php - 在客户端使用 JSON 获取 fb 访问 token