日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CXF+JAXB处理复杂数据

發布時間:2024/9/27 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CXF+JAXB处理复杂数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CXF+JAXB處理復雜數據

CXF默認使用JAXB?來實現對象和XML之間的映射。在前面的例子?中,使用CXF發布的Webservice,其方法的參數和返回值都是簡單類型。 本文討論對象復雜性的分級,驗證對于各種復雜度JAXB的支持情況,以及使用JAXB時對于Map,循環引用,繼承等情況的處理辦法。 文中的例子沒有直接調用JAXB的API,而是用CXF發布webservice的形式驗證對象到xml的marshal和unmarshal, 所以本文也可以作為使用CXF的參考資料。

Table of Contents

  • 1 數據復雜性的分類
    • 1.1 簡單數據類型
    • 1.2 自定義類型
    • 1.3 集合類型
    • 1.4 復雜類型
  • 2 JAXB對數據復雜性的支持
  • 3 常用技巧
    • 3.1 使用自定義的XmlAdapter支持Map
    • 3.2 斷開循環引用的回路
    • 3.3 使用@XmlSeeAlso標注處理繼承關系
  • 4 代碼
    • 4.1 maven工程文件:pom.xml
    • 4.2 Map適配器:MapAdapter.java
    • 4.3 Map適配器使用的key-value結構:MapEntity.java
    • 4.4 JavaBean:User.java
    • 4.5 JavaBean:MyUser.java
    • 4.6 服務接口定義:CXFDemo.java
    • 4.7 服務實現類:CXFDemoImpl.java
    • 4.8 測試代碼:TestEndpoint.java

1?數據復雜性的分類

大體來說,Java中的數據/數據對象按照其復雜度可以分為以下幾類:

1.1?簡單數據類型

包括基本類型和Java對基本類型的封裝,主要有:

基本類型封裝類
floatFloat
doubleDouble
byteByte
shortShort
intInteger
longLong
charCharacter
booleanBoolean
char[]String

1.2?自定義類型

在C里面叫做struct,在Java里面叫做JavaBean,包含自定義屬性和getter/setter方法。

1.3?集合類型

Java的集合類(Collection)主要分為List,Set,Map三個系列。List實現了元素的序列(順序),Set實現不重復的集合,Map實現了key-value的映射。

1.4?復雜類型

更復雜的情況是對于上述三種類型的組合運用,比如在自定義類型中使用集合,或者集合的嵌套等。 復雜類型還會涉及到循環引用和繼承關系等問題。

2?JAXB對數據復雜性的支持

  • 簡單類型

對于簡單的數據類型,JAXB不需要任何處理就完全能夠支持

  • 自定義類型

JAXB對于一般的JavaBean也能夠支持,比如下面的例子:

User.java

public class User {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;} }

?

不需要JavaBean實現Serializable接口,也不需要增加@XmlRootElement聲明。

  • 集合類型

    JAXB能夠內置支持List和Set集合,但是對于Map的支持需要自己處理。

  • 復雜類型

    JAXB支持簡單類型、自定義類型、集合類型等的嵌套,但是對于循環引用、繼承等情況需要增加額外的處理。

3?常用技巧

3.1?使用自定義的XmlAdapter支持Map

JAXB可以在變量上添加@XmlJavaTypeAdapter標注,指定對該變量專門的適配器進行處理。 適配器繼承XmlAdapter類,并覆蓋了marshal和unmarshal方法,分別用于對象到XML的映射和XML到對象的映射。

使用XmlAdapter可以實現對Map類型的映射。

比如對于要通過CXF發布的WebService接口方法上,可以增加標注:

@XmlJavaTypeAdapter(MapAdapter.class) Map<String,User> getUserMap();Integer setUserMap(@XmlJavaTypeAdapter(MapAdapter.class)Map<String,User> users);

其中的MapAdapter就是自己實現的Map適配器,代碼如下:

MapAdapter.java

MapEntity是自己定義的一個簡單結構,用于保持Map中的key-value關系:

MapEntity.java public class MapEntity{public Object key;public Object value; }

?

經過這樣的處理,就能夠實現Map與XML之間的映射。

3.2?斷開循環引用的回路

