叶凡网络:GlassFish 4 中EclipseLink MOXY实现REST应用简介

2013-11-28 10:10:11 | 新闻来源:叶凡网络 | 点击量:923

这是符合JSON格式规范的输出了读者可以进一步通过http://www.eclipse.org/eclipselink/moxy.php访问更多关于MOXY项目的情况,可见。也可以关注http://blog.bdoughan.com/博客以了解更多关于MXOY项目的用法。

Eclips旗下的EclipseLink开源项目向JA VEEE7中贡献了不少力量,其中包括JPA 2.1JSR-338实现,另外一个贡献是本文向大家介绍的EclipseLinkMOXy项目,JA VEEE7中JA X-RSREST规范)一个默认的JSONProvid最近,随着JA VA EE7规范的最终落地,其中Oracl还发布了GlassFish4服务器,可以说是JA VA EE7规范的一种参考实现。其中。

主要用来实现快速将JA VA 中的对象转化为各种类型的XML该项目主要有如下的特性:首先简单介绍下Eclips旗下的EclipseLink开源项目.

   支持JA XB中最多的注解

   同时支持XML和JSON

   支持最新的JPA 2.1

对JPA -RS增强支持

MOXY可以用来实现JA X-RS规范中的各种转换,MOXY有十分强大的将各类JA VA 对象 序列化为XML以及XML反序列化为JA VA 对象的能力。这在REST架构的应用中。下面以一个REST例子进行讲解。如果读者对REST和JA X-RS规范有不清楚的地方,请参考相关的资料。

代码如下:设计一个最简单的HelloWorldRESTWebservic其中Custom对象是一个简单的POJO对象。

   packagorg.example.service;

 

   importjavax.ejb.*;

   importjavax.ws.rs.*;

   importjavax.ws.rs.core.MediaType;

   importorg.example.model.*;

 

   @Stateless

   @LocalBean

   @Path"/customers"

   publicclassCustomerServic{

 

       @GET

       @Produc{

           MediaType.A PPLICA TION_XML.

           MediaType.A PPLICA TION_JSON

       }

       @Path"{id}"

       publicCustomread@PathParam"id"intid{

           Customcustom=newCustom;

           customer.setIdid;

           customer.setNam"JaneDoe";

 

           PhoneNumbpn=newPhoneNumb;

           pn.setTyp"work";

           pn.setValu"5551111";

           customer.getPhoneNumb.addpn;

 

           returncustomer;

        }

 

   }

用注解可以看到,Custom对象中有一个PhoneNumb表示电话号码的Pojo代码中的注解都是遵守JA X-RS规范的REST相关的注解。其中。

用如下的方式,@MediaType.A PPLICA TION_XML和@MediaType.A PPLICA TION_JSON分别指出该REST会同时以XML和JSON形式对外发布。而在JA X-RS规范中。就可以实现REST对外发布安排:

    packagorg.example.service;

 

   importjavax.ws.rs.A pplicationPath;

   importjavax.ws.rs.core.A pplication;

 

   @A pplicationPath"rest/*"

   publicclassCustomerA pplication extendApplicat{

 

   }

@A pplicationPath注解指定所有服务的相对基址,其中。如果为空字符串,则直接使用上下文根路径。上面表示这个REST服务将以如http://localhost/rest/xxx形式对外发布,应该的根为rest

 接下来我具体看Custom这个POJO代码如下:

   packagorg.example.model;

 

   importjava.util.*;

   importjavax.xml.bind.annotation.*;

 

   @XmlRootElement

   publicclassCustom{

 

       privatintid;

       privatStringname;

       privatList<PhoneNumber>phoneNumb=newArrayList<PhoneNumber>;

 

       publicintgetId{

           returnid;

       }

 

       publicvoidsetIdintid{

           this.id=id;

       }

 

       publicStringgetNam{

           returnname;

       }

 

       publicvoidsetNamStringname{

           this.nam=name;

       }

 

       @XmlElementWrapp

       @XmlElementname="phoneNumber"

       publicList<PhoneNumber>getPhoneNumb{

           returnphoneNumbers;

       }

 

   }

其中坚持了对另外一个对象phoneNumb引用。使用@XmlElementWrapp其目的为了XML中通过单独设置名为phoneNumb别名标签去这个Custom对象中。

