摘要
今天突然兴起,想学学webService,然后就找找资料,做了个简单的DEMO。先记录下来,以便日后使用。 首先,先说点理论上的东西。
今天突然兴起,想学学webService,然后就找找资料,做了个简单的DEMO。先记录下来,以便日后使用。 首先,先说点理论上的东西。
WebService又是一种高级应用,与之前学习的Struts、spring、hibernate等框架不同。WebService是面向服务的架构(SOA),看起来像是比SSH框架要大。那么它到底是做什么用的?什么才是面向服务的架构?
让我们来看一种需求,集团公司可能具有多种WEB应用。比如,前年开发了个进销存系统、去年开发了一个ERP、今年又开发了一个OA。现在这家集团公司需要将这三个系统整合,难道需要重新编码将它们整合吗?而这三个系统又是用不同语言编写的,这种成本对公司来说无疑是一种浪费。WebService可以很好的解决这种需求。
WebService是可以进行跨语言、跨平台、分布式系统间整合的方案,WebService像是一条线将这些系统穿起来——企业服务总线(ESB)。WebService使用简单对象访问协议(SOAP)使用http协议传输xml数据(xml是最常用的,也有其他格式数据。)来完成系带间的整合。
什么是整合?当然是功能和数据的整合,也就是一个系统可以调用另一个系统的WebService接口来完成数据的交互。这样我们就需要知道,提供WebService服务功能的应用公开了哪些接口,我们可以通过WebService描述文档(WSDL)得知。WSDL不需要我们手动编写,Java的WebService实现可以为我们自动生成。JDK1.6新增支持WebService,但还不够成熟。所以我们使用Apache第三方开源组织提供的WebService实现——Axis。
Axis的当前版本是Java版本,它的C++版本正在开发中。Axis是一个功能强大的soap引擎,关于它们的详细信息在此就不做介绍了。下面,让我们来编写一个例子程序,以了解WebService的应用流程。
==================================================================================================================
下面开始编写服务端代码:
1.在MyEclipse中,建立一个WebProject。命名为WebService.
2.下载axis1.4的包,解压,里面有一些关于axis的资料和文件。
将webapps里面的,WEB-INF中的web.xml复制,替换到自己的WebService项目中。
如果你没有,可以将下如代码拷贝到你的web.xml中:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Apache-Axis</display-name> <listener> <listener-class>org.apache.axis.transport.http.AxisHTTPSessionListener</listener-class> </listener> <servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AxisServlet </servlet-class> </servlet> <servlet> <servlet-name>AdminServlet</servlet-name> <display-name>Axis Admin Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AdminServlet </servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet> <servlet-name>SOAPMonitorService</servlet-name> <display-name>SOAPMonitorService</display-name> <servlet-class> org.apache.axis.monitor.SOAPMonitorService </servlet-class> <init-param> <param-name>SOAPMonitorPort</param-name> <param-value>5001</param-value> </init-param> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>SOAPMonitorService</servlet-name> <url-pattern>/SOAPMonitor</url-pattern> </servlet-mapping> <!-- uncomment this if you want the admin servlet --> <!-- <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> --> <session-config> <!-- Default to 5 minute session timeouts --> <session-timeout>5</session-timeout> </session-config> <!-- currently the W3C havent settled on a media type for WSDL; http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft for now we Go with the basic 'it's XML' response --> <mime-mapping> <extension>wsdl</extension> <mime-type>text/xml</mime-type> </mime-mapping> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> <welcome-file-list id="WelcomeFileList"> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.jws</welcome-file> </welcome-file-list> </web-app>
然后,引入jar包,
在自己下的axis的jar包中,有一些jar包,可以将其全部引入。
我只引入了其中一部分axis.jar,axis-ant.jar,commons-discovery-0.2.jar,commons-logging-1.0.4.jar,jaxrpc.jar,log4j-1.2.8.jar,saaj.jar,wsdl4j-1.5.1.jar,xercesImpl-2.8.1.jar,xmlsec-1.4.5.jar。
然后,将项目部署,启动tomcat,输入http://10.64.59.12:8080/WebService/services,查看页面。
如果出现了
就表示你环境搭建工作已经完成了。可以进入真正的开发了。
3.在src中,建立类:HelloService.java
public class HelloService { public String sayHello(){ return "hello"; } public String sayHelloToPerson(String name){ if(name == "" || name.equals("")){ name = "nobody"; } return "hello " + name; } }
4.其实开发工作就已经完成了,如此简单。下一步,就是将这个发布到webservice上。
编写一个文件:deploy.wsdd
内容如下:
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="HelloServices" provider="java:RPC"> <parameter name="className" value="HelloService"/> //如果将类放在包下,value应写成packagename.className的形式 <parameter name="allowedMethods" value="*"/> </service> </deployment>
把它放在F:\test下,
然后cmd,进入F:test,再输入:
java -cp F:\axis-1_4\lib\axis.jar;F:\axis-1_4\lib\axis-ant.jar;F:\axis-1_4\lib\commons-discovery-0.2.jar;F:\axis-1_4\lib\commons-logging-1.0.4.jar;F:\axis-1_4\lib\jaxrpc.jar;F:\axis-1_4\lib\log4j-1.2.8.jar;F:\axis-1_4\lib\mail-1.4.jar;F:\axis-1_4\lib\saaj.jar;F:\axis-1_4\lib\wsdl4j-1.5.1.jar;F:\axis-1_4\lib\xercesImpl-2.8.1.jar;F:\axis-1_4\lib\xml-apis-1.3.03.jar;F:\axis-1_4\lib\xmlsec-1.4.5.jar;F:\axis-1_4\lib\xmlsecSamples-1.4.5.jar;F:\axis-1_4\lib\xmlsecTests-1.4.5.jar org.apache.axis.client.AdminClient -lhttp://10.64.59.12:8080/WebService/services/AdminService deploy.wsdd
回车,在窗口中下面出现:
Processing file deploy.wsdd <Admin>Done processing</Admin>
就表示你发布成功了。
再在浏览器中输入http://10.64.59.12:8080/WebService/services时,看到
则HelloServices就被成功发布了。
===================================================================================================================================
下面,就是客户端对webservice的访问
写个测试类:
import java.io.IOException; import java.NET.MalformedURLException; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class TestService { private static final Log log = LogFactory.getLog(TestService.class); private static final String HELLO_SERVICE_ENDPOINT = "http://10.64.59.12:8080/WebService/services/HelloServices?wsdl"; /** * 调用sayHello方法 */ public void callSayHello() { try { Service service = new Service(); Call call = (Call) service.createCall(); //传递url call.setTargetEndpointAddress(new java.Net.URL(HELLO_SERVICE_ENDPOINT)); //调用方法名字 call.setOperationName(new QName("http://webservice.sinosoft.com/","sayHello")); call.setReturnType(org.apache.axis.Constants.XSD_STRING); try { //ret即执行方法之后得到的返回值,此处不用传参,故不用写字符串 String ret = (String) call.invoke(new Object[] {}); System.out.println("The return value is:" + ret); return; } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (ServiceException e) { e.printStackTrace(); } log.error("call sayHello service error!"); } /** * 调用sayHelloToPerson方法 */ public void callSayHelloToPerson() { try { Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(new java.net.URL(HELLO_SERVICE_ENDPOINT)); call.setOperationName(new QName("http://webservice.sinosoft.com/","sayHelloToPerson")); call.addParameter("name", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.setReturnType(org.apache.axis.Constants.XSD_STRING); try { //ret即执行方法之后得到的返回值,此处传了一个字符串做为参数,如果不写空,会报错 String ret = (String) call.invoke(new Object[] {"Seven"}); System.out.println("The return value is:" + ret); return; } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (ServiceException e) { e.printStackTrace(); } log.error("call sayHello service error!"); } /** * 调用两个方法 * @param args */ public static void main(String[] args) { TestService tester = new TestService(); tester.callSayHello(); tester.callSayHelloToPerson(); } }
会打印出:
The return value is:hello The return value is:hello Seven
就表示 这个Demo做成功了。
此时,如果修改HelloService.java,执行测试类时,就可以即时响应HelloService.java中的变化了。