这两天在学习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接口创建一个服务模型Service Service 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,不知道是干什么用的,找时候学习一下。