JAXB复杂对象反序列化

发布于:2025-02-20 ⋅ 阅读:(128) ⋅ 点赞:(0)

记录一次jaxb反序列化的使用,只是简单快速上手使用

一、xml文本

<InputProxyChannelStatusList version="1.0" xmlns="http://www.std-cgi.com/ver20/XMLSchema">
   <InputProxyChannelStatus version="1.0">
       <id>6</id>
       <sourceInputPortDescriptor>
           <proxyProtocol>HIKVISION</proxyProtocol>
           <addressingFormatType>ipaddress</addressingFormatType>
           <ipAddress>11</ipAddress>
           <managePortNo>11</managePortNo>
           <srcInputPort>1</srcInputPort>
           <userName>11</userName>
           <cameraType>none</cameraType>
           <streamType>auto</streamType>
           <deviceID></deviceID>
       </sourceInputPortDescriptor>
       <online>true</online>
   </InputProxyChannelStatus>
   <InputProxyChannelStatus version="1.0">
       <id>8</id>
       <sourceInputPortDescriptor>
           <proxyProtocol>HIKVISION</proxyProtocol>
           <addressingFormatType>ipaddress</addressingFormatType>
           <ipAddress>11</ipAddress>
           <managePortNo>11</managePortNo>
           <srcInputPort>1</srcInputPort>
           <userName>11</userName>
           <cameraType>none</cameraType>
           <streamType>auto</streamType>
           <deviceID></deviceID>
       </sourceInputPortDescriptor>
       <online>true</online>
   </InputProxyChannelStatus>
</InputProxyChannelStatusList>

二、对应的java对象

根据xml内容的层次关系定义对象

  • InputProxyChannelStatusListDTO
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "InputProxyChannelStatusList",namespace = "http://www.std-cgi.com/ver20/XMLSchema")
public class InputProxyChannelStatusListDTO implements Serializable {


    @XmlAttribute
    private String version;

    @XmlElement(name = "InputProxyChannelStatus", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private List<InputProxyChannelStatusDTO> InputProxyChannelStatus;

}
  • InputProxyChannelStatusDTO
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class InputProxyChannelStatusDTO implements Serializable {


    @XmlAttribute
    private String version;

    @XmlElement(name = "id",namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private Integer id;
    @XmlElement(name = "sourceInputPortDescriptor",namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private SourceInputPortDescriptorDTO sourceInputPortDescriptor;
    @XmlElement(name = "online",namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private boolean online;


}
  • SourceInputPortDescriptorDTO
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class SourceInputPortDescriptorDTO implements Serializable {


    @XmlElement(name = "proxyProtocol", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String proxyProtocol;
    @XmlElement(name = "addressingFormatType", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String addressingFormatType;
    @XmlElement(name = "ipAddress", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String ipAddress;
    @XmlElement(name = "managePortNo", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private int managePortNo;
    @XmlElement(name = "srcInputPort", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private int srcInputPort;
    @XmlElement(name = "userName", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String userName;
    @XmlElement(name = "cameraType", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String cameraType;
    @XmlElement(name = "streamType", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String streamType;
    @XmlElement(name = "deviceID", namespace = "http://www.std-cgi.com/ver20/XMLSchema")
    private String deviceID;
}

三、序列化和反序列代码

    public static void main(String[] args) throws Exception{
        String xmlStr="";
        final JAXBContext jaxbContext = JAXBContext.newInstance(InputProxyChannelStatusListDTO.class);
        final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        final StringReader stringReader = new StringReader(xmlStr);


        final InputProxyChannelStatusListDTO unmarshal = (InputProxyChannelStatusListDTO)unmarshaller.unmarshal(stringReader);

        System.out.println(unmarshal);

        final StringWriter stringWriter = new StringWriter();
        final Marshaller marshaller = jaxbContext.createMarshaller();
        //格式化
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        //编码
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        //是否省略xml头信息
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); 
        marshaller.marshal(unmarshal, stringWriter);


        System.out.println(stringWriter.toString());

    }

四、注意要点

1、相信发现了,有个地方特别繁琐,就是每个元素的命名空间,在我使用的版本里边,每个元素都必须写上 namespace = “”,如果根节点不写会报错
意外的元素 (uri:"http://www.std-cgi.com/ver20/XMLSchema", local:"InputProxyChannelStatusList")。所需元素为<{}InputProxyChannelStatusList>
节点元素不写返回的值就是空,目前没有去深究,有些教程上边用的时全局处理注解,这里懒得处理,先用着。
2、另外就是jdk1.8带有jaxb,后续版本可能需要引入依赖,自己选择依赖版本,这里先展示一个,如果有问题可以自行查找可用依赖

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.1</version>
</dependency>