更清晰的输出。

代码如下: 接下来请看PhoneNumb类。

   packagorg.example.model;

 

   importjavax.xml.bind.annotation.*;

 

   publicclassPhoneNumb{

 

       privatStringtype;

       privatStringvalue;

 

       @XmlA ttribut

       publicStringgetTyp{

           returntype;

       }

 

       publicvoidsetTypStringtype{

           this.typ=type;

       }

 

       @XmlValu

       publicStringgetValu{

           returnvalue;

       }

 

       publicvoidsetValuStringvalu{

           this.valu=value;

       }

 

   }

其中使用了注解@XmlA ttribut将type设置为转换后XML中的一个属性,注意。而@XmlValu则将字段valu直接序列为值,即如下的样子:

   <?xmlversion="1.0"encoding="UTF-8"?>

   <phone-numbtype="work">555-1234</phone-number> 

则输出的XML为: 如果不使用@XmlValu注解。

   <phone-numbertypephone-numbertype="work">

     <value>12345</value>

   </phone-number> 

尝试调用这个服务。下面是调用的urlhttp://localhost:8080/CustomerResource/rest/customers/1,接下来。则返回的XML为:

   <?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>

   <customid="1">

       <name>JanDoe</name>

       <phoneNumbers>

           <phoneNumbtype="work">5551111</phoneNumber>

       </phoneNumbers>

   </customer>

因为对象是以JA XB规范去注解的可以通过REST返回XML如果在GlassFish3.1.2时候,这个并不奇怪。Moxi还不是默认的JSONProvid有如下的几点值得注意:

     POJO中的id属性如果是int类型的会以JSONtext类型返回

其实持有的List<PhoneNumber>但在转变为JSON时变为JSON对象而不是一个JSON数组,   custom对象中的phoneNumb属性。如下:

       {

 

           "id":"1".

 

           "name":"JaneDoe".

 

           "phoneNumbers":{

 

               "phoneNumber":{

 

                   "@type":"work".

                 "$":"5551111" 

               }

           } 

       }

转变成JSON后,更奇怪的由于使用了@XmlA ttribut注解和@XmlValu注解。会分别变成@type$显的不合理。而在最新的GlassFish4中,上面的问题已经得到明显改善,输出的JSON如下:

       "id":1.

 

       "name":"JaneDoe".

 

       "phoneNumbers":{

 

           "phoneNumber":[

 

               "@type":"work".

 

               "$":"5551111"

           ]

       }

   }

因此在序列化为JSON后依然为String类型。但熟悉JSON朋友应该清楚,phoneNumb这里依然没能转换为最标准的JSON格式,但我可以使用JA X-RS中的ContextResolv机制,并使用MXOY中MOXyJsonConfig类去自定义JSON格式的显示,代码如下:GlassFish4中,能够正确将POJO中的如int类型的正确序列化为JSON中的整形,即“id:1,注意到PhoneNumb类中的valu属性由于是String类型。

   packagorg.example.service;

 

   importjavax.ws.rs.ext.*;

   importorg.eclipse.persistence.jaxb.JA XBContextProperties;

   importorg.glassfish.jersey.moxy.json.MoxyJsonConfig;

 

   @Provid

   publicclassMOXyJsonContextResolvimplementContextResolver<MoxyJsonConfig>{

 

       privatfinalMoxyJsonConfigconfig;

 

       publicMOXyJsonContextResolv{

           config=newMoxyJsonConfig

               .setA ttributePrefix""

               .setValueWrapp"value"

true;               .propertiJA XBContextProperties.JSON_WRA PPER_A S_A RRA Y_NA ME.

       }

 

       @Overrid

       publicMoxyJsonConfiggetContextClass<?>objectTyp{

           returnconfig;

       }

 

   }

通过MoxyJsonConfig类中的setValueWrapp方法,其中。重新设置了使用原来POJO中的字段名作为JSONkei因此就不带任何多余的符号了生成的XML如下:

   {

       "id":1.

       "name":"JaneDoe".

       "phoneNumbers":[

           {

               "type":"work".

               "value":"5551111"

           }

       ]

   }

上一篇:叶凡网络:中国周边空域已被完全监控:日战机5分钟可升空 下一篇:叶凡网络:31省市区超八成设7至8名副省长 各级政府领导职数弹性较大