目录

JAXB将Xml和实体类相互转化的笔记

JAXB是什么?

JAXB(即Java Architecturefor XML Binding)是一个业界的标准,即是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。

使用举例

实体类

父节点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@XmlRootElement(name = "Xml")
@ApiModel("XML对象")
public class XMLEty {

    @XmlElement(name = "Header")
    private Header header;
    @XmlElement(name = "Body")
    private Body body;

    @XmlTransient
    public Header getHeader() {
        return header;
    }

    @XmlTransient
    public Body getBody() {
        return body;
    }
}

头节点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Header {
    @XmlElement(name = "b")
    String b;

    @XmlTransient
    public String getB() {
        return b;
    }
}

身体节点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Body {
    @XmlElement(name = "a")
    String a;

    @XmlTransient
    public String getA() {
        return a;
    }
}

业务逻辑(Controller)

实体类到XML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@PostMapping("/re")
public String reIndex() {
    String result = "null";
    StringWriter writer = new StringWriter();
    Header header = new Header("B-Header");
    Body body = new Body("A-Body");
    XMLEtyReq xml = new XMLEtyReq(header,body);
    Marshaller m = null;
    try {
        JAXBContext context = JAXBContext.newInstance(XMLEtyReq.class);
        m = context.createMarshaller();
        m.marshal(xml, writer);
        result = writer.toString();
    } catch (JAXBException ex) {
        ex.printStackTrace();
    }
    return result;
}

XML到实体类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@PostMapping("/")
public String index(@RequestBody JSONObject jsonObj) {
    Unmarshaller uma = null;
    Object obj = null;
    try {
        JAXBContext jc = JAXBContext.newInstance(XMLEty.class);
        uma = jc.createUnmarshaller();
        String param = jsonObj.getString("param");
        obj = uma.unmarshal(new StringReader(param));
    } catch (JAXBException e) {
        e.printStackTrace();
    }
    return ((XMLEty) obj).toString();
}

注:

  • 多层通过类的嵌套实现
  • 内部类需要定义为static
  • 使用@XmlTransient注解它会为它的target阻止绑定操作,这个target可以是一个class或者一个field或者一个method。否则会报错:JAXB 有两个名为XX的属性,类的两个属性具有相同名称XX详情点我

其他注解

  1. XmlTransient

    设置getter/setter不和xml绑定,类似ORM框架中Transient注解,

  2. XmlAccessorType

    Controls whether fields or Javabean properties are serialized by default.

    控制是否默认序列化字段或者Javabean 的属性(四种情况如下)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
        /**
         * Every getter/setter pair in a JAXB-bound class will be automatically
         * bound to XML, unless annotated by {@link XmlTransient}.
         *
         * Fields are bound to XML only when they are explicitly annotated
         * by some of the JAXB annotations.
         */
        PROPERTY,
        /**
         * Every non static, non transient field in a JAXB-bound class will be automatically
         * bound to XML, unless annotated by {@link XmlTransient}.
         *
         * Getter/setter pairs are bound to XML only when they are explicitly annotated
         * by some of the JAXB annotations.
         */
        FIELD,
        /**
         * Every public getter/setter pair and every public field will be
         * automatically bound to XML, unless annotated by {@link XmlTransient}.
         *
         * Fields or getter/setter pairs that are private, protected, or
         * defaulted to package-only access are bound to XML only when they are
         * explicitly annotated by the appropriate JAXB annotations.
         */
        PUBLIC_MEMBER,
        /**
         * None of the fields or properties is bound to XML unless they
         * are specifically  annotated with some of the JAXB annotations.
         */
        NONE
    
  3. XmlAttribute

    可以绑定属性到对应的标签

    Java代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @XmlRootElement
    @SuppressWarnings("serial")
    public class TVenueEntity implements java.io.Serializable {
    	private long venueId;
    	@XmlAttribute(name = "venueId")
    	public long getVenueId() {
    		return venueId;
    	}
    }
    

    生成的xml

    1
    2
    
    <tVenueEntity venueId="1132">
    </tVenueEntity>
    
  4. XmlElementWrpper

    当属性是集合时如List、Set、Map等,需要在外层对多个内部对象进行包装,否则序列化报错

    报错

    1
    
    [javax.xml.bind.JAXBException: class java.util.HashSet nor any of its super class is known to this context.]
    

    Java代码

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    @XmlRootElement
    @SuppressWarnings("serial")
    public class TVenueEntity implements java.io.Serializable {
    	private List<long> venueIds;
    	@XmlElementWrpper(name="venueIds")
    	@XmlElement(name = "venueId")
    	public long getVenueId() {
    		return venueId;
    	}
    }
    

    生成的XML

    1
    2
    3
    4
    5
    6
    7
    
    <tVenueEntity>
        <venueIds>
            <venueId>1</venueId>
            <venueId>2</venueId>
            <venueId>3</venueId>
        </venueIds>
    </tVenueEntity>