在之前的介绍里,web service的发布都是通过调用:
- Endpoint.publish()??
方法来启动一个java内嵌的web容器来实现的。
?
这里要介绍一下怎么把生成的web service部署到一个web容器中去。
?
还是以之前的计算器的例子为例。首先我们用wsgen工具去生成部署所需要的所有部件:
?
- wsgen?-wsdl?-keep?-d?../output?-cp?.?test.CalculatorImpl???
运行此命令时,我得到了一个错误信息:
- The?@javax.jws.WebService.name?element?cannot?be?used?in?with?@javax.jws.WebService.endpointInterface?element??
意思是?name 属性和 endpointInterface 属性不能同时出现,只好把CalculatorImpl里的name属性先删除,回头查一下为什么会有这个错误。
?
运行完上面命令行后,我们就得到一些新文件:
- CalculatorImplService.wsdl
- CalculatorImplService_schema1.xsd
- Add.java
- AddResponse.java
- Multi.java
- MultiResponse.java
把他们拷到工程里去先,其中:
- 所有的java文件和到源码里去
- 新建一个wsdl目录,把wsdl文件和xsd文件放到此目录中去。
剩下的就是怎么提供一个web.xml了,使得对url的访问能被我们的web service实现类处理请求了。
?
下载:
?以前一直都是基于JDK自带的api来实现的,下面就需要用到一些jax-ws提供的lib包了。所以需要先去下一份jax-ws的实现,例如我当前使用的2.2.5的下载地址是:
http://jax-ws.java.net/2.2.5/
?
实现方式:
sun的jax-ws实现提供了两个类用来配置web容器的web.xml,实现从url到web service实现类的映射:
- 监听类:com.sun.xml.ws.transport.http.servlet.WSServletContextListener
- Servlet: com.sun.xml.ws.transport.http.servlet.WSServlet
?
其中WSServletContextListener又会去查找和web.xml在同一级目录下的另一个文件sun-jaxws.xml,整个过程的流程图大约为:
?
sun-jaxws.xml文件的schema可以在下载的jax-ws RI的docs目录下找着(sun-jaxws.xsd)。
?
这里直接给出calculator的web.xml和sun-jaxws.xml的一个实现:
?
- <?xml?version="1.0"?encoding="UTF-8"?> ??
- <endpoints?xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"??
- ????version="2.0"> ??
- ????<endpoint?name="calculator"?implementation="test.CalculatorImpl"??
- ????????url-pattern="/calculator"?/> ??
- </endpoints>???
?
- <?xml?version="1.0"?encoding="UTF-8"?> ??
- <!DOCTYPE?web-app?PUBLIC?"-//Sun?Microsystems,? ??
- Inc.//DTD?Web?Application?2.3//EN" ??
- "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> ??
- ? ??
- <web-app> ??
- ????<listener> ??
- ????????<listener-class> ??
- ????????????????com.sun.xml.ws.transport.http.servlet.WSServletContextListener ??
- ????????</listener-class> ??
- ????</listener> ??
- ????<servlet> ??
- ????????<servlet-name>calculator</servlet-name> ??
- ????????<servlet-class> ??
- ????????????com.sun.xml.ws.transport.http.servlet.WSServlet ??
- ????????</servlet-class> ??
- ????????<load-on-startup>1</load-on-startup> ??
- ????</servlet> ??
- ????<servlet-mapping> ??
- ????????<servlet-name>calculator</servlet-name> ??
- ????????<url-pattern>/calculator</url-pattern> ??
- ????</servlet-mapping> ??
- ????<session-config> ??
- ????????<session-timeout>120</session-timeout> ??
- ????</session-config> ??
- </web-app>???
按照上面的流程图就可以很清楚的理解了:
?
在初始化期间,WSServletContextListener会读取WEB-INF目录下的 sun-jaxws.xml和web.xml,将web service的实现类与某个url进行绑定,这个绑定是通过一个WSServlet类间接进行的。每次来一个请求后,WSServletContextListener就会进行拦截,根据请求的url,找到对应的web service的实现,调用其他方法。
?
依赖包
很显然,诸如 WSServletContextListener 和 WSServlet 类并不是java缺省自带的。这些类在下载的jax-ws RI的lib目录下的jar里,所以要想真正成功的运行这些web service,我们也需要把必需的依赖包加上,它们包括:
- gmbal-api-only.jar
- ha-api.jar
- jaxb-impl.jar
- jaxws-api.jar
- jaxws-rt.jar
- management-api.jar
- policy.jar
- stax-ex.jar
- streambuffer.jar
打包
打包就不具体介绍了,总之包的结构如下:
?
?
参考:http://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/