`
yaodi0818
  • 浏览: 135165 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
开发环境: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 {
	
	@Override
	public String getTestString(String str) {
		return "Hello" + str;
	}
	
	@Override
	public ExceedVO getTestObject(EnterVO vo) {
		ExceedVO revo = new ExceedVO();
		revo.setDescStr("名称:"+vo.getName()+"年龄:"+vo.getAge());
		return revo;
	}
	
	@Override
	public 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 Call
		call.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服务了!
分享到:
评论
10 楼 2047699523 2015-04-14  
如何在java Web项目中开发WebService接口
http://www.zuidaima.com/question/1925428495420416.htm
9 楼 feelingkeep 2014-10-30  
HelloWorldClientServlet里面的call.setTargetObjectURI("名字"); 这个名字应该和soap服务端设置的id名称是一致的 楼主给的代码里面call.setTargetObjectURI("urn:HelloWorldService"); 和服务器的hello不一致哦~~
8 楼 liuzibin 2014-05-05  
谢谢的东西,能够发我一份吗?我到处找都没能找到。我的QQ邮箱是347754769@qq.com我是刚学ws,对你这个问题还有待研究
7 楼 H伊方H 2012-07-03  
                  
6 楼 fengyun4love 2012-02-16  
我最近在学soap,可是apache网上似乎已经没有了,求大瞎给我一份sopa.war,我的网址是fengyun4love@163.com,十分感谢.
5 楼 jsamson 2011-09-07  
你好,不知有没遇到过用wsdl文件生成的客户端放在weblogic服务器后,调用服务端返回对象报错,报...is not bound。主要提示说一些属性没邦定之类。
4 楼 Jerry_BJ 2011-08-30  
您好 有一问题不是很懂  希望能加Q详聊 谢谢!251637313
3 楼 yanglinumber1 2009-02-18  
谢谢的东西,能够发我一份SOAP.WAR吗?我到处找都没能找到。我的QQ邮箱是471723842@qq.com我是刚学ws,对你这个问题还有待研究。
2 楼 yanglinumber1 2009-02-18  
谢谢的东西,能够发我一份SOAP.WAR吗?我到处找都没能找到。我的QQ邮箱是471723842@qq.com我是刚学ws,对你这个问题还有待研究。
1 楼 yaodi0818 2009-01-05  
在项目中使用XFire发布服务,在本地测试一切正常,但是传到服务器上,发现List的第一个元素是没有内容的,后面的元素内容显示正常,
通过调试服务端没有问题,是往客户端之间传输时丢失的,目前的解决办法比较2,是在List前面加了一条垃圾数据,故意把List的第一个元素挤下来。
希望有人能帮我解答!!!谢谢

相关推荐

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

    NULL 博文链接:https://zlhroar.iteye.com/blog/2229400

    webservice(wsdl、soap)实例有demo

    webservice实例有demo,用于写各种接口

    使用XFire实现SOAP的webservice数据传输源码(java)

    WebService之WSDL和SOAP实例(基于JAVA),博客地址:http://www.cnblogs.com/zhongshengzhen/p/4290670.html

    01_webservice快速实例

    01_webservice快速实例,02_wsimport的使用,03_wsdl和soap讲解(介入了tcpmon工具),04_SOA的分析,05_dtd讲解,06_schema的命名空间,07_schema的元素和属性的定义,以及基础的讲解。

    java 调用https webservice实例及axis包

    java 调用https发布的webservice接口实例及axis包及详细说明

    PB调用JAVA WEBSERVICE实例

    JAVA WEBSERVICE 建的实例工程,给PB调用, 因VS建的 WEBSERVICE PB很难调用,所以用JAVA的axis做了个小实例 共大家参考

    webservice定制发布实例(java版)

    axis发布webservice,RPC和message两种方式,进行自定义对象的传送.

    php WebService用法实例

    php webservice用法实例,SoapServer,soapClient,wsdl;注意Client/index.php代码中记得替换成自己的wsdl测试路径。

    C#调用WebService实例开发

    是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。简单的理解就是:webservice 就是放在服务器上的函数,所有人都可以调用,然后返回信息。 比如google就有一个web service ,你调用它...

    php soap 实例

    php soap 实例 SOAP 是基于XML和HTTP通讯协议,XML各个平台,各种语言都支持的一种语言。 不同语言之间需要通信(例如:php,java,c),可以通过SOAP,WSDL使不同操作系统,不同技术的编程语言互相通信。

    WebService技术及其应用实例论文

    其次介绍了WebService技术中的关键技术,其中包括可扩展性标记语言(XML)、简单对象访问协议(SOAP)、Web服务描述语言(WSDL)和统一描述、发现与集成(UDDI)注册中心。最后本文依据WebServices的技术原理、体系...

    WEBservice实战开发视频教程

    资源名称:WEBservice实战开发视频教程 教程内容:第一期:01_webservice快速实例02_wsimport的使用03_wsdl和soap讲解(介入了tcpmon工具)04_SOA的分析(纯属扯淡)05_dtd讲解06_schema的命名空间07_schema的元素和...

    phpStudy实现WebService实例,亲自测试及写了例子

    client.php中,修改代码new SoapClient("http://webservice.my.com/hello.wsdl");中的域名或网址 client.php?fun=fun1 返回1个失败提示 client.php?fun=fun2 返回一个简单数组(json,下同) client....

    WebService 的调用天气预报(附源码Demo)

    WebService 的调用天气预报,使用wsimport命令生成webService客户端代码实例,java project 下载后可以直接运行

    gsoap 2.8 (SOAP/XML 关于C/C++ 语言的自动化实现工具内附 CSharp webservice例子,及GSOAP client和server例子)

     ×gSOAP编译器可以根据用户定义的C和C++数据结构自动生成符合SOAP的实例化代码。  ×gSOAP支持WSDL 1.1, SOAP 1.1, SOAP 1.2, SOAP RPC 编码方式以及 literal/document 方式.  ×gSOAP是少数完全支持SOAP1.1 RPC...

    Webservice代码实例和培训教程

    Webservice代码实例和培训教程 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用...

    C#调用WebService实例与开发教程(推荐)

    Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI...

    THINKPHP3.2使用soap连接webservice的解决方法

    今天使用THINKPHP3.2 框架中开发时使用soap连接webservice 一些浅见现在分享一下, 1.首先我们要在php.ini 中开启一下  php_openssl.dll  php_soap.dll 2.在方法中创建的 SoapClient 类 的实例 $url=...

    WebService的创建以及调用

    Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI...

Global site tag (gtag.js) - Google Analytics