您的位置:首页 > 其它

WSServletContextListener jax-ws 源码分析

2016-03-10 16:05 218 查看
1.package com.birds.ws;
2.
3.import javax.jws.WebMethod;
4.import javax.jws.WebService;
5.
6./**
7. * @author birds
8. * @since Nov 27, 2008 9:20:16 PM
9. */
10.@WebService
11.public class HelloQuick {
12. public HelloQuick() {
13. }
14. @WebMethod
15. public String show() {
16. return "SHOW YOU!";
17. }
18.
19.}
20.// 上面的代码,足够简单, 在HelloQuick类上面 ,有一个 Annotation修饰 @WebService
21.这个修饰必须是 javax.jws.WebService , javax.jws.WebServiceProvider 其中一个,
22.默认构造函数必须有一个。
23.业务方法 show() 函数上面有一个 @WebMethod修饰,,如果这个函数有参数,就需要增加参数的修饰
24.比方说: show(@WebParam(name = "msg") String msg){} 多了一个参数
25.知道更多的细节,参考 jax-ws的文档,

建立环境 : 这里使用 Tomcat 6.0

需要编写 配置 webapps/jaxws2/WEB-INF/Web.xml

27.<?xml version="1.0" encoding="UTF-8"?>
28.<web-app version="2.5"
29. xmlns="http://java.sun.com/xml/ns/javaee"
30. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
31. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
32. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
33.
34. <listener>
35. <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
36. </listener>
37.
38. <servlet>
39. <servlet-name>fish</servlet-name>
40. <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
41. </servlet>
42.
43. <servlet-mapping>
44. <servlet-name>fish</servlet-name>
45. <url-pattern>/quick</url-pattern>
46. </servlet-mapping>
47.
48. <welcome-file-list>
49. <welcome-file>index.jsp</welcome-file>
50. </welcome-file-list>
51.</web-app>

WSServletContextListener ,和 WSServlet 都是 系统运行需要的配置,

还需要建立一个 sun-jaxws.xml

54.<?xml version="1.0" encoding="UTF-8"?>
55.<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
56. version='2.0'>
57. <endpoint name='fish' implementation='com.birds.ws.HelloQuick'
58. url-pattern='/quick' />
59.</endpoints>
60.
61.<!--
62. endpoint 一个端点,代表了一个服务,
63. name = fish
64. url-pattern="/quick"
65.
66. -->

下面是 com.sun.xml.ws.transport.http.servlet.WSServletContextListener 加载/WEB-INF/sun-jaxws.xml

是 jax-ws 的源代码。

70. try {
71. // Parse the descriptor file and build endpoint infos
72. DeploymentDescriptorParser<ServletAdapter> parser = new DeploymentDescriptorParser<ServletAdapter>(
73. classLoader,new ServletResourceLoader(context), createContainer(context), new ServletAdapterList());
74. URL sunJaxWsXml = context.getResource(JAXWS_RI_RUNTIME);
75. if(sunJaxWsXml==null)
76. throw new WebServiceException(WsservletMessages.NO_SUNJAXWS_XML(JAXWS_RI_RUNTIME));
77. List<ServletAdapter> adapters = parser.parse(sunJaxWsXml.toExternalForm(), sunJaxWsXml.openStream());
78.
79. delegate = createDelegate(adapters, context);
80.
81. context.setAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO,delegate);
82.
83. } catch (Throwable e) {
84. logger.log(Level.SEVERE,
85. WsservletMessages.LISTENER_PARSING_FAILED(e),e);
86. context.removeAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO);
87. throw new WSServletException("listener.parsingFailed", e);
88. }
89. // JAXWS_RI_RUNTIME 为 /WEB-INF/sun-jaxws.xml
90.这个监听器 主要是 解析 endpoints ,
91. delegate = createDelegate(adapters, context);
92. context.setAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO,delegate);
93. 这两行代码 把解析的 endpoint 结果 放入 session中 ,给后面的 WSServlet使用,
94. 下面是
95.com.sun.xml.ws.transport.http.servlet.WSServlet 部分源代码.
96.
97.public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
delegate = getDelegate(servletConfig);
}
98.// 这个地方就是取出 上面监听器 解析sun-jaxws.xml 结果,
99.delegate 这个是 主要处理大部分逻辑的代码 ,是 WSServletDelegate类
100.看 WSServelt 的doPost方法,将会调用
101.protected void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException {
if (delegate != null) {
delegate.doPost(request,response,getServletContext());
}
}
102.这里便会访问到 WSServletDelegate 的doPost方法
103. ServletAdapter target = getTarget(request);
if (target != null) {
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
WsservletMessages.SERVLET_TRACE_GOT_REQUEST_FOR_ENDPOINT(target.name));
}
target.handle(context, request, response);
} else {
Localizer localizer = getLocalizerFor(request);
writeNotFoundErrorPage(localizer, response, "Invalid Request");
}
104.这部分代码 开始处理请求 并且生成WSDL服务
105.当tomcat启动成功后 在浏览器中输入
106.http://localhost:8080/jaxws2/quick?wsdl
107.将会显示 WSDL xml服务结果.
108.
109.

