Introduction to JAXB (1)

从Hearbeat说起

公司的运营部门要求所有上线的component有个链接,进行heartbeat检测。

要求如下:

  1. 提供一个http url
  2. 这个http url 返回xml来显示server的状态,格式如下

heartbeat需要check哪些内容(db/io/thread/cpu/memory/file handler...),这里不作讨论。我看过的code中,有以下实现:

  • 打开一个socket端口(非web app),如果系统自检 ok, 返回一个OK的xml字符串。如果自检失败,返回fail的xml字符串。

  • 定义一个servlet(web app),其他同上。
  • 为heartbeat定义一个wsdl(web app, deploy in axis2 aar ), 提供一个heartbeat service,比如:

http://host/app/UserService (domain service) 
http://host/app/HeartbeatService (heartbeat service)

  • 使用axis2的RawXMLINOutMessageReceiver或者AbstractInOutMessageReceiver(web app, deploy in axis2 aar),定义一个POJOs的service, 返回OMElement(可以从xml转换得到)。本质和3相同,不过是少了wsdl

 

    按照生成xml的方法,上面四种方式归结为3种

    1. raw string
    2. 定义xsd
    3. 使用DOM Tree (OMElement)。使用DOM Tree给人的感觉和raw string没啥区别。

      这里就出现了JAXB的第一个应用场景: 需要生成xml,xml相对简单:定义xsd有大材小用之嫌,代码中字符串拼接又太ugly。

      什么是JAXB

      Java Architecture for XML Binding(JAXB) 是一种OX(object <-> xml mapping)工具。主要提供了两个功能:将 java对象编码序列化(marshal)成xml,或者反之,从xml反序列化到java对象。一图以蔽之:

      • xml schema 与 classes(interfaces) 之间的相互转换(为下面的转换做铺垫)
      • xml document 和 instance object 之间的相互转换

      xml是比java,c++, python...等编程语言更通用的描述语言,从语言相互翻译的角度而言,上面两种映射天然如此。

       

      序列化任意java对象

      回到本文开头heartbeat xml生成的问题,

      • 首先定义HeartBeat类,包含status。selfCheck方法检测server的各种状态,这里仅仅是sample stub code,直接返回一个HeartBeat

       

      • 使用JAXB将HeartBeat实例对象marshal成xml

       

      • 生成的xml如下

       

      说明:

      Status被定义成static inner class而不是inner class,否则会报错is a non-static inner class, and JAXB can’t handle those.

      JAXBElement中Qname的local part为admin,因为xml的root elment从admin开始

       


      在上面的例子中,Heartbeat类定义上未加任何的annotation,就直接被JAXB marshal。理论上,我们可以仿照上一篇A generic JAXB marshal/unmarshal XmlType中的泛型方法定义,将marshal方法定义成一个可marhal任意java对象的通用方法。不过在实际中,我们很少直接handle未加任何jaxb annotation的对象,主要有循环引用,内部类等问题。

       

      上面的例子可以看出jaxb相当简单易用(点此从一个实例看jaxb的强大),秉承JDK API的一贯风格。

      XJC:schema -> java

      如果遵循contract first的原则,在解决与xml相关的问题时,schema first.

      • 首先定义heartbeat的schema如下(由xml->xsd在线工具得到):

      • 使用xjc(jdk工具,与java/javac在同一目录,在CMD命令窗口可直接使用),生成java类:xjc heartbeat.xsd

      Admin

       

       

      ObjectFactory


       

      • 使用jaxb,将admin marshal。比前面少了两行new JAXBElement对象的代码

       

       

      class定义中使用的Annotation和xml schema定义一一对应,说明如下:

       

      @XmlRootElement(name = "admin")


      //xml 文档根节点

      <xsd:element name="admin">

      @XmlAccessorType(XmlAccessType.FIELD)

      @XmlType(name = "", propOrder = {

      "status"

      })

      @XmlElement(required = true)

      protected List<Admin.Status> status;


      //nested 的complexType,所以XmlType的name为空;有Order indicator 

      sequence,所以有propOrder来指定序列化顺序

      //maxOccurs为unbounded,所以status定义为List,默认minOccurs为1,所以添加了required = true

       

      //XmlAccessorType 表明了哪些field需要被序列化。


       

       

      <xsd:complexType>
           <xsd:sequence>

                <xsd:element maxOccurs="unbounded" name="status">

      @XmlAccessorType(XmlAccessType.FIELD)

      @XmlType(name = "", propOrder = {

      "name",

      "value"

      })

       

      //同上

                   <xsd:complexType>

                     <xsd:sequence>

                        <xsd:element name="name" type="xsd:int" />

                        <xsd:element name="value" type="xsd:int" />

                     </xsd:sequence>

                   </xsd:complexType>

                </xsd:element>

          </xsd:sequence>

      </xsd:complexType>

       

      </xsd:element>

      schemagen:java -> schema

      如果你习惯先写java class,或者已经有很多写好的java code(有没有jaxb annotation都成)。schemagen(同xjc,jdk工具)是帮助你快速定义schema的不二选择。

       

      对上面生成的Admin.java使用schemagen(schemagen Admin.java),生成的schema和前面的定义一模一样

       

      • 0
        点赞
      • 1
        收藏
        觉得还不错? 一键收藏
      • 打赏
        打赏
      • 0
        评论

      “相关推荐”对你有帮助么?

      • 非常没帮助
      • 没帮助
      • 一般
      • 有帮助
      • 非常有帮助
      提交
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包

      打赏作者

      FireCoder

      你的鼓励将是我创作的最大动力

      ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
      扫码支付:¥1
      获取中
      扫码支付

      您的余额不足,请更换扫码支付或充值

      打赏作者

      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值