XFire发送和接收复杂类型、对象
这两天在学习WebService,首先选择的是XFire。服务端返回对象和集合,在客户端处理的时候我使用了两种方式。一种是自己手动创建客户端的代理接口和实体类。类所在的包同服务端一致;还有一种是我使用了Ant生成的客户端代码。第一种手动创建的测试返回值都没有问题,但是第二种方式我使用了xmlBeans工具所以生成的方法返回值类型是XmlObject,这里要怎么处理呢,要自己解析这个xml文件吗?XFire有没有自己的方式,可以直接把返回的XmlObject转换成实体对象呢?还有,我服务端一个方法接收一个实体类型的对象,在客户端调用这个方法的时候要如何传入对象呢?百度了一天也没有一个能很好的说明解决方法的,入门的helloword倒是不少。希望高手能帮忙看看,提点一小,或给点解决的意见。
?
下面是代码:
服务端代码结构:
?
?
实体类User.java
?
?
public class User implements Serializable{/** * */private static final long serialVersionUID = 1L;private String name;private Date birthday;//set,get..............
?
?
服务端服务类IHelloServiceImpl(接口IHelloService的代码就不贴了)
?
import java.util.ArrayList;import java.util.Date;import java.util.List;import com.study.bo.User;import com.study.service.IHelloService;public class IHelloServiceImpl implements IHelloService {public String copyMessage(String msg) {return msg;}public List getList(List t) {for(int i = 0 ; i < t.size() ; i++){System.out.println(t.get(i));}List al = new ArrayList();User user = new User();user.setName("路人甲");user.setBirthday(new Date());al.add(user);return al;}public void sayHello() {System.out.println("hello world");}public User getUserByName(String name){User user = new User();user.setName(name);return user;}}
?
?
因为使用了List类型,所以要做一个映射IHelloService.aegis.xml
?
<?xml version="1.0" encoding="UTF-8"?><mappings><mapping><method name="getList"><parameter index="0" componentType="java.lang.String" /><return-type componentType="com.study.bo.User" /></method></mapping></mappings>
?
services.xml和web.xml的代码就不贴了,相信大家都知道
?
下面是客户端的:
代码结构:
?
?
客户端创建方式一:手动ClientFromInterface.java
?
package com.study.client;import java.net.MalformedURLException;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.codehaus.xfire.client.XFireProxyFactory;import org.codehaus.xfire.service.Service;import org.codehaus.xfire.service.binding.ObjectServiceFactory;import com.study.bo.User;import com.study.service.IHelloService;/** * 使用WEB服务端提供的接口来创建客户端 * @author sysuser * */public class ClientFromInterface {/** * 1.使用XFire的ObjectServiceFactory从IHelloService接口创建一个服务模型Service<br/> * 2.创建一个服务端代理<br/> * 3.使用代理访问服务端方法 * @param args * @throws MalformedURLException */public static void main(String[] args) throws MalformedURLException {//使用XFire的ObjectServiceFactory从IHelloService接口创建一个服务模型ServiceService serviceModel = new ObjectServiceFactory().create(IHelloService.class);//访问地址String url = "http://127.0.0.1:8181/StudyXFireService/services/HelloService";//创建代理工厂XFireProxyFactory proxyFactory = new XFireProxyFactory();//通过proxyFactory,使用服务模型serviceModel和服务端点URL(用来获得WSDL) //得到一个服务的本地代理,这个代理就是实际的客户端 IHelloService client = (IHelloService)proxyFactory.create(serviceModel, url);client.sayHello();String msg = client.copyMessage("路人小子 ");System.out.println(msg);User user = client.getUserByName("gaojun");System.out.println(user.getName());List<User> userList = new ArrayList<User>();User user1 = new User();user1.setAge(10);user1.setName("name_1");user1.setBirthday(new Date());User user2 = new User();user2.setAge(20);user2.setName("name_2");user2.setBirthday(new Date());userList.add(user1);userList.add(user2);List<User> list1 = client.getList(userList);for(int i = 0 ; i < list1.size() ; i++){System.out.println(list1.get(i).getName());System.out.println(list1.get(i).getBirthday());}}}
?
这种方式下,传入和接收User,List都没有问题。
?
客户端创建方式二:ant生成方式
?
HelloServicePortType.java
?
package com.study.antService;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;import org.apache.xmlbeans.XmlObject;@WebService(name = "HelloServicePortType", targetNamespace = "http://www.study.xfire/HelloService")@SOAPBinding(use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)public interface HelloServicePortType { @WebMethod(operationName = "getUserByName", action = "") @WebResult(name = "out", targetNamespace = "http://www.study.xfire/HelloService") public XmlObject getUserByName( @WebParam(name = "in0", targetNamespace = "http://www.study.xfire/HelloService") String in0); @WebMethod(operationName = "getList", action = "") @WebResult(name = "out", targetNamespace = "http://www.study.xfire/HelloService") public XmlObject getList( @WebParam(name = "in0", targetNamespace = "http://www.study.xfire/HelloService") XmlObject in0); @WebMethod(operationName = "copyMessage", action = "") @WebResult(name = "out", targetNamespace = "http://www.study.xfire/HelloService") public String copyMessage( @WebParam(name = "in0", targetNamespace = "http://www.study.xfire/HelloService") String in0); @WebMethod(operationName = "sayHello", action = "") public void sayHello();}
?
HelloServiceClient.java
?
package com.study.antService;import java.net.MalformedURLException;import java.util.Collection;import java.util.HashMap;import javax.xml.namespace.QName;import org.codehaus.xfire.XFireRuntimeException;import org.codehaus.xfire.aegis.AegisBindingProvider;import org.codehaus.xfire.annotations.AnnotationServiceFactory;import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations;import org.codehaus.xfire.client.XFireProxyFactory;import org.codehaus.xfire.service.Endpoint;import org.codehaus.xfire.service.Service;import org.codehaus.xfire.soap.AbstractSoapBinding;import org.codehaus.xfire.transport.TransportManager;import org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry;public class HelloServiceClient { private static XFireProxyFactory proxyFactory = new XFireProxyFactory(); private HashMap endpoints = new HashMap(); private Service service0; public HelloServiceClient() { create0(); Endpoint HelloServicePortTypeLocalEndpointEP = service0 .addEndpoint(new QName("http://www.study.xfire/HelloService", "HelloServicePortTypeLocalEndpoint"), new QName("http://www.study.xfire/HelloService", "HelloServicePortTypeLocalBinding"), "xfire.local://HelloService"); endpoints.put(new QName("http://www.study.xfire/HelloService", "HelloServicePortTypeLocalEndpoint"), HelloServicePortTypeLocalEndpointEP); Endpoint HelloServiceHttpPortEP = service0 .addEndpoint(new QName("http://www.study.xfire/HelloService", "HelloServiceHttpPort"), new QName("http://www.study.xfire/HelloService", "HelloServiceHttpBinding"), "http://127.0.0.1:8181/StudyXFireService/services/HelloService"); endpoints.put(new QName("http://www.study.xfire/HelloService", "HelloServiceHttpPort"), HelloServiceHttpPortEP); } public Object getEndpoint(Endpoint endpoint) { try { return proxyFactory.create((endpoint).getBinding(), (endpoint).getUrl()); } catch (MalformedURLException e) { throw new XFireRuntimeException("Invalid URL", e); } } public Object getEndpoint(QName name) { Endpoint endpoint = ((Endpoint) endpoints.get((name))); if ((endpoint) == null) { throw new IllegalStateException("No such endpoint!"); } return getEndpoint((endpoint)); } public Collection getEndpoints() { return endpoints.values(); } private void create0() { TransportManager tm = (org.codehaus.xfire.XFireFactory.newInstance().getXFire().getTransportManager()); HashMap props = new HashMap(); props.put("annotations.allow.interface", true); AnnotationServiceFactory asf = new AnnotationServiceFactory(new Jsr181WebAnnotations(), tm, new AegisBindingProvider(new XmlBeansTypeRegistry())); asf.setBindingCreationEnabled(false); service0 = asf.create((com.study.antService.HelloServicePortType.class), props); { AbstractSoapBinding soapBinding = asf.createSoap11Binding(service0, new QName("http://www.study.xfire/HelloService", "HelloServicePortTypeLocalBinding"), "urn:xfire:transport:local"); } { AbstractSoapBinding soapBinding = asf.createSoap11Binding(service0, new QName("http://www.study.xfire/HelloService", "HelloServiceHttpBinding"), "http://schemas.xmlsoap.org/soap/http"); } } public HelloServicePortType getHelloServicePortTypeLocalEndpoint() { return ((HelloServicePortType)(this).getEndpoint(new QName("http://www.study.xfire/HelloService", "HelloServicePortTypeLocalEndpoint"))); } public HelloServicePortType getHelloServicePortTypeLocalEndpoint(String url) { HelloServicePortType var = getHelloServicePortTypeLocalEndpoint(); org.codehaus.xfire.client.Client.getInstance(var).setUrl(url); return var; } public HelloServicePortType getHelloServiceHttpPort() { return ((HelloServicePortType)(this).getEndpoint(new QName("http://www.study.xfire/HelloService", "HelloServiceHttpPort"))); } public HelloServicePortType getHelloServiceHttpPort(String url) { HelloServicePortType var = getHelloServiceHttpPort(); org.codehaus.xfire.client.Client.getInstance(var).setUrl(url); return var; }}
?
HelloServiceImpl.java
?
package com.study.antService;import javax.jws.WebService;import org.apache.xmlbeans.XmlObject;@WebService(serviceName = "HelloService", targetNamespace = "http://www.study.xfire/HelloService", endpointInterface = "com.study.client.HelloServicePortType")public class HelloServiceImpl implements HelloServicePortType{ public XmlObject getUserByName(String in0) { throw new UnsupportedOperationException(); } public XmlObject getList(XmlObject in0) { throw new UnsupportedOperationException(); } public String copyMessage(String in0) { throw new UnsupportedOperationException(); } public void sayHello() { throw new UnsupportedOperationException(); }}
?
测试类如下:
?
package com.study.client;import org.apache.xmlbeans.XmlObject;import com.study.antService.HelloServiceClient;import com.study.antService.HelloServicePortType;import com.study.bo.User;public class HelloWordTest {public static void main(String[] args) {HelloServiceClient client = new HelloServiceClient();HelloServicePortType service = client.getHelloServiceHttpPort();service.sayHello();String msg = "信息";String ms = service.copyMessage(msg);System.out.println(ms);XmlObject xmlObject = service.getUserByName("snm");System.out.println(xmlObject.toString());}}
?
可以看到,测试类返回的并不是User对象而是XmlObject,到这一步要如何处理呢?只能自己使用Dom或是其它工具解析xml了吗?XFire自己不提供转换成对象的功能吗?另xml打印结果如下:
<ns1:out xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="http://www.study.xfire/HelloService"> <age xmlns="http://bo.study.com">0</age> <name xmlns="http://bo.study.com">snm</name></ns1:out>
?代码有点多,主要是希望大家能看清楚。提点一下到这一步应该如果进行下去。
?
在实际的应用开发过程中,为了实现多平台的适用性,服务端和客户端一般都接收或返回xml文件的字符串,而尽量不使用复杂对象的吗?如果那样,对xml文件又是如何处理的呢,也是自己解析吗?
在解决问题的过程中看到SOAP,不知道是干什么用的,找时候学习一下。
?
?