`
mj4d
  • 浏览: 300181 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAX-WS:背后的技术JAXB及传递Map

阅读更多

接上文JAX-WS:创建简单的webservice,JAX-WS对大部分复杂对象传递都能直接支持。在服务端传递了自定义的复杂对象Person:

public class Person implements Serializable {
    private static final long serialVersionUID = 8336803120311071811L;

    private String            username;
    private Date              birthday;
    private List<Address>     addresses;
//getter/setter

我们来看看根据wsimport生产的客户端中Person的定义:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "person", propOrder = {
    "addresses",
    "birthday",
    "username"
})
public class Person {

    @XmlElement(nillable = true)
    protected List<Address> addresses;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar birthday;
    protected String username;
//getter/setter
}

在生产的客户端代码中多了很多annotation声明,在前面也说了JAX-WS是一种基于xml传递的webservice,也就是需要将传递的参数转化为xml文档,而这其中转化的过程就是我们见到的客户端对象中各种annotation声明,其背后的技术也就是前面说的JAXB(Java Architecture for XML Binding)简单地说就是一种将JAVA对象和XML互相转换的技术。包含在包
javax.jws
javax.xml.bind下提供了一系列解组、编组已经运行时绑定的API
javax.xml.bind.annotation 定义将 Java 程序元素定制成XML模式映射的注释
javax.xml.bind.annotation.adapters XmlAdapter 及其规范定义的子类允许任意 Java 类与 JAXB 一起使用

---------------------------------------- 

主要的接口或类:

HandlerChain 将 Web Service 与外部定义的处理程序链关联。
Oneway 指示给定 @WebMethod 只有一条输入消息并且没有输出。
WebMethod 定制一个公开为 Web Service 操作的方法。
WebParam 定制单个参数到 Web Service 消息部分和 XML 元素的映射关系。
WebResult 定制返回值到 WSDL 部分和 XML 元素的映射关系。
WebService 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口。

 

Element 这是一个元素标记接口。
Marshaller Marshaller 类负责管理将 Java 内容树序列化回 XML 数据的过程。 
Unmarshaller Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 内容树的过程,并可在解组时有选择地验证 XML 数据。
UnmarshallerHandler 作为 SAX ContentHandler 实现的 Unmarshaller。
ValidationEvent此事件指示在执行解组操作期间验证传入的 XML 数据时、对 Java 内容树执行按需验证时或将 Java 内容树编组回 XML 数据时遇到问题。
DatatypeConverter可以使用 javaType 绑定声明来自定义 XML 模式数据类型到 Java 数据类型的绑定。
JAXBContext JAXBContext 类提供到 JAXB API 的客户端入口点。
XmlAdapter 修改 Java 类型以适应自定义编组

 

主要的Annotation

XmlAccessorOrder  控制类中字段和属性的排序。
XmlAccessorType  控制默认情况下是否对字段或 Javabean 属性进行系列化。
XmlAttribute   将 JavaBean 属性映射到 XML 属性。
XmlElement   将 JavaBean 属性映射到派生于属性名称的 XML 元素。
XmlElementWrapper  生成一个包装 XML 表示形式的包装器元素。
XmlList    用来将属性映射到列表简单类型。
XmlMimeType   关联控制属性 XML 表示形式的 MIME 类型。 
XmlRootElement   将类或枚举类型映射到 XML 元素。
XmlTransient   阻止将 JavaBean 属性映射到 XML 表示形式。
XmlType   将类或枚举类型映射到 XML 模式类型。
XmlValue   支持将类映射到带有 simpleContent 的 XML 模式复杂类型或 XML 模式简单类型。

 

1、如何解码转码

JAXBContext是JAXB API 的客户端入口,从java到xml的互相转换对应Marshaller和Unmarshaller。一个简单的例子是

JAXBContext jaxbContext = JAXBContext.newInstance(claszz);
Marshaller marshaller = jaxbContext.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://sws.org/sample");

marshaller.marshal(t, System.out);
marshaller.marshal(t, new File("c:\\t.xml"));

 这里只是java转xml的例子。设置了格式化输出、encoding等属性、schema等信息,同时输出到控制台和指定文件路径 

 

2、常用annotation
常用的annotation用来绑定转换运行过程中的各种属性,如绑定属性、绑定的顺序、格式化处理等。下面介绍一些常用

@XmlRootElement(name="",namespace="")
标注此类作为xml的一个root节点,常用在顶层类或枚举类型。以下注释一起使用: XmlType、XmlEnum、XmlAccessorType、 XmlAccessorOrder。作为生产xml的root节点,名称可通过name来指定,默认会为该类名

@XmlAccessorType(XmlAccessType.FIELD)
控制对JavaBean的访问方式,一般有PROPERTY(getter/setter)、FIELD,PUBLIC_MEMBER(public getter/setter,fileds)、NONE可用于包,顶层类。若用于包表示该包下所有的类都照此处理,顶层类也即如果该类有其他的实体也将照此处理
默认为@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)

@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
指定序列化javabean的顺序

@XmlElement
@XmlElement 注释可以与以下程序元素一起使用: JavaBean 属性 ,非 static、非 transient 字段 ,XmlElements 中的程序元素

 @XmlElement(name = "firstName")
 private String name;
 private int age;

如果顶层类中标志了访问类型,如Filed。那么各个fileds的名称会被处理为xml中的节点,若按照上面的标注,此时节点名会是firstName

  <firstName>nico</firstName>
  <age>20</age>

@XmlTransient
@XmlTransient 注释对于解决 JavaBean 属性名称与字段名称之间的名称冲突,或者用于防止字段/属性的映射。

 @XmlTransient
 private String lastName;

则lastName不会被映射

@XmlList
@XmlList 来将属性映射到列表简单类型。比较两种序列方式:            

 List<String> data;       
<foo><data>aaaa</data><data>bbbb</data></foo>
            
@XmlList       
List<String> data;
<foo><data>aaaa bbbb</data></foo>

@XmlJavaTypeAdapter(class)
用来描述自定义的adapter,需要继承XmlAdapter,用来对自定义序列化的格式。如我们对时间的格式化输出

 

@XmlValue   
支持将类映射到带有 simpleContent 的 XML 模式复杂类型或 XML 模式简单类型。 简单说就是可以指定格式

<msg name="name">robin</msg>

 下面是一个Person的javabean,包含了一系列的声明:

@XmlRootElement(name = "per")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class Person {
    @XmlElement(name = "firstName")
    private String         name;
    @XmlTransient
    private String         lastName;
    @XmlJavaTypeAdapter(value = DateXmlAdapter.class)
    private Date           birthDay;
    @XmlList
    private List<String>   lang;

    private List<KeyValue> msg;
//getter/setter
}

 其中DateXmlAdapter如下:

public class DateXmlAdapter extends XmlAdapter<String, Date> {

    @Override
    public String marshal(Date v) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
        return format.format(v);
    }

    @Override
    public Date unmarshal(String v) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
        return format.parse(v);
    }

}

 KeyValue:

@XmlAccessorType(XmlAccessType.FIELD)
public class KeyValue {

    @XmlAttribute
    private String name;
    @XmlValue
    private String value;

序列化结果为:

Person p = new Person();
p.setName("robin");
p.setLastName("yang");
p.setBirthDay(new Date());
List<String> lang = Arrays.asList(new String[] { "java", "javascript", "python" });
p.setLang(lang);
List<KeyValue> msg = new ArrayList<KeyValue>();
msg.add(new KeyValue("aa", "aaa-value"));
msg.add(new KeyValue("bbb", "bbb-value"));
p.setMsg(msg);
<per>
    <birthDay>2012-11-17</birthDay>
    <lang>java javascript python</lang>
    <msg name="aa">aaa-value</msg>
    <msg name="bbb">bbb-value</msg>
    <firstName>robin</firstName>
</per>

3、JAX-WS传递Map

前面在说到可以传递复杂对象时并没有指定Map,是因为并不支持原生的Map传递。如果需要传递我们需要做一个简单的包装,同时需要利用到上面说的XmlJavaTypeAdapter来对bean到xml转换转换。下面的例子是传递Map实例:

@WebService
public interface JaxWsMapService {

    @WebMethod
    public WrapperMapResult getPersonMap();

}

 WrapperMapResult 只是对Map的一个简单封装:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class WrapperMapResult {

    private String              message;
    private boolean             success;

    @XmlJavaTypeAdapter(value = MapAdapter.class)
    private Map<String, Person> map;

 其中最重要的是MapAdapter:

public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Person>> {

    @Override
    public Map<String, Person> unmarshal(MapConvertor convertor) throws Exception {
        List<MapEntry> entries = convertor.getEntries();
        if (entries != null && entries.size() > 0) {
            Map<String, Person> map = new HashMap<String, Person>();
            for (MapEntry mapEntry : entries) {
                map.put(mapEntry.getKey(), mapEntry.getValue());
            }
            return map;
        }
        return null;
    }

    @Override
    public MapConvertor marshal(Map<String, Person> map) throws Exception {
        MapConvertor convertor = new MapConvertor();
        for (Map.Entry<String, Person> entry : map.entrySet()) {
            convertor.addEntry(new MapConvertor.MapEntry(entry));
        }
        return convertor;
    }

}

这里声明了MapConvertor用来解析Map<String, Person>

@XmlType(name="MapConvertor")
@XmlAccessorType(XmlAccessType.FIELD)
public class MapConvertor {

    private List<MapEntry> entries = new ArrayList<MapConvertor.MapEntry>();

    public void addEntry(MapEntry entry) {
        entries.add(entry);
    }

    public List<MapEntry> getEntries() {
        return entries;
    }

    //结构依赖于需要Conver的Map,比如这里Map<String, Person>
    public static class MapEntry {
        private String key;
        private Person value;

        public MapEntry() {

        }

        public MapEntry(String key, Person person) {
            this.key = key;
            this.value = person;
        }

        public MapEntry(Map.Entry<String, Person> entry) {
            this.key = entry.getKey();
            this.value = entry.getValue();
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public Person getValue() {
            return value;
        }

        public void setValue(Person value) {
            this.value = value;
        }

    }

}

其他的步骤按照wsimport生产客户端代码调用即可,这样就完成了JAX-WS中map的传递

分享到:
评论

相关推荐

    JAX-WS 2.2 RI所有相关jar包

    JAX-WS 2.2 RI 所包含的JAR包集合,包含25个JAR包,列表如下: FastInoset.jar gmbal-api-only.jar ha-api.jar javax.annotation.jar javax.mail_1.4.jar jaxb-api.jar jaxb-impl.jar jaxb-xjc.jar jaxws-api...

    jax-ws webservice demo

    基于jax-ws 实现的web service client和server端的demo程序。 注:如果使用的是 myeclipse 时 server 部署到tomcat 启动的时候会报错 解决办法:找到myeclipse安装目录下的 plugins 目录里 查找 webservices-rt.jar,...

    JAX-WS自学笔记

    JAX-WS自学笔记 本人自学JAX-WS笔记和简单例子,文档标题结构如下: JAX-WS使用教程 1、JAX-WS概述 2、创建Web Service 2.1 从java开始 2.1.1 运行wsgen 2.1.2 生成的WSDL和XSD 2.1.3 目录结构 2.2 从WSDL...

    Jax-ws所需要的JAR包

    亲测可用,Jax-ws所需要的JAR包,拷贝到tomcat安装路径的lib里,实现了webservice发布到tomcat,赞!

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例 - 外衣 - 博客频道 - CSDN_NET.mht

    JAX-WS 2.2 完整jar包

    JAX-WS 2.2 RI 所包含的JAR包集合,包含25个JAR包,列表如下: FastInoset.jar gmbal-api-only.jar ha-api.jar javax.annotation.jar javax.mail_1.4.jar jaxb-api.jar jaxb-impl.jar jaxb-xjc.jar jaxws-api...

    metro-jax-ws-master

    The Java API for XML Web Services (JAX-WS) is a Java programming language API for creating web services, particularly SOAP services. JAX-WS is one of the Java XML programming APIs. It's a part of the ...

    jaxb-api.jar.jaxws-api.zip_ jaxb-api.jar_cxf_jax-ws.jar_jaxb-api

    cxf框架与jdk6出现冲突的支持包,请大家支持下!

    webService部署tomcat需要的jax-ws jar包

    webService部署tomcat需要的jax-ws 的完整jar包

    JAX-WS_WebService.rar

    JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用

    jax-ws:用于 XML Web 服务的 Java API (JAX-WS)

    jax-ws 用于 XML Web 服务的 Java API (JAX-WS) #内容 temp-converter-client:用于现有 .Net Web 服务的 JAX-WS 客户端。 问候服务:JAX-WS 问候服务

    JAX-WS2.0 API

    JAX-WS2.0 API

    Jax-WS 简单实例

    Jax-WS的简单实例 Jax-WS的简单实例

    jax-ws webservice简单demo

    jax-ws webservice完整demo,包含所有jax-ws 2.2jar包。

    jax-rs jax-ws所需包,亲测可用

    javax.xml.ws.Service 报错需要的包,亲测可以用,直接下载在ide里buildpath一下就可以,四个jar包 ,整合了其他的jar所以配置简单

    使用JAX-WS(JWS)发布WebService

    使用JAX-WS(JWS)发布WebService 使用myeclipse开发java的webservice的两种方式 方式一: (此方式只能作为调试,有以下bug:jdk1.6u17?以下编译器不支持以Endpoint.publish方式发布document方式的soap,必须在...

    JAX-WS开发的文件生成与部署相关全视频过程

    如果基于一个JAX-WS进行WebService开发,有很多教程,但是具体怎么更自动地生成一些文件,实现客户端与服务端的交互,都讲得不大清楚,为了让大家更方便地部署,我将服务端、客户端文件的生成与部署全过程以及测试...

    JAX-WS的lib、src和docs

    3.众多元数据(Annotations)会被JAX-WS用来描述Web Services的相关类,包括Common Annotations, Web Services Metadata, JAXB2的元数据和JAX-WS2.0规范自己的元数据. 4.Annotation Processing Tool(APT)是JAX-WS重要的...

Global site tag (gtag.js) - Google Analytics