109.<definitions targetNamespace="http://ws.birds.com/" name="HelloQuickService">
110.−
111. <types>
112.−
113. <xsd:schema>
114.<xsd:import namespace="http://ws.birds.com/" schemaLocation="http://localhost:8080/jaxws2/quick?xsd=1"/>
115.</xsd:schema>
116.</types>
117.−
118. <message name="show">
119.<part name="parameters" element="tns:show"/>
120.</message>
121.−
122. <message name="showResponse">
123.<part name="parameters" element="tns:showResponse"/>
124.</message>
125.−
126. <portType name="HelloQuick">
127.−
128. <operation name="show">
129.<input message="tns:show"/>
130.<output message="tns:showResponse"/>
131.</operation>
132.</portType>
133.−
134. <binding name="HelloQuickPortBinding" type="tns:HelloQuick">
135.<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
136.−
137. <operation name="show">
138.<soap:operation soapAction=""/>
139.−
140. <input>
141.<soap:body use="literal"/>
142.</input>
143.−
144. <output>
145.<soap:body use="literal"/>
146.</output>
147.</operation>
148.</binding>
149.
150. <service name="HelloQuickService">
151.
152. <port name="HelloQuickPort" binding="tns:HelloQuickPortBinding">
153.<soap:address location="http://localhost:8080/jaxws2/quick"/>
154.</port>
155.</service>
156.</definitions>

上面的tomcat 6.0可能启动有错误 ,,这个需要把jax-ws 需要的几个包复制到 tomcat6.0/endorsed 目录下,这个目录原本没有,需要自己创建,主要是覆盖java虚拟机默认的 加载jaxb-api.jar ,

可以看看 http://java.sun.com/j2se/1.5.0/docs/guide/standards/index.html

如果不是用tomcat做服务发布的话, 用普通的java命令的话 需要在java安装目录下 建立 这个endorsed目录,把jar包放到下面,

jdk1.5 把叫做 " Endorsed Standards Override Mechanism ".

// 下面是 客户端代码 ,用来调用创建好的服务

// 用 jdk提供的 wsimport 的命令 来生成 对应的客户端服务代码,,也可以自己编写,如果你很清楚 jax-ws的机制。
wsimport -p com.birds.ws.myclient.HelloServices http://localhost:8080/jaxws2/quick?wsdl-p 选项是 可以帮你生成包名. 生成了六个文件HelloQuick.class, HelloQuickService.class,ObjectFactory.class,package-info.classShow.class, ShowResponse.class如果想看到源代码 可以加上 -keep 选项,以上就可以方面的创建 客户端服务代码,不用自己手工编写 下面就很容易的调用。public static void main(String[] args) { HelloQuickService HelloQuickService = new HelloQuickService(); HelloQuick quick = HelloQuickService.getHelloQuickPort(); System.out.println(quick.show()); }这样就是一个简单的jax-ws 应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: