我们使用JAX-WS建立一个简单的 WEB 服务 ,建立业务逻辑代码 ,就是暴露给客户的 服务的代码.
到这里下载 JAX-WS 2.0的 包: https://jax-ws.dev.java.net/
- package com.birds.ws;
- import javax.jws.WebMethod;
- import javax.jws.WebService;
- /**
- * @author birds
- * @since Nov 27, 2008 9:20:16 PM
- */
- @WebService
- public class HelloQuick {
- public HelloQuick() {
- }
- @WebMethod
- public String show() {
- return "SHOW YOU!";
- }
- }
- // 上面的代码,足够简单, 在HelloQuick类上面 ,有一个 Annotation修饰 @WebService
- 这个修饰必须是 javax.jws.WebService ,
javax.jws.WebServiceProvider
其中一个, - 默认构造函数必须有一个。
- 业务方法 show() 函数上面有一个 @WebMethod修饰,,如果这个函数有参数,就需要增加参数的修饰
- 比方说: show(@WebParam(name = "msg") String msg){} 多了一个参数
- 知道更多的细节,参考 jax-ws的文档,
建立环境 : 这里使用 Tomcat 6.0
需要编写 配置 webapps/jaxws2/WEB-INF/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">
- <listener>
- <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
- </listener>
- <servlet>
- <servlet-name>fish</servlet-name>
- <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>fish</servlet-name>
- <url-pattern>/quick</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
WSServletContextListener ,和 WSServlet 都是 系统运行需要的配置,
还需要建立一个 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='fish' implementation='com.birds.ws.HelloQuick'
- url-pattern='/quick' />
- </endpoints>
- <!--
- endpoint 一个端点,代表了一个服务,
- name = fish
- url-pattern="/quick"
- -->
下面是 com.sun.xml.ws.transport.http.servlet.WSServletContextListener 加载/WEB-INF/sun-jaxws.xml
是 jax-ws 的源代码。
- try {
- // Parse the descriptor file and build endpoint infos
- DeploymentDescriptorParser<ServletAdapter> parser = new DeploymentDescriptorParser<ServletAdapter>(
- classLoader,new ServletResourceLoader(context), createContainer(context), new ServletAdapterList());
- URL sunJaxWsXml = context.getResource(JAXWS_RI_RUNTIME);
- if(sunJaxWsXml==null)
- throw new WebServiceException(WsservletMessages.NO_SUNJAXWS_XML(JAXWS_RI_RUNTIME));
- List<ServletAdapter> adapters = parser.parse(sunJaxWsXml.toExternalForm(), sunJaxWsXml.openStream());
- delegate = createDelegate(adapters, context);
- context.setAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO,delegate);
- } catch (Throwable e) {
- logger.log(Level.SEVERE,
- WsservletMessages.LISTENER_PARSING_FAILED(e),e);
- context.removeAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO);
- throw new WSServletException("listener.parsingFailed", e);
- }
- // JAXWS_RI_RUNTIME 为 /WEB-INF/sun-jaxws.xml
- 这个监听器 主要是 解析 endpoints ,
- delegate = createDelegate(adapters, context);
- context.setAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO,delegate);
- 这两行代码 把解析的 endpoint 结果 放入 session中 ,给后面的 WSServlet使用,
- 下面是
- com.sun.xml.ws.transport.http.servlet.WSServlet 部分源代码.
- public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
delegate = getDelegate(servletConfig);
} - // 这个地方就是取出 上面监听器 解析sun-jaxws.xml 结果,
- delegate 这个是 主要处理大部分逻辑的代码 ,是 WSServletDelegate类
- 看 WSServelt 的doPost方法,将会调用
- protected void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException {
if (delegate != null) {
delegate.doPost(request,response,getServletContext());
}
} - 这里便会访问到 WSServletDelegate 的doPost方法
- 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");
} - 这部分代码 开始处理请求 并且生成WSDL服务
- 当tomcat启动成功后 在浏览器中输入
- http://localhost:8080/jaxws2/quick?wsdl
- 将会显示 WSDL xml服务结果.
- <definitions targetNamespace="http://ws.birds.com/" name="HelloQuickService">
- −
- <types>
- −
- <xsd:schema>
- <xsd:import namespace="http://ws.birds.com/" schemaLocation="http://localhost:8080/jaxws2/quick?xsd=1"/>
- </xsd:schema>
- </types>
- −
- <message name="show">
- <part name="parameters" element="tns:show"/>
- </message>
- −
- <message name="showResponse">
- <part name="parameters" element="tns:showResponse"/>
- </message>
- −
- <portType name="HelloQuick">
- −
- <operation name="show">
- <input message="tns:show"/>
- <output message="tns:showResponse"/>
- </operation>
- </portType>
- −
- <binding name="HelloQuickPortBinding" type="tns:HelloQuick">
- <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
- −
- <operation name="show">
- <soap:operation soapAction=""/>
- −
- <input>
- <soap:body use="literal"/>
- </input>
- −
- <output>
- <soap:body use="literal"/>
- </output>
- </operation>
- </binding>
- <service name="HelloQuickService">
- <port name="HelloQuickPort" binding="tns:HelloQuickPortBinding">
- <soap:address location="http://localhost:8080/jaxws2/quick"/>
- </port>
- </service>
- </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.class
Show.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 应用。