對象之間的引用很有可能出現回路。最簡單的情況是兩個對象之間互相引用。這在ORM中很常見。如果我們在前面的User類中增加父子關系,如下:

User.java

當同時在兩個方向設置引用關系時,就發生了循環引用:

child.parent = parent; parent.children.put(child.getName(), child);

發生循環引用時,JAXB就會拋出異常。而處理的辦法就是斷開其中一個方向的引用。具體做法就是使用@XmlTransient標注,表明該屬性在marshal是不作處理。 如上面的User中,我們可以只處理parent到child的引用,而不處理child到parent的引用:

@XmlTransient public User parent;

?

這樣雖然解決了循環引用的問題,但是會導致得到User對象的parent屬性為null。為使用帶來不變。 解決的辦法是在JavaBean中增加afterUnmarshal()方法,當JAXB從xml恢復出對象后,會自動調用這個方法。我們可以在方法中將丟失的信息補全:

afterUnmarshal方法 public void afterUnmarshal(Unmarshaller u,Object parent) {for(Iterator itor = this.children.values().iterator();itor.hasNext();){User user = (User)itor.next();user.parent = this;} }

?

3.3?使用@XmlSeeAlso標注處理繼承關系

繼承關系在ORM中已經處理得非常完善了,JAXB處理繼承關系更加簡單,只需要在繼承樹的根類上增加@XmlSeeAlso標注,聲明所有的子類即可。 比如我們定義了一個User的子類:

public class MyUser extends User {...}

則只需要在User類上面增加標注:

@XmlSeeAlso @XmlSeeAlso({MyUser.class }) public class User {...}

?

4?代碼

本文相關的所有代碼如下:

4.1?maven工程文件

pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hysec</groupId><artifactId>cxfdemo</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>cxfdemo</name><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>apache-cxf</artifactId><version>2.4.1</version><type>pom</type></dependency></dependencies> </project>

?

4.2?Map適配器

