Apache CXF 整合 Map

來源:互聯網
上載者:User

標籤:des   style   http   color   java   使用   os   io   

在進行編碼前有必要對一些基本的認識進行介紹,以便後面的講解。

1、JAXB:

    JAXB能夠使用Jackson對JAXB註解的支援實現(jackson-module-jaxb-annotations),既方便產生XML,也方便產生JSON,這樣一來可以更好的標誌可以轉換為JSON對象的JAVA類。JAXB允許JAVA人員將JAVA類映射為XML表示方式,常用的註解包括:@XmlRootElement,@XmlElement等等。

    JAXB(Java Architecture for XML Binding) 是一個業界的標準,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML執行個體文檔反向產生Java對象樹的方法,並能將Java對象樹的內容重新寫到XML執行個體文檔。從另一方面來講,JAXB提供了快速而簡便的方法將XML模式綁定到Java表示,從而使得Java開發人員在Java應用程式中能方便地結合XML資料和處理函數。

2、Java SE中的JAXB

    JAXB 2.0是JDK 1.6的組成部分。JAXB 2.2.3是JDK 1.7的組成部分。


   2.1 JDK中JAXB相關的重要Class和Interface:
    JAXBContext類,是應用的入口,用於管理XML/Java綁定資訊。
    Marshaller介面,將Java對象序列化為XML資料。
    Unmarshaller介面,將XML資料還原序列化為Java對象。


   2.2 JDK中JAXB相關的重要Annotation:
    @XmlType,將Java類或枚舉類型映射到XML模式類型
    @XmlAccessorType(XmlAccessType.FIELD) ,控制欄位或屬性的序列化。FIELD表示JAXB將自動綁定Java類中的每個非靜態(static)、非瞬態的(由@XmlTransient標註)欄位到XML。其他值還有XmlAccessType.PROPERTY和XmlAccessType.NONE。
    @XmlAccessorOrder,控制JAXB 綁定類中屬性和欄位的排序。
    @XmlJavaTypeAdapter,使用定製的適配器(即擴充抽象類別XmlAdapter並覆蓋marshal()和unmarshal()方法),以序列化Java類為XML。
    @XmlElementWrapper ,對於數組或集合(即包含多個元素的成員變數),產生一個封裝該數組或集合的XML元素(稱為封裝器)。
    @XmlRootElement,將Java類或枚舉類型映射到XML元素。
    @XmlElement,將Java類的一個屬性對應到與屬性同名的一個XML元素。
    @XmlAttribute,將Java類的一個屬性對應到與屬性同名的一個XML屬性。

3、解組和編組

    解組:( unmarshalling )把資料從儲存媒介上轉化到記憶體中的過程,正好與編組相反。因此需要把 xml 文檔解組到 Java VM 中。這裡的複雜性不是在扁平資料中,因為這不是必需的,而在於從正確的資料到正確 Java 代碼變數的映射。如果映射是錯誤的,就不可能正確的訪問資料。當然,如果再嘗試重新編組還會造成更大的問題,並且問題傳播的很快。
    編組:( marshalling )是把記憶體中的資料轉化到儲存媒介上的過程。因此在 java 和 XML 環境中,編組就是把一些 Java 對象轉換成一個或多個 XML 文檔。在資料庫環境中,則是把 Java 表示的資料存入資料庫。顯然,編組的秘密在於把 Java 執行個體中的物件導向結構轉化成適用於 XML 的扁平結構,或者 RDBMS 中的關係結構

    好的,下面開始編碼了。工程以上一篇的為基礎。

一、建立Person類


    其代碼為:

package com.yao.spring.bean;import java.io.Serializable;public class Person implements Serializable{private static final long serialVersionUID = -283567759187941425L;private String name;private int age;@Overridepublic String toString() {return "Person [age=" + age + ", name=" + name + "]";}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
二、因為我們其中要返回一個Map<String,Person>的類型,所以我們要實現一個解組和編組的適配器工具。

    2.1 建立Map轉換器類:MapConvertor,@XmlType注釋標明該類可以轉化為xml類型,@XmlAccessorType(XmlAccessType.FIELD) ,控制欄位或屬性的序列化。

package com.yao.spring.util;import java.util.ArrayList;import java.util.List;import java.util.Map;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlType;@XmlType(name = "MapConvertor")@XmlAccessorType(XmlAccessType.FIELD)public class MapConvertor {    private List<MapEntry> entries = new ArrayList<MapEntry>();    public void addEntry(MapEntry entry) {        entries.add(entry);    }    public List<MapEntry> getEntries() {        return entries;    }        public static class MapEntry {        private String key;        private Object value;                public MapEntry() {            super();        }        public MapEntry(Map.Entry<String, Object> entry) {            super();            this.key = entry.getKey();            this.value = entry.getValue();        }        public MapEntry(String key, Object value) {            super();            this.key = key;            this.value = value;        }        public String getKey() {            return key;        }        public void setKey(String key) {            this.key = key;        }        public Object getValue() {            return value;        }        public void setValue(Object value) {            this.value = value;        }    }}
    2.2 建立Map適配器類 MapAdapter,用於編組與解組,重寫XmlAdapter的 編組(marshal )與解組(unmarshal)方法。
package com.yao.spring.util;import java.util.HashMap;import java.util.Map;import javax.xml.bind.annotation.adapters.XmlAdapter;/** * 對Map類型做轉換的類和適配器類 * @author Kangjun * */public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {    @Override    public MapConvertor marshal(Map<String, Object> map) throws Exception {        MapConvertor convertor = new MapConvertor();        for (Map.Entry<String, Object> entry : map.entrySet()) {            MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);            convertor.addEntry(e);        }        return convertor;    }    @Override    public Map<String, Object> unmarshal(MapConvertor map) throws Exception {        Map<String, Object> result = new HashMap<String, Object>();        for (MapConvertor.MapEntry e : map.getEntries()) {            result.put(e.getKey(), e.getValue());        }        return result;    }}

