当前位置: 首页 > 面试题库 >

EclipseLink MOXy JSON序列化

堵宪
2023-03-14
问题内容

我有一个示例课:

class Zoo {
    public Collection<? extends Animal> animals;
}

当用MOXy序列化时,我得到:

{
    "bird": [
        {
            "name": "bird-1",
            "wingSpan": "6 feets",
            "preferredFood": "food-1"
        }
    ],
    "cat": [
        {
            "name": "cat-1",
            "favoriteToy": "toy-1"
        }
    ],
    "dog": [
        {
            "name": "dog-1",
            "breed": "bread-1",
            "leashColor": "black"
        }
    ]
}

为什么鸟,猫和狗不是数组,为什么使用数组指示符“ []”?第二,是否有摆脱“鸟”,“猫”和“狗”的方法?

换句话说,我试图到达:

{
        {
            "name": "bird-1",
            "wingSpan": "6 feets",
            "preferredFood": "food-1"
        }
    ,
        {
            "name": "cat-1",
            "favoriteToy": "toy-1"
        }
    ,
        {
            "name": "dog-1",
            "breed": "bread-1",
            "leashColor": "black"
        }
}

谢谢,Behzad


问题答案:

问题#1

为什么鸟,猫和狗不是数组,为什么使用数组指示符“ []”?

为了获得此JSON表示,您已经将模型与@XmlElementRef注释映射,该注释告诉JAXB使用@XmlRootElement注释的值作为继承指示符。使用MOXy的JSON绑定,这些就成为了关键。因为不允许重复键,所以我们将这些键的值设为JSON数组。

动物园

在模型中@XmlElementRef,您的animals字段/属性上具有注释。

import java.util.Collection;
import javax.xml.bind.annotation.XmlElementRef;

class Zoo {
    @XmlElementRef
    public Collection<? extends Animal> animals;
}

动物

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Bird.class, Cat.class, Dog.class})
public abstract class Animal {

    private String name;

}

在每个子类上都有一个@XmlRootElement注释。

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Bird extends Animal {

    private String wingSpan;
    private String preferredFood;

}

input.json /输出

{
   "bird" : [ {
      "name" : "bird-1",
      "wingSpan" : "6 feets",
      "preferredFood" : "food-1"
   } ],
   "cat" : [ {
      "name" : "cat-1",
      "favoriteToy" : "toy-1"
   } ],
   "dog" : [ {
      "name" : "dog-1",
      "breed" : "bread-1",
      "leashColor" : "black"
   } ]
}

想要查询更多的信息

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html

问题2

第二,是否有摆脱“鸟”,“猫”和“狗”的方法?

您将需要某种继承指示器来表示各种子类。

选项#1-@XmlDescriminatorNode/@XmlDescriminatorValue

在这里,我使用MOXy的@XmlDescriminatorNode/ @XmlDescriminatorValue注释进行此操作。

动物园

import java.util.Collection;

class Zoo {
    public Collection<? extends Animal> animals;
}

动物

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Bird.class, Cat.class, Dog.class})
@XmlDiscriminatorNode("@type")
public abstract class Animal {

    private String name;

}

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;

@XmlDiscriminatorValue("bird")
public class Bird extends Animal {

    private String wingSpan;
    private String preferredFood;

}

input.json /输出

{
   "animals" : [ {
      "type" : "bird",
      "name" : "bird-1",
      "wingSpan" : "6 feets",
      "preferredFood" : "food-1"
   }, {
      "type" : "cat",
      "name" : "cat-1",
      "favoriteToy" : "toy-1"
   }, {
      "type" : "dog",
      "name" : "dog-1",
      "breed" : "bread-1",
      "leashColor" : "black"
   } ]
}

想要查询更多的信息

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-moxy-extension.html

选项#2-@XmlClassExtractor

ClassExtractor(AnimalExtractor)

您可以编写一些代码,这些代码将根据JSON内容确定适当的子类。

import org.eclipse.persistence.descriptors.ClassExtractor;
import org.eclipse.persistence.sessions.*;

public class AnimalExtractor extends ClassExtractor {

    @Override
    public Class extractClassFromRow(Record record, Session session) {
        if(null != record.get("@wingSpan") || null != record.get("@preferredFood")) {
            return Bird.class;
        } else if(null != record.get("@favoriteToy")) {
            return Cat.class;
        } else {
            return Dog.class;
        }
    }

}

动物

