webservice如何傳遞複雜引數和自定義引數
首先說引數為User物件。
伺服器端照常如舊。還是用最初的文件中方式搭建。其中有個方法如下:
[html] view plaincopyprint?
1. public User getUserName(User u){
2. User user= new User();
3. user.setAge(u.getAge()+10);
4. user.setName( "^"+u.getName()+ "^");
5. user.setId(u.getId()+1);
6. return user;
7. }
public User getUserName(User u){
User user= new User();
user.setAge(u.getAge()+10);
user.setName("^"+u.getName()+ "^");
user.setId(u.getId()+1);
return user;
}
那我們客戶端如何傳遞過去呢?
當然我們還是使用Axiom方式。
因為在Axiom中,傳遞的引數必須為OMElement型別。所以呢。我們必須把我們自定義的物件轉化成OMElement物件。
那如何轉化呢?
[html] view plaincopyprint?
1. //把user物件轉化成相應的omElment物件
2. public static OMElement castElment(User u){
3. javax.xml.stream.XMLStreamReader reader = BeanUtil.getPullParser(u);
4. StreamWrapper parser = new StreamWrapper(reader);
5. StAXOMBuilder stAXOMBuilder
6. OMElement element = stAXOMBuilder.getDocumentElement();
7. return element;
8. }
//把user物件轉化成相應的omElment物件
public static OMElement castElment(Useru){
javax.xml.stream.XMLStreamReaderreader = BeanUtil.getPullParser(u);
StreamWrapper parser = newStreamWrapper(reader);
StAXOMBuilder stAXOMBuilder=OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory. getOMFactory(),parser);
OMElement element =stAXOMBuilder.getDocumentElement();
return element;
}
那我們我們繼續分析轉換後的OMElement結果?
OMElement param=castElment(u);
//輸出轉換後的omElement物件
System. out.println(param);
結果如下:
<User><age>10</age><id>0</id><name>李四</name></User>
實際上傳遞的是一串xml
main方式如下:
[html] view plaincopyprint?
1. public static void main(String[] args) throws Exception {
2. EndpointReference targetEPR = new EndpointReference("http://localhost:8080/testWSServerByAxis2/services/myService?wsdl" );
3. try {
4. Options options = new Options();
5. options.setTo(targetEPR);
6.
7. //載入目標伺服器
8. ServiceClient sender = new ServiceClient();
9. sender.setOptions(options);
10.
11. OMFactory fac = OMAbstractFactory.getOMFactory();
12. OMNamespace omNs = fac.createOMNamespace("http://test.com" , "" );
13. //呼叫服務端的方法
14. OMElement method = fac.createOMElement("getUserName" , omNs);
15. //給方法賦值引數值,引數值只能是omNode形式。所以需要把自定義物件轉成omNode物件
16. //呼叫把自定義物件轉化成omNode物件
17. User u= new User();
18. u.setId(0);
19. u.setAge(10);
20. u.setName( "李四");
21. OMElement param= castElment(u);
22. //輸出轉換後的omElement物件
23. System.out.println(param);
24. method.addChild(param);
25. //返回OMElement物件
26. OMElement result = sender.sendReceive(method);
27. System.out.println("clientResult="+result);
28. Iterator iterator=result.getChildElements();
29. while(iterator.hasNext()){
30. System.out.println("ok");
31. OMNode omNode = (OMNode) iterator.next();
32. if(omNode.getType()==omNode. ELEMENT_NODE){
33. OMElement omElement = (OMElement) omNode;
34. System.out.println("***="+omElement.getLocalName());
35. if (omElement.getLocalName().toLowerCase().equals("return" )) {
36. User u1 = (User) BeanUtil.processObject(omElement, User. class, null, true, new DefaultObjectSupplier());
37. System.out.println(u1.getName());
38. }
39. }
40. }
41. } catch (Exception e) {
42. e.printStackTrace();
43. }
44. }
public static void main(String[] args) throwsException {
EndpointReference targetEPR = newEndpointReference("http://localhost:8080/testWSServerByAxis2/services/myService?wsdl");
try {
Options options = newOptions();
options.setTo(targetEPR);
//載入目標伺服器
ServiceClient sender = newServiceClient();
sender.setOptions(options);
OMFactory fac =OMAbstractFactory.getOMFactory();
OMNamespace omNs =fac.createOMNamespace("http://test.com" , "" );
//呼叫服務端的方法
OMElement method =fac.createOMElement("getUserName" , omNs);
//給方法賦值引數值,引數值只能是omNode形式。所以需要把自定義物件轉成omNode物件
//呼叫把自定義物件轉化成omNode物件
User u= new User();
u.setId(0);
u.setAge(10);
u.setName( "李四");
OMElement param= castElment(u);
//輸出轉換後的omElement物件
System.out.println(param);
method.addChild(param);
//返回OMElement物件
OMElement result =sender.sendReceive(method);
System.out.println("clientResult="+result);
Iterator iterator=result.getChildElements();
while(iterator.hasNext()){
System.out.println("ok");
OMNode omNode = (OMNode)iterator.next();
if(omNode.getType()==omNode. ELEMENT_NODE){
OMElement omElement =(OMElement) omNode;
System.out.println("***="+omElement.getLocalName());
if(omElement.getLocalName().toLowerCase().equals("return" )) {
User u1 = (User)BeanUtil.processObject(omElement, User. class, null, true, newDefaultObjectSupplier());
System.out.println(u1.getName());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
還是按照上篇部落格的返回值,得到的結果如下:
[html] view plaincopyprint?
1. clientResult=<ns:getUserNameResponse xmlns:ns="http://test.com"><ns:return xmlns:ax21="http://entity.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:User"><ax21:age>20</ax21:age><ax21:id>1</ax21:id><ax21:name>^李四^</ax21:name></ns:return></ns:getUserNameResponse>
clientResult=<ns:getUserNameResponsexmlns:ns="http://test.com"><ns:returnxmlns:ax21="http://entity.com/xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:User"><ax21:age>20</ax21:age><ax21:id>1</ax21:id><ax21:name>^李四^</ax21:name></ns:return></ns:getUserNameResponse>
其次,若傳遞List<User>物件呢?
大家想想,List,如何傳遞呢?轉化成訊息又是在怎麼樣的呢?
因為傳遞引數必須為OmElement,那我們看一下List如何轉化的OmElement物件呢?
[html] view plaincopyprint?
1. //把List物件轉化成相應的omElment物件
2. ublic static OMElement castElment(List<User> userList){
3. // 構建 OMFactory 工廠
4. OMFactory factory = OMAbstractFactory. getOMFactory();
5. OMNamespace omNamespace = factory.createOMNamespace("http://test.com" , "" );
6. OMElement omElement = BeanUtil. getOMElement(new QName("root"), userList.toArray(), new QName("user"), false, null);
7. return omElement;
//把List物件轉化成相應的omElment物件
public static OMElementcastElment(List<User> userList){
// 構建 OMFactory 工廠
OMFactory factory =OMAbstractFactory. getOMFactory();
OMNamespace omNamespace =factory.createOMNamespace("http://test.com" , "" );
OMElement omElement = BeanUtil.getOMElement(new QName("root"), userList.toArray(), new QName("user"),false, null);
return omElement;
}
那轉換後的輸出結果是:
[html] view plaincopyprint?
1. <root><user><age>10</age><id>0</id><name>李四0</name></user><user><age>11</age><id>1</id><name>李四1</name></user><user><age>12</age><id>2</id><name>李四2</name></user></root>
<root><user><age>10</age><id>0</id><name>李四0</name></user><user><age>11</age><id>1</id><name>李四1</name></user><user><age>12</age><id>2</id><name>李四2</name></user></root>
注意觀察輸出的OMElement。其中是由use標籤包含的。這樣下次獲得這樣的List返回值的OMElement,則只要把user中的取出然後封裝成物件即可。
另外還需要注意:BeanUtil. getOMElement方法中的第一個引數,不能為null,輸出的是在物件外有一層標籤。第三個引數是封裝物件的標籤的命名。
這樣話Axis2基本上可以正常投入使用中。雖然Axis2中使用axiom方式可以處理複雜自定義型別,但是說實話還是需要進行轉化。但是在CXF中,其實沒有怎麼麻煩。直接傳遞即可。
但是正所謂人無完人,Axis2中介面引數是什麼,釋出服務後生成的wsdl上的element的命名則與介面引數命名是一樣的。但是在CXF中,卻不同。CXF若不用註解的方式改命名,則預設情況則是arg0,arg1.