1、傳遞複雜對象(list、map、自定義對象)java
在使用WebService服務的時候常常須要傳遞參數,咱們不可能只使用基本類型,因此也應該支持複雜對象。先創建一個複雜的類:apache
類的代碼比較多也比較簡單,這個類須要實現Serializable接口,也就是說必須得實現可序列化才行。由於代碼比較多我就直接摺疊了,這麼多字段的緣由是想構建一個至關複雜的類。。。。瀏覽器
public class Address implements Serializable { private static final long UID = 3222222L; private Integer identifier; //地址 private String address; //城市 private String city; //省份 private String province; //國家 private String country; //郵編 private String postalCode; private String[] array; private List<Integer> list; private boolean isExist; public Address(){ list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); } public Integer getIdentifier() { return identifier; } public void setIdentifier(Integer identifier) { this.identifier = identifier; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getPostalCode() { return postalCode; } public void setPostalCode(String postalCode) { this.postalCode = postalCode; } public String[] getArray() { return array; } public void setArray(String[] array) { this.array = array; } public List<Integer> getList() { return list; } public void setList(List<Integer> list) { this.list = list; } public boolean isExist() { return isExist; } public void setExist(boolean exist) { isExist = exist; } }
而後就是創建具體的WebService類,這個服務的功能註釋中寫得很清楚app
public class AddressManager { //將返回一個預先創建好的Address對象,測試返回複雜對象 public Address getaddress(){ Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); return address; } //返回傳遞上來的Address對象,不作修改,測試上傳複雜對象 public Address setaddress(Address address){ return address; } //將返回一個預先創建好的list,測試返回list public List<Address> getaddressList() { List<Address> returnList = new ArrayList<Address>(); Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); returnList.add(address); address = new Address(); address.setIdentifier(2); address.setAddress("xx2"); address.setCity("yy2"); address.setProvince("zz2"); address.setCountry("CN2"); address.setPostalCode("100862"); address.setExist(true); address.setArray(new String[]{"12","22","32"}); returnList.add(address); return returnList; } //返回傳遞上來的list,不作修改,測試上傳list public List<Address> setAddressList(List<Address> list){ return list; } //將返回一個預先創建好的map,測試返回map public Map<Integer, Address> getAddressMap(){ Map<Integer,Address> returnMap = new HashMap<Integer,Address>(); Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); returnMap.put(address.getIdentifier(),address); address = new Address(); address.setIdentifier(2); address.setAddress("xx2"); address.setCity("yy2"); address.setProvince("zz2"); address.setCountry("CN2"); address.setPostalCode("100862"); address.setExist(true); address.setArray(new String[]{"12","22","32"}); returnMap.put(address.getIdentifier(),address); return returnMap; } //返回傳遞上來的map,不作修改,測試上傳map public Map<Integer,Address> setAddressMap(Map<Integer,Address> map){ return map; } }
而後就是發佈這個服務,在server-config.wsdd添加如下XML代碼:ide
<service name="AddressManager" provider="java:RPC"> <parameter name="className" value="example.AddressManager"/> <parameter name="allowedMethods" value="*"/> <beanMapping qname="myNSD:Address" xmlns:myNSD="urn:AddressManager" languageSpecificType="java:model.Address" /> </service>
和以前不一樣的就是多了<beabMapping>這個節點。qname 表示 XML 規範中定義的限定名稱,他由名稱空間 URI、本地部分和前綴組成。除了本地部分其餘都不是必須的另外QName是不可變的。xmlns後面的myNS是必須的。具體根據前面所指定的 qname來決定。以後能夠隨意命名一個namespace。其實我能夠任意寫幾個能夠用的就能夠大概看出規律了:post
<beanMapping qname="myNSD:Address1" xmlns:myNSD="urn:AddressManager1" languageSpecificType="java:model.Address" />
<beanMapping qname="NSD:Address" xmlns:NSD="urn:AddressManager" languageSpecificType="java:model.Address" />
而後我在用特殊符號總結一下,該怎麼編寫這個節點測試
<beanMapping qname="***:+++" xmlns:***="!!!:---" languageSpecificType="java:model.Address" />
***處是兩個一一對應的,就是說任意編寫只是這兩個要同樣,+++、---、!!!這三處任意填寫。。這裏的qname客戶端將會用到。this
最後的languageSpecificType指定的是你傳遞的對象類型。url
到此點擊運行,在瀏覽器中輸入http://localhost:8080/test/services能夠看到,AddressManager服務已經被髮布還能夠看到能夠被調用的方法:spa
而後是客戶端的代碼:
首先是獲取一個Adress對象的方法,具體流程註釋中寫得很清楚,要注意的地方有生成Qname時第一個參數名字空間URI,第二個參數本地部分,注意這兩部分在server-config.wsdd文件中標籤beanMapping配置:
public static void getServerAddress(){ try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); //生成QName,兩個參數與服務端的發佈時的XML設定有關 QName qn = new QName("urn:AddressManager","Address"); //註冊參數 call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "getaddress")); //設置返回類型 call.setReturnClass(Address.class); Object[] sss = null; //經過call.invoke 調用服務,獲取返回值 Address address = (Address) call.invoke(sss); System.out.println("Address: "); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } }
運行這個方法能夠看到輸出,已經獲得了這個Address對象:
而後是上傳一個Address對象在客戶端的代碼,比剛纔多一個call.addParameter("address", qn , ParameterMode.IN);用於註冊參數,若是上傳的是String類型就不須要這條語句。
public static void setServerAddress(){ Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); //生成QName,兩個參數與服務端的發佈時的XML設定有關 QName qn = new QName("urn:AddressManager","Address"); //註冊參數 call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "setaddress")); //設置返回類型 call.setReturnClass(Address.class); //定義一個參數類型,若是是String類型的參數能夠不須要這句話 call.addParameter("address", qn , ParameterMode.IN); //經過call.invoke 調用服務,獲取返回值 address = (Address) call.invoke(new Object[]{address}); System.out.println("Address: "); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } }
輸出是:
而後下面的代碼是所有的代碼,包括list和map:
public class ClientAddress { public static void getServerList(){ try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); QName qn = new QName("urn:AddressManager","Address"); call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "getaddressList")); call.setReturnClass(ArrayList.class); Object[] sss = null; //經過call.invoke 調用服務,獲取返回值 List<Address> list = (ArrayList) call.invoke(sss); System.out.println("List size: " + list.size()); for(Iterator<Address> iter = list.iterator(); iter.hasNext();){ Address address = iter.next(); System.out.println("id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); } }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void getServerMap(){ try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); QName qn = new QName("urn:AddressManager","Address"); call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "getAddressMap")); call.setReturnClass(HashMap.class); Object[] sss = null; //經過call.invoke 調用服務,獲取返回值 Map<Integer,Address> map = (Map) call.invoke(sss); System.out.println("map size: " + map.size()); for(Iterator<Integer> iter = map.keySet().iterator(); iter.hasNext();){ Integer key = iter.next(); Address address = map.get(key); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); } }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void setServerList(){ List<Address> list = new ArrayList<Address>(); Address address = new Address(); address.setIdentifier(3); address.setAddress("xx3"); address.setCity("yy3"); address.setProvince("zz3"); address.setCountry("CN3"); address.setPostalCode("100863"); address.setExist(false); address.setArray(new String[]{"13","23","33"}); list.add(address); address = new Address(); address.setIdentifier(4); address.setAddress("xx4"); address.setCity("yy4"); address.setProvince("zz4"); address.setCountry("CN4"); address.setPostalCode("100864"); address.setExist(true); address.setArray(new String[]{"14","24","34"}); list.add(address); try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); QName qn = new QName("urn:AddressManager","Address"); call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "setAddressList")); call.setReturnClass(ArrayList.class); call.addParameter("list", qn , ParameterMode.IN); //經過call.invoke 調用服務,獲取返回值 list = (ArrayList) call.invoke(new Object[]{list}); System.out.println("list size: " + list.size()); for(Iterator<Address> iter = list.iterator(); iter.hasNext();){ address = iter.next(); System.out.println("id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); } }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void setServerMap(){ Map<Integer,Address> map = new HashMap<Integer,Address>(); Address address = new Address(); address.setIdentifier(3); address.setAddress("xx3"); address.setCity("yy3"); address.setProvince("zz3"); address.setCountry("CN3"); address.setPostalCode("100863"); address.setExist(false); address.setArray(new String[]{"13","23","33"}); map.put(address.getIdentifier(),address); address = new Address(); address.setIdentifier(4); address.setAddress("xx4"); address.setCity("yy4"); address.setProvince("zz4"); address.setCountry("CN4"); address.setPostalCode("100864"); address.setExist(true); address.setArray(new String[]{"14","24","34"}); map.put(address.getIdentifier(),address); try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); QName qn = new QName("urn:AddressManager","Address"); call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "setAddressMap")); call.setReturnClass(HashMap.class); call.addParameter("map", qn , ParameterMode.IN); //經過call.invoke 調用服務,獲取返回值 map = (Map) call.invoke(new Object[]{map}); System.out.println("map size: " + map.size()); for(Iterator<Integer> iter = map.keySet().iterator(); iter.hasNext();){ Integer key = iter.next(); address = map.get(key); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); } }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void getServerAddress(){ try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); //生成QName,兩個參數與服務端的發佈時的XML設定有關 QName qn = new QName("urn:AddressManager","Address"); //註冊參數 call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "getaddress")); //設置返回類型 call.setReturnClass(Address.class); Object[] sss = null; //經過call.invoke 調用服務,獲取返回值 Address address = (Address) call.invoke(sss); System.out.println("Address: "); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void setServerAddress(){ Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); //生成QName,兩個參數與服務端的發佈時的XML設定有關 QName qn = new QName("urn:AddressManager","Address"); //註冊參數 call.registerTypeMapping(Address.class, qn, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "setaddress")); //設置返回類型 call.setReturnClass(Address.class); //定義一個參數類型,若是是String類型的參數能夠不須要這句話 call.addParameter("address", qn , ParameterMode.IN); //經過call.invoke 調用服務,獲取返回值 address = (Address) call.invoke(new Object[]{address}); System.out.println("Address: "); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist " + address.isExist()); }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void main(String[] args){ getServerList(); getServerMap(); setServerList(); setServerMap(); getServerAddress(); setServerAddress(); } }
輸出:
2、帶有內部類的自定義對象
若是自定義的對象中擁有一個自定義類也是可能會出現的。
修改剛剛自定義的類,添加一個自定義類,這個內部類必須是靜態且可序列化的:
public class Address implements Serializable { ...... private innername innc; public static class innername implements Serializable{ private String innername; public String getInnername() { return innername; } public void setInnername(String innername) { this.innername = innername; } } public innername getInnc() { return innc; } public void setInnc(innername innc) { this.innc = innc; } ...... }
而後修改AddressManager,這裏爲了簡單由於只測試這個內部對象的使用,因此只修改獲取Address的方法就能夠測試
public class AddressManager { //將返回一個預先創建好的Address對象,測試返回複雜對象 public Address getaddress(){ Address address = new Address(); address.setIdentifier(1); address.setAddress("xx"); address.setCity("yy"); address.setProvince("zz"); address.setCountry("CN"); address.setPostalCode("10086"); address.setExist(false); address.setArray(new String[]{"1","2","3"}); Address.innername innername = new Address.innername(); innername.setInnername("my name"); address.setInnc(innername); return address; } ....... }
真正須要修改的是用於發佈的XML代碼,和剛纔同樣添加一個<beanMapping>節點:
<service name="AddressManager" provider="java:RPC"> <parameter name="className" value="example.AddressManager"/> <parameter name="allowedMethods" value="*"/> <beanMapping qname="myNSD:Address" xmlns:myNSD="urn:AddressManager" languageSpecificType="java:model.Address" /> <beanMapping qname="ns:InnerClass" xmlns:ns="urn:AddressManager" languageSpecificType="java:model.Address$innername"/> </service>
點擊運行,而後修改客戶端的代碼,惟一改變的地方就是註冊了第二個參數:
public class ClientAddress { ....... public static void getServerAddress(){ try { String url = "http://localhost:8080/test/services/AddressManager?wsdl"; //生成服務對象Service Service service = new Service(); Call call = (Call) service.createCall(); //生成QName,兩個參數與服務端的發佈時的XML設定有關 QName qn1 = new QName("urn:AddressManager","Address"); QName qn2 = new QName("urn:AddressInnerClass","InnerClass"); //註冊參數 call.registerTypeMapping(Address.class, qn1, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.class, qn1), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.class, qn1)); call.registerTypeMapping(Address.InnerClass.class, qn2, new org.apache.axis.encoding.ser.BeanSerializerFactory(Address.InnerClass.class, qn2), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Address.InnerClass.class, qn2)); //設置Endpoint地址 call.setTargetEndpointAddress(new java.net.URL(url)); //綁定請求方法名稱 call.setOperationName(new QName(url, "getaddress")); //設置返回類型 call.setReturnClass(Address.class); Object[] sss = null; //經過call.invoke 調用服務,獲取返回值 Address address = (Address) call.invoke(sss); System.out.println("Address: "); System.out.println(" id號: " + address.getIdentifier() + " address: " + address.getAddress() + " city: " + address.getCity() + " province: " + address.getProvince() + " country: " + address.getCountry() + " postalCode: " + address.getPostalCode() + " array: " + address.getArray()[0] + " list: " + address.getList() + " isExist: " + address.isExist() + " incname: " + address.getInnc().getInnername()); }catch (ServiceException e){ System.out.println("ServiceException"); e.printStackTrace(); }catch (RemoteException e){ System.out.println("RemoteException"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("MalformedURLException"); e.printStackTrace(); } } public static void main(String[] args){ getServerAddress(); } }
運行後輸出是:
3、註冊參數的方法
其實註冊參數的方法還能夠修改爲這樣,最後的效果是同樣的:
//註冊參數 call.registerTypeMapping(Address.class, qn1, BeanSerializerFactory.class, BeanDeserializerFactory.class); call.registerTypeMapping(Address.InnerClass.class, qn2, BeanSerializerFactory.class, BeanDeserializerFactory.class);