@XmlClassExtractor注释用于指定ClassExtractor

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlClassExtractor;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Bird.class, Cat.class, Dog.class})
@XmlClassExtractor(AnimalExtractor.class)
public abstract class Animal {

    private String name;

}

由于MOXy处理@XmlElement@XmlAttribute批注的方式,您想要使可用的任何数据ClassExtractor都需要使用批注@XmlAttribute

import javax.xml.bind.annotation.XmlAttribute;

public class Bird extends Animal {

    @XmlAttribute
    private String wingSpan;

    @XmlAttribute
    private String preferredFood;

}

input.json /输出

{
   "animals" : [ {
      "wingSpan" : "6 feets",
      "preferredFood" : "food-1",
      "name" : "bird-1"
   }, {
      "favoriteToy" : "toy-1",
      "name" : "cat-1"
   }, {
      "breed" : "bread-1",
      "leashColor" : "black",
      "name" : "dog-1"
   } ]
}

想要查询更多的信息

  • http://blog.bdoughan.com/2012/02/jaxb-and-inheritance-eclipselink-moxy.html

演示代码

以下演示代码可与上述两个映射一起使用。

import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Zoo.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum14210676/input.json");
        Zoo zoo = unmarshaller.unmarshal(json, Zoo.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(zoo, System.out);
    }

}


 类似资料:
  • 我正在尝试使用kryo序列化和反序列化到二进制。我想我已经完成了序列化,但似乎无法反序列化。下面是我正在处理的代码,但最终我想存储一个字节[],然后再次读取它。文档只显示了如何使用文件。

  • 问题内容: 我尝试过在Java和Android之间实现跨平台序列化。我使用了Serializable,并将我的代码在Android中与台式机Java放在同一软件包中。 来源:java-desktop序列化 资料来源:Android-反序列化 学生是一类,实现了Serializable。在桌面上,我将学生实例序列化为“ thestudent.dat”。我将此文件放在Android设备上的SD卡上,并

  • 问题内容: 我注意到存储在Redis中的某些序列化对象在反序列化方面遇到问题。 当我对Redis中存储的对象类进行更改时,通常会发生这种情况。 我想了解问题,以便为解决方案设计一个清晰的方案。 我的问题是,什么导致反序列化问题?移除公共/私人财产会引起问题吗?也许添加新属性?向类添加新功能会产生问题吗?那么更多的构造函数呢? 在我的序列化对象中,我有一个属性Map,如果我更改(更新了一些属性,添加

  • 问题内容: Golang中将结构序列化和反序列化为字符串的最佳方法(完整性和性能)是什么,反之亦然? 例如,如果我有这个结构: 我想将其存储在Redis上并取回。我试过保存,整型和字符串,这很好,但是如何存储结构对象? 问题答案: 使用gob和base64可以解决问题,例如: 当您需要序列化自定义结构或类型(例如struct)时,只需添加以下行:

  • 主要内容:1 Java序列化和反序列化,2 Java序列化的优点,3 java.io.Serializable接口,4 Java ObjectOutputStream,5 Java ObjectInputStream,6 Java序列化的例子,7 Java反序列化的例子1 Java序列化和反序列化 Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate,RMI,JPA,EJB和JMS技术。 序列化的反向操作称为反序列化,其中字节流被转换为对象。序列化和反序列化过程与平台

  • FAQs in section [36]: [36.1]“序列化”是什么东东? [36.2] 如何选择最好的序列化技术? [36.3] 如何决定是要序列化为可读的(“文本”)还是不可读的(“二进制”)格式? or non-human-readable ("binary") format?") [36.4] 如何序列化/反序列化数字,字符,字符串等简单类型? [36.5] 如何读/写简单类型为可读的

  • 上一小节我们学习了 Java 的输入输出流,有了这些前置知识点,我们就可以学习 Java 的序列化了。本小节将介绍什么是序列化、什么是反序列化、序列化有什么作用,Serializable 接口以及 Externalizable 接口,常用序列化工具介绍等内容。 1. 序列化与反序列化 序列化在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式,以留待后续在相同或另一台计算机环境中,能

  • 通常情况下,这种形式是基于文本的,它被用来发送Django的数据,当然,序列化处理的形式也有例外(基于文本或者相反)。 参见 如果您只是想从表中获取一些数据到序列化形式,可以使用dumpdata管理命令。 序列化数据 从最高层面来看,序列化数据是一项非常简单的操作 from django.core import serializers data = serializers.serialize("x