以下都是根据项目中实际应用编写,难免出现疏漏,如果有疑问可以博客交流。
第一部分:JAX-WS框架。
A:建立webservice工程。
第一步:利用myeclipse8.0 新建 Web Service Project,填写项目名称,我这里填写为webservice_server,然后选择webservice的framework,我这里选择JAX-WS。点击finish完成webservice工程创建。
第二步:在WEB-INFlib下面加入JAX-WS需要的包;如axis.jar、jaxrpc.jar、说saaj.jar、webservices-api.jar等jar包。
第三步:在src目录下建立service包和dao包,在service里定义服务接口和接口实现类,接口实现类通过dao对象调用dao层实现逻辑。
第四步:根据service里定义的接口实现类,新建other==》Web Services==》Web Service,点击next,在strategy选项中选择第二个单项按钮即:create webservice from java class (Bottom-up scenario),点击next在java class中选择service里定义的接口实现类,然后再选择 generate wsdl in project 复选框,点击finish即可。
第五步:启动webservice工程;
B:建立客户端访问webservice工程
第六步:新建javaproject;
第七步:src目录建立jaxws.client包,在jaxws.client包下面建立业务包。比如自己开发的项目中的ping包,然后再ping包下根据webservice工程生成客户端代码,具体方法:新建other==》Web Services==》Web Service Client,点击next,选择客户端项目名称后,再点击next,然后在java package点击 browse...选择需要生成代码需要放置的地方,比如ping包下面。然后点击next,没有出现错误时,点击finish即可。
第八步:在jaxws.client包下面编写客户端调用webservice的类,例如PingLient,在类中利用ping包下面的service代理对象调用webservice中的方法。另外此类中还需要webservice中model(vo)对象和客户端model对象的转换等。
至此,核心的webservice应用简单介绍完了,如果有疑问可以博客交流。
第二部分:XFire框架。
以下应用有部分参考自http://kaguvivian.javaeye.com/blog/114665
??????????????????????????????????? http://blog.csdn.net/lsunwing/archive/2010/04/06/5454003.aspx
第一步:利用myeclipse8.0 新建 Web Service Project,然后选择webservice的framework,我这里选择XFire。
第二步:在这个项目里我勾选了Xfire1.2 Core Libraries;HTTP Client Libraries;XML Beans Libraries。Xfire1.2 Core Libraries,核心包
HTTP Client Libraries,客户端包
XML Beans Libraries,xml支持包
这三个包中核心包和xml支持包是必须的,而第二个只是为了在webservice_server 工程中模拟客户端做测试用。点击finish完成提供服务的工程创建。
主要是确保引入了以下包:
? activation-1.0.2.jar
? commons-codec-1.3.jar
? commons-httpclient-3.0.jar
? commons-logging-1.0.4.jar
? jaxen-1.1-beta-8.jar
? jdom-1.0.jar
? log4j-1.2.x.jar
? mail-1.3.3_01.jar
? spring-1.2.x.jar
? stax-api-1.0.jar
? wsdl4j-1.5.2.jar
? wstx-asl-2.9.jar
? xbean-2.1.0.jar
? xbean-spring-2.2.jar
? xfire-all-1.0.jar
? XmlSchema-1.0.jar
打开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>/services/*</url-pattern>
? </servlet-mapping>
? <welcome-file-list>
??? <welcome-file>index.jsp</welcome-file>
? </welcome-file-list>
</web-app>
第三步:编写java类
编写对应的接口和实现类IQueryUnivid 和 QueryUnividImpl
QueryUnividImpl是一个普通的Java类,没有任何代码告诉我们它将会在Web Services中使用。只是要有默认的构造函数,类型是public。这是必须的。否则,XFire不能够初始化这个类。好的,这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。
Web应用的部署描述符
在Java中,Web应用程序通常需要至少一个部署描述符(叫做web.xml)对其进行配置。XFire本身是一个基于servlet的应用程序。因此,我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web Services。我们使用一个称为services.xml的新文件来完成这件事。
services.xml
现在我们不得不说一下我们的Web Services的由什么组成的了。这由一个叫做services.xml的文件完成,当这个项目在tomcat发布后,它存放在WEB-INF/classes/META-INF/xfire目录下,它在Web应用程序的标准类路径中。而在Eclipse环境中我们可以看到Eclipse已经为我们把它清楚的列在项目路径中。这里是services.xml中的基本配置条目:
?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
? ?<service>
???? <!--
?????????? 第一个子元素是<name></name>Banking,它可以是你提供任何的合法名字。
?????????? 这将会被客户端程序和其它需要定位你的服务的组件用到。
?????????? 例如,在服务准备好以后,你将在浏览器上使用这个名字来查看WSDL。
???? -->
??? ?<name>Querying</name>?
??<namespace>myquery</namespace>?
??<serviceClass>com.sxcct.mapc.library.IQueryUnivid</serviceClass>?
??<implementationClass>com.sxcct.mapc.library.impl.QueryUnividImpl</implementationClass>?
?</service>
?
</beans>
?
Web Services的定义包含在元素中,它还含有一些子元素。
第一个子元素是<name></name>Banking,它可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如,在服务准备好以后,你将在浏览器上使用这个名字来查看WSDL。
下一个子元素是<namespace></namespace>。任何合法的XML名字都是可以的。<namespace></namespace>用来唯一标识你的服务的各个参数。(注释@)
注释@:Namespace派什么用?namespace的作用是要避免命名冲突。如果我建立一项Web
Service,其中的WSDL文件包含一个名为"foo"的元素,而你想要使用我的服务与另一项服务连接作为补充,这样的话另一项服务的WSDL文件就不能包含名为"foo"的元素。两个服务器程序只有在它们在两个事例中表示完全相同的东西时,才可以取相同的名字。如果有了表示区别的namespace,我的网络服务里的"foo"就可以表示完全不同于另一个网络服务里"foo"的含义。在你的客户端里,你只要加以限制就可以引用我的"foo"。
<serviceclass></serviceclass>元素包含了Java类的名字,它指定了方法签名。在我们的例子中,它是接口IQueryUnivid 。如果Java类没有实现任何接口,你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services。
<implementationclass></implementationclass>保存了实现方法的Java类名。这是一个可选元素。如果上一个元素<serviceclass></serviceclass>包含了一个接口,那么相应的实现类必须在这里指定。
就是这样。我们的Web Services配置完成了。
我们如何知道Web Service正在工作呢?
为了了解Web Service是否正在工作,我们需要测试。首先,我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL?因为我们的应用程序的war文件是aa.war,并且在services.xml中给出的服务名是Banking,WSDL的URL应该是:http://localhost:8080/webservice_server/services/Querying?wsdl。
请注意:URL的第一部分,例如,http://localhost:8080,可能会根据你的应用服务器不同而不同。无论怎样,当你输入URL后,将会看到一个XML文档,这个文档叫做服务的WSDL。如果你看到了,这就是你的应用作为Web Service已经可用的第一个证明。
在这个WSDL中我们可以看到<xsd:element name="getUnivid">的服务方法明以及他的一个参数描述等信息。但是这个测试是不够的。可能会发生这种情况,可以看到WSDL,但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了,我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。
下面是模拟客户端的测试类
package com.sxcct.mapc.simulateclient;
//http://localhost:8080/webservice_server/services/Querying?wsdl
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
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;
import com.sxcct.mapc.library.IQueryUnivid;
public class QueryUnividClient {
?private String fileName = "log4j.xml";
?private static final Logger logger = Logger.getLogger(QueryUnividClient.class);
?public static void main(String[] args) {
??DOMConfigurator.configure("D:/apache-tomcat-6.0.26/webapps/webservice_server/WEB-INF/config/log4j.xml");
??logger.debug("begin>>>>>>>>>>>>>>>>>>>>>>>>>>>>>begin");
??QueryUnividClient bClient = new QueryUnividClient();
??bClient.callWebService("0000000041");
??logger.debug("end>>>>>>>>>>>>>>>>>>>>>>>>>>>>>end");
?}
?
?public String callWebService(String cardNo) {
??// create a metadata of service
??Service serviceModel = new ObjectServiceFactory().create(IQueryUnivid.class);
??System.out.println("callSoapServiceLocal(): got service model.");
??// Create a proxy for the deployed service 为XFire获得一个代理工厂对象
??XFire xfire = XFireFactory.newInstance().getXFire();
??XFireProxyFactory factory = new XFireProxyFactory(xfire);
??
??// 得到一个服务的本地代理
??String serviceUrl = "http://127.0.0.1:8080/webservice_server/services/Querying";
??IQueryUnivid client = null;
??try {
???client = (IQueryUnivid) factory.create(serviceModel,serviceUrl);
??} catch (MalformedURLException e) {
???System.out.println("WsClient.callWebService(): EXCEPTION: " + e.toString());
??}
??
??// Invoke the service 调用服务返回状态结果信息
??String serviceResponse = "";
??try {
???serviceResponse = client.getUnivid(cardNo);
??} catch (Exception e) {
???System.out.println("WsClient.callWebService(): EXCEPTION: " + e.toString());
???serviceResponse = e.toString();
??}
??System.out.println("WsClient.callWebService(): univid=" + serviceResponse);
??
??// Return the response
??return serviceResponse;
?}
?
?/**
? *? 取得配置文件内容
? * @return
? */
?public FileInputStream getFileContent(){
??FileInputStream is = null;
??try
??{
???String path = getContentPath();
???System.out.println(path + "config/" + fileName);
???is = new FileInputStream(path + "config/" + fileName);
??}
??catch (FileNotFoundException e)
??{
???e.printStackTrace();
??}
??return is;
?}
?
?private String getContentPath()
?{
??String path = this.getClass().getResource("").toString();
??if (!path.endsWith(File.separator))
??{
???path = path + File.separator;
??}
??int index1 = path.lastIndexOf(":");
??int index2 = path.indexOf("WEB-INF");
??if (index1 > 0)
??{
???if (System.getProperty("file.separator").equals("/"))
???{
????// unix、linux系统
????index1 = index1 + 1;
???}
???else
???{
????// windows系统
????index1 = index1 - 1;
???}
??},
??path = path.substring(index1,index2 + 8);
??
??return path;
?}
}
?
其实这样测试和实际的应用可能还有所区别,这样吧,我们新建个webserver的client工程去调用服务端的方法,这样会比较符合实际的项目应用。
?注意:
第一步:建立客户端的时候一定新建other里的myeclipse菜单选择Web Services==》Web Service Client
第二步:选择create a new web service project...,填写客户端项目名:webservice_cliens
加入xfire框架,next,加入核心包,finish。
然后在project下拉框中选择刚才新添得项目名webservice_cliens,next,?
在WSDL URL中键入server工程WSDL链接地址,即:http://localhost:8080/webservice_server/services/Querying?wsdl
点击Next之后会验证wsdl地址,这时验证可能会出错(如果服务端程序tomcat或其他应用程序中间件启动的话是不会验证出错的,建议建立client端工程之前启动服务端的程序)但不必关心,继续Next。
默认全部选择,finish完成Web Service Client的建立。
步骤3、测试Web Service服务
打开类QueryingClient.java,找到main方法,并修改如下:?
??????? String cardNo = "0000000041";??
??????? System.out.println("根据卡号"+cardNo+"查到的学号是"+service.getUnivid(cardNo));?
???????
??System.out.println("test client completed");
??????? System.exit(0);
运行此类就可以看到结果
?
以上单独建立了一个webservice client工程,其实建立一个java project 工程,然后右键工程myeclipse==>add xfire? web service capabilityis也可以测试调用远程webservice服务。