MapAdapter.java package com.hysec.utils.jaxb;import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set;import javax.xml.bind.annotation.adapters.XmlAdapter;public class MapAdapter extends XmlAdapter<MapEntity[], Map> {@Overridepublic MapEntity[] marshal(Map map) throws Exception {// TODO Auto-generated method stubMapEntity[] list = new MapEntity[map.size()];Set keyset = map.keySet();int index =0;for(Iterator itor=keyset.iterator();itor.hasNext();){MapEntity item = new MapEntity();item.key = itor.next();item.value = map.get(item.key);list[index++] = item; }return list;}@Overridepublic Map unmarshal(MapEntity[] list) throws Exception {// TODO Auto-generated method stubMap map = new HashMap();for(int i=0;i<list.length;i++){MapEntity item = list[i];map.put(item.key, item.value);}return map;}}

?

4.3?Map適配器使用的key-value結構

MapEntity.java package com.hysec.utils.jaxb;public class MapEntity{public Object key;public Object value; }

?

4.4?JavaBean父類

User.java package cxfdemo;import java.util.HashMap; import java.util.Iterator; import java.util.Map;import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlTransient;@XmlSeeAlso({MyUser.class }) public class User {private Integer id;private String name;@XmlTransient public User parent;public Map<String,User> children = new HashMap<String,User>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void afterUnmarshal(Unmarshaller u,Object parent) {for(Iterator itor = this.children.values().iterator();itor.hasNext();){User user = (User)itor.next();user.parent = this;}}}

?

4.5?JavaBean子類

MyUser.java package cxfdemo;public class MyUser extends User {public String myProp; }

?

4.6?webservice接口定義


CXFDemo.java package cxfdemo;import java.util.List; import java.util.Map; import java.util.Set;import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;import com.hysec.utils.jaxb.MapAdapter;@WebService public interface CXFDemo {String sayHello(String foo);String sayHelloToUser(User user);User getUser(String name);List<User> getUsers();Integer setUsers(List<User> users);Set<User> getUserSet();Integer setUserSet(Set<User> users);@XmlJavaTypeAdapter(MapAdapter.class) Map<String,User> getUserMap();Integer setUserMap(@XmlJavaTypeAdapter(MapAdapter.class)Map<String,User> users);User addChild(User parent,User child); }

?

4.7?webservice實現類

CXFDemoImpl.java package cxfdemo; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set;import javax.jws.WebService;@WebService() public class CXFDemoImpl implements CXFDemo {public String sayHello(String foo) {return "hello "+foo;}public String sayHelloToUser(User user){return "hello "+user.getName();}public User getUser(String name){User user = new User();user.setName(name);return user;}public List<User> getUsers(){List<User> users = new ArrayList<User>();users.add(new User());return users;}public Integer setUsers(List<User> users){return users.size();}public Set<User> getUserSet(){Set<User> set = new HashSet<User>();set.add(new User());set.add(new User());return set;}public Integer setUserSet(Set<User> users){return users.size();}public Map<String,User> getUserMap(){HashMap<String,User> map = new HashMap<String,User>();User user1 = new User();user1.setName("Holbrook");map.put("Holbrook", user1);User user2 = new User();user2.setName("wanghaikuo");map.put("wanghaikuo", user2);return map;}public Integer setUserMap(Map<String,User> users){return users.size();}public User addChild(User parent,User child){child.parent = parent;parent.children.put(child.getName(), child);return parent;} }

?

4.8?測試用例

TestEndpoint.java package cxfdemo.test;import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set;import javax.xml.ws.Endpoint;import junit.framework.Assert; import junit.framework.TestCase;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import cxfdemo.CXFDemo; import cxfdemo.CXFDemoImpl; import cxfdemo.MyUser; import cxfdemo.User;public class TestEndpoint extends TestCase {private static final String ADDRESS = "http://localhost:9000/cxfdemo"; private static CXFDemo service;@Overrideprotected void setUp() throws Exception {// TODO Auto-generated method stubsuper.setUp();if(null==service){System.out.println("Starting Server"); CXFDemoImpl demo = new CXFDemoImpl(); Endpoint.publish(ADDRESS, demo);System.out.println("Start success");JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();factory.setServiceClass(CXFDemo.class);factory.setAddress(ADDRESS);service = (CXFDemo)factory.create();}}public void testSayHello(){Assert.assertEquals(service.sayHello("foo"), "hello foo");}public void testSayHelloToUser(){User user = new User();user.setName("Holbrook");String result = service.sayHelloToUser(user);Assert.assertEquals(result,"hello Holbrook");}public void testGetUser(){User user = service.getUser("Holbrook");Assert.assertEquals("Holbrook",user.getName());}public void testGetUsers(){List<User> users = service.getUsers();Assert.assertEquals(1,users.size());}public void testSetUsers(){List<User> users = new ArrayList<User>();users.add(new User());users.add(new User());users.add(new User());Assert.assertEquals(3,service.setUsers(users).intValue());}public void testGetUserSet(){Set<User> userSet = service.getUserSet();Assert.assertEquals(2,userSet.size());}public void testSetUserSet(){Set<User> set = new HashSet<User>();set.add(new User());set.add(new User());Assert.assertEquals(2, service.setUserSet(set).intValue());}public void testGetUserMap(){Map<String,User> map = service.getUserMap();Assert.assertTrue(map.containsKey("Holbrook"));Assert.assertTrue(map.containsKey("wanghaikuo"));}public void testSetUserMap(){HashMap<String,User> map = new HashMap<String,User>();User user1 = new User();user1.setName("Holbrook");map.put("Holbrook", user1);User user2 = new User();user2.setName("wanghaikuo");map.put("wanghaikuo", user2);Assert.assertEquals(2, service.setUserMap(map).intValue());}public void testAddChild(){User root = new User();root.setName("root");//root.parent = root; User child = new User();child.setName("child");User parent = service.addChild(root, child);Assert.assertTrue(parent.children.containsKey("child"));Assert.assertEquals(parent.children.get("child").parent, parent);}public void testInheritance(){User parent = new User();MyUser child = new MyUser();child.setName("child");child.myProp = "subclass Prop";User root = service.addChild(parent, child);User newChild = root.children.get("child");System.out.println(newChild instanceof MyUser);System.out.println(((MyUser)newChild).myProp);}}

?

Date: 2012-12-14 23:39:13 CST

Author: Holbrook

Org version 7.8.11 with Emacs version 24

Validate XHTML 1.0 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的CXF+JAXB处理复杂数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。