WebService之WSDL和SOAP实例(基于JAVA)

来源:互联网 发布:大数据分析是什么 编辑:程序博客网 时间:2024/05/21 11:26

开发环境:jdk1.6 + Tomcat 6.0.18 + MyEclipse6.0 

首先是使用WSDL协议实现:这里使用XFire 
XFire一个免费、开源的SOAP框架,它构建了POJO和SOA之间的桥梁,主要特性就是支持将POJO通过非常简单的方式发布成Web服务,其原理是以接口反射机制自动取得远程方法的 
WSDL是一个用来描述Web服务和说明如何与Web服务通信的XML语言 

准备:开发之前请先到官网(http://xfire.codehaus.org/Download)下载xfire-distribution-1.2.6.zip并解压缩 

(1)、新建一个Web项目(服务端),名称为XFireWebService,其目的是为了测试WebService服务端 
为工程添加XFire支持的类库,把xfire-1.2.6里lib所有jar和xfire-all-1.2.6.jar拷贝到工程lib里 

(2)、把XFire加载到系统中来,增加web.xml的配置信息 

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <servlet>    <servlet-name>XFireServlet</servlet-name>    <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>    <load-on-startup>0</load-on-startup>  </servlet>  <servlet-mapping>    <servlet-name>XFireServlet</servlet-name>    <url-pattern>/servlet/XFireServlet/*</url-pattern>  </servlet-mapping>  <servlet-mapping>    <servlet-name>XFireServlet</servlet-name>    <url-pattern>/services/*</url-pattern>  </servlet-mapping>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

(3)、创建Web服务接口,声明该Web服务对外暴露的接口 

package com.test.ws;import java.util.List;/** * <p>Title: IHelloService</p> * <p>Description: 定义接口</p> */public interface IHelloService {public String getTestString(String str); public ExceedVO getTestObject(EnterVO vo);public List getTestList(List list);}

(4)、创建Web服务实现类,为Web服务接口提供实现 

package com.test.ws;import java.util.ArrayList;import java.util.List;/** * <p>Title: HelloServiceImpl</p> * <p>Description: 接口实现</p> */public class HelloServiceImpl implements IHelloService {@Overridepublic String getTestString(String str) {return "Hello" + str;}@Overridepublic ExceedVO getTestObject(EnterVO vo) {ExceedVO revo = new ExceedVO();revo.setDescStr("名称:"+vo.getName()+"年龄:"+vo.getAge());return revo;}@Overridepublic List getTestList(List list) {List<EnterVO> users = new ArrayList<EnterVO>();for(int i=0; i<9; i++){EnterVO user = new EnterVO("姓名"+i, i);users.add(user);}return users;}}

(5)、这两个类是具体的业务实现类,对业务方法的具体实现放在里面 

package com.test.ws;import java.io.Serializable;/** * <p>Title: EnterVO</p> * <p>Description: 入参对象</p> */public class EnterVO implements Serializable {private static final long serialVersionUID = 1L;private String name;    private int age;   public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public EnterVO(String name, int age) {this.name = name;this.age = age;}public EnterVO() { }}package com.test.ws;import java.io.Serializable;/** * <p>Title: ExceedVO</p> * <p>Description: 出参对象</p> */public class ExceedVO implements Serializable {private static final long serialVersionUID = 1L;private String descStr;public String getDescStr() {return descStr;}public void setDescStr(String descStr) {this.descStr = descStr;}}

(6)、在src目录下新建一个META-INF文件夹里包含xfire/service.xml该文件是XFire框架的服务发布文件 

<?xml version="1.0" encoding="UTF-8"?><!-- 服务发布文件 --><beans xmlns="http://xfire.codehaus.org/config/1.0"><service> <!-- service标签和它所包含的xml内容为发布成Web服务的POJO提供完整的描述 --><name>HelloService</name> <!-- Web服务被发布时所采用的唯一名称 --><namespace>http://test/HelloService</namespace> <!-- Web服务发布时所使用的命名空间 --><serviceClass>com.test.ws.IHelloService</serviceClass> <!-- Web服务接口类的全名 --><implementationClass>com.test.ws.HelloServiceImpl</implementationClass> <!-- Web服务实现类的全名 --><!-- 不需要接口时,把业务写在serviceClass标签中 --></service></beans>

(7)、注意:当用到List等集合类型时,需要定义Mapping关系 
必须与接口同名后缀.aegis.xml,而且要与接口同一位置 

<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://xfire.codehaus.org/schemas/1.0/mapping.xsd">  <!-- XFire可以支持基本类型,但针对集合类型时需要特殊配置 -->    <mapping>         <method name="getTestList"> <!-- 需要配置的方法名 -->         <!-- index="0"代表方法的参数的序号0即第一个参数,componentType属性代表集合参数内包含的类型 -->         <parameter index="0" componentType="java.lang.String" />          <!-- 配置返回类型,componentType属性代表返回的集合中所包含的类 -->            <return-type componentType="com.test.ws.EnterVO" />         </method>           </mapping>   </mappings>

web.xml和service.xml都可以通过IDE自动生成,也可以手写 

(8)、到这步webService服务端就基本完成 
部署项目,启动Tomcat,测试一下wsdl,访问http://localhost:8080/XFireWebService/services/HelloService?wsdl 
如果能正确显示wsdl文件,说明刚才的部署成功了!!! 

(9)、再建一个Web项目(客户端),名称为XFireWebClient,其目的是用来调用一个webService服务 
将XFire的库文件拷贝到Web项目的WEB-INF\lib目录下,同时需要将服务器端发布的服务打包发布给客户端,发布给客户端的代码只需要打包接口和参数类即可,实现类不必打包到客户端 
这里发布的jar包名称为IHelloService.jar,里面包含IHelloService、EnterVO、ExceedVO这三个类 

(10)、在这个Web项目里面新建一个Servlet作为测试的Servlet,名称为ClientTestServlet.java 
在web.xml里面配置好这个Servlet后,就可以在Servlet里面写webService调用的代码了 

package com.test.ws;import java.io.IOException;import java.net.MalformedURLException;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.codehaus.xfire.XFire;import org.codehaus.xfire.XFireFactory;import org.codehaus.xfire.client.XFireProxyFactory;import org.codehaus.xfire.service.Service;import org.codehaus.xfire.service.binding.ObjectServiceFactory;/** * <p>Title: ClientTestServlet</p> * <p>Description: 测试Servlet</p> */public class ClientTestServlet extends HttpServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");Service serviceModel = new ObjectServiceFactory().create(IHelloService.class);       XFire xfire = XFireFactory.newInstance().getXFire();    XFireProxyFactory factory = new XFireProxyFactory(xfire);         String serviceUrl = "http://localhost:8080/XFireWebService/services/HelloService";    IHelloService client = null;    try {    client = (IHelloService) factory.create(serviceModel, serviceUrl);    } catch (MalformedURLException e) {    e.printStackTrace();    }            String str = client.getTestString("Beijing");    request.setAttribute("str", str);        EnterVO enterVO = new EnterVO();    enterVO.setName("Yaodi");    enterVO.setAge(26);    ExceedVO vo = client.getTestObject(enterVO);    request.setAttribute("vo", vo);        List<String> al = new ArrayList<String>(); al.add("111"); al.add("222");al.add("333");    List list = client.getTestList(al);    request.setAttribute("list", list);                request.getRequestDispatcher("/result.jsp").forward(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request,response);}}

客户端的web.xml如下所示: 


<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <servlet>    <servlet-name>ClientTestServlet</servlet-name>    <servlet-class>com.test.ws.ClientTestServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>ClientTestServlet</servlet-name>    <url-pattern>/ClientTest.do</url-pattern>  </servlet-mapping>  <welcome-file-list>    <welcome-file>ClientTest.do</welcome-file>  </welcome-file-list></web-app>

(11)、注意:XFireWebService项目里的IHelloService.aegis.xml文件,也要放到XFireWebClient项目中来,位置与ClientTestServlet.java同级 

(12)、Servlet返回的结果页面:result.jsp 

<%@ page language="java" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ page isELIgnored="false"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>测试客户端</title>  </head>    <body>    测试客户端!!!<br>    String:${str} <br>    Object:${vo.descStr} <br>    List:<br>    <c:forEach items="${list}" var="list">   ${list.name} --- ${list.age} <br>    </c:forEach>  </body></html>

13)、同样将这个Web项目发布,同时启动XFireWebService和XFireWebClient这两个应用,然后在地址栏里面输入http://localhost:8080/XFireWebClient/ 
此时会调用客户端的Servlet,然后调用其doGet方法,如果正常的话,可以看到页面输出结果了(*^__^*) 