這時的類結構如下:

三、建立要調用的介面:PersonService。注意到public Map<String, Person> getPersonMap()方法有注釋@XmlJavaTypeAdapter(MapAdapter.class),此處注釋的XmlJavaTypeAdapter是對自訂編組使用實現XmlAdapter的適配器,即MapAdapter這個類,該類實現了XmlAdapter適配器,因此要實現解組和編組兩個方法。可能有的初學讀者會提到:為什麼我們要實現編組和解組呢?原因很簡單,CXF不能直接支援Map。

package com.yao.spring.service;import java.util.Map;import javax.jws.WebService;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;import com.yao.spring.bean.Person;import com.yao.spring.util.MapAdapter;@WebServicepublic interface PersonService {public Person getPerson();@XmlJavaTypeAdapter(MapAdapter.class)public Map<String, Person> getPersonMap();}

這時的類結構如下:

四、實現介面的方法類PersonServiceImpl:
package com.yao.spring.service;import java.util.HashMap;import java.util.Map;import javax.jws.WebService;import com.yao.spring.bean.Person;@WebService(endpointInterface="com.yao.spring.service.PersonService")public class PersonServiceImpl implements PersonService {@Overridepublic Person getPerson() {Person p = new Person();p.setAge(22);p.setName("yaokj");return p;}@Overridepublic Map<String, Person> getPersonMap() {Person p = new Person();p.setAge(25);p.setName("yaokj");Map<String, Person> map = new HashMap<String, Person>();map.put("yaokj", p);return map;}}
五、修改cxf-servlet.xml檔案,添加:<jaxws:endpoint id="personService" implementor="com.yao.spring.service.PersonServiceImpl" address="/PersonService"/>
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">    <jaxws:endpoint id="helloWorld" implementor="com.yao.spring.service.HelloWorldImpl" address="/HelloWorld"/><jaxws:endpoint id="personService" implementor="com.yao.spring.service.PersonServiceImpl" address="/PersonService"/></beans>
六、修改client-beans.xml檔案。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">    <bean id="client" class="com.yao.spring.service.HelloWorld" factory-bean="clientFactory" factory-method="create"/>    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">        <property name="serviceClass" value="com.yao.spring.service.HelloWorld"/>        <property name="address" value="http://localhost:8080/HelloSpringCXF/services/HelloWorld"/>    </bean>        <bean id="personClient" class="com.yao.spring.service.PersonService" factory-bean="personFactory" factory-method="create" />    <bean id="personFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">    <property name="serviceClass" value="com.yao.spring.service.PersonService"/>    <property name="address" value="http://localhost:8080/HelloSpringCXF/services/PersonService" />    </bean></beans>
七、編寫用戶端代碼:PersonClient
package com.yao.spring.client;import java.util.Map;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.yao.spring.bean.Person;import com.yao.spring.service.PersonService;public class PersonClient {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"client-beans.xml"});PersonService personService = (PersonService)ctx.getBean("personClient");Person p =  personService.getPerson();System.out.println(p);Map<String,Person> map = personService.getPersonMap();System.out.println("map: "+map.get("yaokj"));ctx.close();System.exit(0);}}

這時的類結構如下:

八、啟動Tomcat

九、運行PersonClient,並列印,成功。

2014-8-21 2:12:02 org.springframework.context.support.AbstractApplicationContext prepareRefresh資訊: Refreshing org[email protected]735cda3f: startup date [Thu Aug 21 02:12:02 CST 2014]; root of context hierarchy2014-8-21 2:12:02 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions資訊: Loading XML bean definitions from class path resource [client-beans.xml]2014-8-21 2:12:03 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons資訊: Pre-instantiating singletons in org.s[email protected]28e70e30: defining beans [client,clientFactory,personClient,personFactory]; root of factory hierarchy2014-8-21 2:12:03 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass資訊: Creating Service {http://service.spring.yao.com/}HelloWorldService from class com.yao.spring.service.HelloWorld2014-8-21 2:12:04 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass資訊: Creating Service {http://service.spring.yao.com/}PersonServiceService from class com.yao.spring.service.PersonServicePerson [age=22, name=yaokj]map: Person [age=25, name=yaokj]2014-8-21 2:12:04 org.springframework.context.support.AbstractApplicationContext doClose資訊: Closing org[email protected]735cda3f: startup date [Thu Aug 21 02:12:02 CST 2014]; root of context hierarchy2014-8-21 2:12:04 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons資訊: Destroying singletons in org.s[email protected]28e70e30: defining beans [client,clientFactory,personClient,personFactory]; root of factory hierarchy


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.