问题:在项目中使用XFire发布服务,在本地测试一切正常,但是传到服务器上,发现List的第一个元素是没有内容的,后面的元素内容显示正常, 
通过调试服务端没有问题,是往客户端之间传输时丢失的,目前的解决办法比较2,是在List前面加了一条垃圾数据,故意把List的第一个元素挤下来。 
希望有人能帮我解答!!!谢谢 


 其次是使用SOAP协议实现:有时需要其它语言做服务端,java做客户端,就要用到SOAP获取WebService了 
SOAP简单对象访问协议是一种轻量的、简单的、基于 XML 的协议,它被设计成在WEB上交换结构化的和固化的信息 

这里演示的例子服务端和客户端都是java 

首先从网站http://xml.apache.org/soap/index.html下载soap,解压得到soap.war 
把soap.war放到Tomcat\webapps\目录下 

(1)、新建一个Web项目(服务端)名为SoapService 

(2)、编写服务端代码HelloWorldService.java 

package HelloWorld;/** * <p>Title: HelloWorldService</p> * <p>Description: 服务端</p> */public class HelloWorldService {public String getMessage(){return "Hello World!!!";}public String getMessage(String str1, String str2) { return "Hello World! " + str1 + "&" + str2; } }

编写完成后,将HelloWorldService发布jar到Tomcat\lib\目录中 

(3)、SOAP服务的发布 
启动Tomcat自动将soap.war解压,访问http://localhost:8080/soap/admin/,会出现soap的管理页面 
注意:这里会出现错误是因为在Tomcat\lib\目录下缺少sun的mail.jar 
进入Deploy,填写如下信息: 
ID: hello 
Scope: Request 
Methods getMessage 
Provider Type: Java 
Java Provider Provider Class: HelloWorld.HelloWorldService 
Java Provider Static: NO 
确认发布,可以点List查看已发布服务! 

(4)、再建一个Web项目(客户端)名为SoapClient 
为工程增加4个jar文件:xerces、soap、activation、mail 

(5)、在这个Web项目里面新建一个Servlet作为测试的Servlet,名称为HelloWorldClientServlet.java 
在web.xml里面配置好这个Servlet后,就可以在Servlet里面写webService调用的代码了 

package HelloWorld;import java.io.IOException;import java.net.URL;import java.util.Vector;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.soap.Constants;import org.apache.soap.Fault;import org.apache.soap.SOAPException;import org.apache.soap.rpc.Call;import org.apache.soap.rpc.Parameter;import org.apache.soap.rpc.Response;/** * <p>Title: HelloWorldClientServlet</p> * <p>Description: 测试Servlet</p> */public class HelloWorldClientServlet extends HttpServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String endPoint = "http://localhost:8080/soap/servlet/rpcrouter"; //url是固定的,带参数绑定Call call = new Call(); //创建一个RPC Callcall.setTargetObjectURI("hello"); //远程的服务名call.setMethodName("getMessage"); //访问方法call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); //设置编码风格//发布带参数的服务Vector params = new Vector();Parameter p1 = new Parameter("name", String.class, "关羽", null); Parameter p2 = new Parameter("name2", String.class, "张飞", null); params.addElement(p1);params.addElement(p2); call.setParams(params);URL url = new URL(endPoint); //SOAP服务的网址,开始发送RPC请求,并返回服务端的应答Response resp = null;try { //检查应答报中文是否有错(有错就打印出错信息,没错就打印返回信息)resp = call.invoke(url, "");} catch (SOAPException e) {e.printStackTrace();} if(resp.generatedFault()){Fault fault = resp.getFault();System.out.println("The Following Error Occured:");System.out.println("Fault Code=" + fault.getFaultCode());System.out.println("Fault String=" + fault.getFaultString());} else {Parameter result = resp.getReturnValue();System.out.println(result.getValue());request.setAttribute("str", result.getValue());}request.getRequestDispatcher("/result.jsp").forward(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request,response);}}

客户端的web.xml如下所示: 

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <servlet>    <servlet-name>HelloWorldClientServlet</servlet-name>    <servlet-class>HelloWorld.HelloWorldClientServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>HelloWorldClientServlet</servlet-name>    <url-pattern>/HelloWorldClientServlet.do</url-pattern>  </servlet-mapping>  <welcome-file-list>    <welcome-file>HelloWorldClientServlet.do</welcome-file>  </welcome-file-list></web-app>

(6)、Servlet返回的结果页面:result.jsp 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ page isELIgnored="false"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>SOAP测试客户端</title>  </head>    <body>    SOAP测试客户端!!!<br>    String:${str} <br>  </body></html>

7)、运行客户端,测试是否通过 
同时启动SoapService和SoapClient这两个应用,访问http://localhost:8080/SoapClient/ 
应该可以看到返回的内容,则证明配置和测试成功,以后就可以发布自己的SOAP服务了!
  • XFireWebService.rar (18 KB)
  • 下载次数: 481
  • SoapWebService.rar (13.1 KB)
  • 下载次数: 670




转载地址:http://di201yao.iteye.com/blog/310292

原创粉丝点击