1.JAX-WS概述
使用JAX-WS可以很方便快捷地开发和访问WEB服务
JAX-WS2.0全称JAVA API for XML-BASED WEB SERVICE(JAX-WS2.0)
在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP的消息代码,
JAX-WS运行时,将会把这些API调用转换成对于SOAP的消息
JAX-WS是用于简化使用JAVA构造WEB服务和WEB服务客户机的工作技术
2.JAX-WS快速上手-HELLO WORLD实例
2.1 开发WEB-SERVICE服务端--JAXWSHelloWorldServer项目
JAX-WS的服务器端类开发很简单,只需要开发一个普通的POJO类,
并通过JAX-WS的Annotations进行标注即可。
然后使用它的wsgen工具即可导出服务端的辅助类。
1、
2. 创建服务端类HelloWorld.java
JAX-WS的服务器端类可以是任意的POJO类,不同的是需要使用@WebServce标注类为服务类,
并使用@WebMethod标准开发的服务方法
1 package com.demo; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebService; 5 6 @WebService 7 public class HelloWorld { 8 9 @WebMethod 10 public String sayHello(String world){ 11 System.out.println("接受客户端请求:"+world); 12 return "Hello"+world+"!"; 13 } 14 15 }
2.运行wsgen导出服务器端代码
要将HelloWorld.java发布为Web服务,还需要相关辅助类
这些辅助类可以通过JDK命令wsgen自动导出
只需要在项目的目录D:\workspace\JAXWSHelloWorldServer下通过DOS命令执行下面命令即可
1 wsgen -cp bin com.demo.HelloWorld -wsdl -s -src -d bin -r wsdl
-cp属性:指定Class二进制文件的目录为bin
-s属性:指定要生成的JAVA Source文件的位置为src
-d属性:指定要生成的Class 文件位置为bin
-r属性:指定要生成的Resources文件的位置为wsdl,如WSDL,XSD的位置
另外。运行该命令前如果wsdl子目录不存在,需要手动创建后再运行
3.导出文件目录结构
运行导出命令后,就会产生两个java类,并在wsdl产生两个资源文件
4.生成java代码的sayHello.java
该类为服务方法sayHello()生成的服务节点类,作用是用来接受客户端传入的参数,
1 package com.demo.jaxws; 2 3 import javax.xml.bind.annotation.XmlAccessType; 4 import javax.xml.bind.annotation.XmlAccessorType; 5 import javax.xml.bind.annotation.XmlElement; 6 import javax.xml.bind.annotation.XmlRootElement; 7 import javax.xml.bind.annotation.XmlType; 8 9 @XmlRootElement(name = "sayHello", namespace = "http://demo.com/") 10 @XmlAccessorType(XmlAccessType.FIELD) 11 @XmlType(name = "sayHello", namespace = "http://demo.com/") 12 public class SayHello { 13 14 @XmlElement(name = "arg0", namespace = "") 15 private String arg0; 16 17 /** 18 * 19 * @return 20 * returns String 21 */ 22 public String getArg0() { 23 return this.arg0; 24 } 25 26 /** 27 * 28 * @param arg0 29 * the value for the arg0 property 30 */ 31 public void setArg0(String arg0) { 32 this.arg0 = arg0; 33 } 34 35 }
5.生成java代码的sayHelloResponse.java
该类是为服务方法sayHello()生成的服务响应类,作用是用来返回结果对象。
1 package com.demo.jaxws; 2 3 import javax.xml.bind.annotation.XmlAccessType; 4 import javax.xml.bind.annotation.XmlAccessorType; 5 import javax.xml.bind.annotation.XmlElement; 6 import javax.xml.bind.annotation.XmlRootElement; 7 import javax.xml.bind.annotation.XmlType; 8 9 @XmlRootElement(name = "sayHelloResponse", namespace = "http://demo.com/") 10 @XmlAccessorType(XmlAccessType.FIELD) 11 @XmlType(name = "sayHelloResponse", namespace = "http://demo.com/") 12 public class SayHelloResponse { 13 14 @XmlElement(name = "return", namespace = "") 15 private String _return; 16 17 /** 18 * 19 * @return 20 * returns String 21 */ 22 public String getReturn() { 23 return this._return; 24 } 25 26 /** 27 * 28 * @param _return 29 * the value for the _return property 30 */ 31 public void setReturn(String _return) { 32 this._return = _return; 33 } 34 35 }
6.生成的WSDL文件HelloWorldService.wsdl
HelloWorldService.wsdl是用来描述Web服务的文件
其中定义了HelloWorld服务及其接口sayHello的参数和数据类型
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --> <definitions targetNamespace="http://demo.com/" name="HelloWorldService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:tns="http://demo.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <types> <xsd:schema> <xsd:import namespace="http://demo.com/" schemaLocation="HelloWorldService_schema1.xsd"/> </xsd:schema> </types> <message name="sayHello"> <part name="parameters" element="tns:sayHello"/> </message> <message name="sayHelloResponse"> <part name="parameters" element="tns:sayHelloResponse"/> </message> <portType name="HelloWorld"> <operation name="sayHello"> <input wsam:Action="http://demo.com/HelloWorld/sayHelloRequest" message="tns:sayHello"/> <output wsam:Action="http://demo.com/HelloWorld/sayHelloResponse" message="tns:sayHelloResponse"/> </operation> </portType> <binding name="HelloWorldPortBinding" type="tns:HelloWorld"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="sayHello"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="HelloWorldService"> <port name="HelloWorldPort" binding="tns:HelloWorldPortBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions>
7.生成XSD文件的HelloWorldService_schemal.xsd
WSDL文件粗体部分引入了HelloWorldService_schemal.xsd
该文件用来定义传入参数类型SayHello.java和返回结果SayHelloResponse.java的XML数据的类型,
均为xs:string类型
1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2 <xs:schema version="1.0" targetNamespace="http://demo.com/" xmlns:tns="http://demo.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 3 4 <xs:element name="sayHello" type="tns:sayHello"/> 5 6 <xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/> 7 8 <xs:complexType name="sayHello"> 9 <xs:sequence> 10 <xs:element name="arg0" type="xs:string" minOccurs="0"/> 11 </xs:sequence> 12 </xs:complexType> 13 14 <xs:complexType name="sayHelloResponse"> 15 <xs:sequence> 16 <xs:element name="return" type="xs:string" minOccurs="0"/> 17 </xs:sequence> 18 </xs:complexType> 19 </xs:schema>
3.发布Web Service服务
3.1 编写服务器端启动程序HelloWorldService.java
以上编写的Web Service服务器端代码必须发布为WSDL服务后才能够被客户端使用
JAX-WS提供了一个发布Web服务的方法,使用Endpoint的publish方法即可将HelloWorld类的实例发布为一个Web服务地址
1 package com.demo; 2 3 import javax.xml.ws.Endpoint; 4 5 public class HelloWorldServer { 6 7 public static void main(String[] args) { 8 Endpoint.publish("http://localhost:8080/HelloWorldService",new HelloWorld()); 9 } 10 }
其中第一个参数为发布的Web服务地址,第二个参数为发布服务的实例
服务地址为http的形式表示,服务的名称可以自定
服务名通常以类名+Service形式表示
4.启动Web Service服务
直接运行Eclipse中运行HelloWorldServer.java即可发布Web服务
Web服务以WSDL的形式描述,因此可以访问http://localhost:8080/HelloWorldService?WSDL来查看该服务
其中引用了类型定义的地址
http://localhost:8080/HelloWorldService?xsd=1
通过输入该地址也可以查看HelloWorldService_schemal.xsd文件定义的内容
5.开发Web Service客户端--JAXWSHelloWorldClient项目
首先创建JAXWSHelloWorldClient表示客户端项目
1.运行wsimport导出客户端代码
通过JDK的命令wsimport可以自动导出某一个WSDL对应服务地址的客户端辅助类,
只需要在项目目录D:\workspace\JAXWSHelloWorldClient下通过DOS命令行执行下面命令即可
1 wsimport -keep -d bin -s src http://localhost:8080/HelloWorldService?wsdl
其中属性:
-d属性:指定生成Class文件的位置为bin
-s属性:指定要访问的WSDL服务的URL地址
2.导出文件目录结构
运行导出命令
3.生成接口类HelloWorld.java
该类为客户端提供了HelloWorld.java的接口
1 package com.demo; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebParam; 5 import javax.jws.WebResult; 6 import javax.jws.WebService; 7 import javax.xml.bind.annotation.XmlSeeAlso; 8 import javax.xml.ws.Action; 9 import javax.xml.ws.RequestWrapper; 10 import javax.xml.ws.ResponseWrapper; 11 12 13 /** 14 * This class was generated by the JAX-WS RI. 15 * JAX-WS RI 2.2.4-b01 16 * Generated source version: 2.2 17 * 18 */ 19 @WebService(name = "HelloWorld", targetNamespace = "http://demo.com/") 20 @XmlSeeAlso({ 21 ObjectFactory.class 22 }) 23 public interface HelloWorld { 24 25 26 /** 27 * 28 * @param arg0 29 * @return 30 * returns java.lang.String 31 */ 32 @WebMethod 33 @WebResult(targetNamespace = "") 34 @RequestWrapper(localName = "sayHello", targetNamespace = "http://demo.com/", className = "com.demo.SayHello") 35 @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://demo.com/", className = "com.demo.SayHelloResponse") 36 @Action(input = "http://demo.com/HelloWorld/sayHelloRequest", output = "http://demo.com/HelloWorld/sayHelloResponse") 37 public String sayHello( 38 @WebParam(name = "arg0", targetNamespace = "") 39 String arg0); 40 41 }
4.生成实现类HelloWorldService.java
该类已经连接到远程的WSDL服务,通过该方法getHelloWorldPort()取得HelloWorld对象
1 package com.demo; 2 3 import java.net.MalformedURLException; 4 import java.net.URL; 5 import javax.xml.namespace.QName; 6 import javax.xml.ws.Service; 7 import javax.xml.ws.WebEndpoint; 8 import javax.xml.ws.WebServiceClient; 9 import javax.xml.ws.WebServiceException; 10 import javax.xml.ws.WebServiceFeature; 11 12 13 /** 14 * This class was generated by the JAX-WS RI. 15 * JAX-WS RI 2.2.4-b01 16 * Generated source version: 2.2 17 * 18 */ 19 @WebServiceClient(name = "HelloWorldService", targetNamespace = "http://demo.com/", wsdlLocation = "http://localhost:8080/HelloWorldService?wsdl") 20 public class HelloWorldService 21 extends Service 22 { 23 24 private final static URL HELLOWORLDSERVICE_WSDL_LOCATION; 25 private final static WebServiceException HELLOWORLDSERVICE_EXCEPTION; 26 private final static QName HELLOWORLDSERVICE_QNAME = new QName("http://demo.com/", "HelloWorldService"); 27 28 static { 29 URL url = null; 30 WebServiceException e = null; 31 try { 32 url = new URL("http://localhost:8080/HelloWorldService?wsdl"); 33 } catch (MalformedURLException ex) { 34 e = new WebServiceException(ex); 35 } 36 HELLOWORLDSERVICE_WSDL_LOCATION = url; 37 HELLOWORLDSERVICE_EXCEPTION = e; 38 } 39 40 public HelloWorldService() { 41 super(__getWsdlLocation(), HELLOWORLDSERVICE_QNAME); 42 } 43 44 public HelloWorldService(WebServiceFeature... features) { 45 super(__getWsdlLocation(), HELLOWORLDSERVICE_QNAME, features); 46 } 47 48 public HelloWorldService(URL wsdlLocation) { 49 super(wsdlLocation, HELLOWORLDSERVICE_QNAME); 50 } 51 52 public HelloWorldService(URL wsdlLocation, WebServiceFeature... features) { 53 super(wsdlLocation, HELLOWORLDSERVICE_QNAME, features); 54 } 55 56 public HelloWorldService(URL wsdlLocation, QName serviceName) { 57 super(wsdlLocation, serviceName); 58 } 59 60 public HelloWorldService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { 61 super(wsdlLocation, serviceName, features); 62 } 63 64 /** 65 * 66 * @return 67 * returns HelloWorld 68 */ 69 @WebEndpoint(name = "HelloWorldPort") 70 public HelloWorld getHelloWorldPort() { 71 return super.getPort(new QName("http://demo.com/", "HelloWorldPort"), HelloWorld.class); 72 } 73 74 /** 75 * 76 * @param features 77 * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values. 78 * @return 79 * returns HelloWorld 80 */ 81 @WebEndpoint(name = "HelloWorldPort") 82 public HelloWorld getHelloWorldPort(WebServiceFeature... features) { 83 return super.getPort(new QName("http://demo.com/", "HelloWorldPort"), HelloWorld.class, features); 84 } 85 86 private static URL __getWsdlLocation() { 87 if (HELLOWORLDSERVICE_EXCEPTION!= null) { 88 throw HELLOWORLDSERVICE_EXCEPTION; 89 } 90 return HELLOWORLDSERVICE_WSDL_LOCATION; 91 } 92 93 }
5.生成对象工厂类ObjectFactory.java
该类用以创建输入参数和结果字符串的对象
1 package com.demo; 2 3 import javax.xml.bind.JAXBElement; 4 import javax.xml.bind.annotation.XmlElementDecl; 5 import javax.xml.bind.annotation.XmlRegistry; 6 import javax.xml.namespace.QName; 7 8 9 /** 10 * This object contains factory methods for each 11 * Java content interface and Java element interface 12 * generated in the com.demo package. 13 * <p>An ObjectFactory allows you to programatically 14 * construct new instances of the Java representation 15 * for XML content. The Java representation of XML 16 * content can consist of schema derived interfaces 17 * and classes representing the binding of schema 18 * type definitions, element declarations and model 19 * groups. Factory methods for each of these are 20 * provided in this class. 21 * 22 */ 23 @XmlRegistry 24 public class ObjectFactory { 25 26 private final static QName _SayHello_QNAME = new QName("http://demo.com/", "sayHello"); 27 private final static QName _SayHelloResponse_QNAME = new QName("http://demo.com/", "sayHelloResponse"); 28 29 /** 30 * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.demo 31 * 32 */ 33 public ObjectFactory() { 34 } 35 36 /** 37 * Create an instance of {@link SayHelloResponse } 38 * 39 */ 40 public SayHelloResponse createSayHelloResponse() { 41 return new SayHelloResponse(); 42 } 43 44 /** 45 * Create an instance of {@link SayHello } 46 * 47 */ 48 public SayHello createSayHello() { 49 return new SayHello(); 50 } 51 52 /** 53 * Create an instance of {@link JAXBElement }{@code <}{@link SayHello }{@code >}} 54 * 55 */ 56 @XmlElementDecl(namespace = "http://demo.com/", name = "sayHello") 57 public JAXBElement<SayHello> createSayHello(SayHello value) { 58 return new JAXBElement<SayHello>(_SayHello_QNAME, SayHello.class, null, value); 59 } 60 61 /** 62 * Create an instance of {@link JAXBElement }{@code <}{@link SayHelloResponse }{@code >}} 63 * 64 */ 65 @XmlElementDecl(namespace = "http://demo.com/", name = "sayHelloResponse") 66 public JAXBElement<SayHelloResponse> createSayHelloResponse(SayHelloResponse value) { 67 return new JAXBElement<SayHelloResponse>(_SayHelloResponse_QNAME, SayHelloResponse.class, null, value); 68 } 69 70 }
6.编写客户端类HelloWorldClient.java
产生以上的辅助类后,就可以编写客户端来访问WEB服务了
根据HelloWorldService的getHelloWorldPort()方法取得HelloWorld实例
该实例即可以实现对远程Web服务的调用
1 package com.demo; 2 3 public class HelloWorldClient { 4 5 public static void main(String[] args) { 6 //创建客户端 7 HelloWorld hello = new HelloWorldService().getHelloWorldPort(); 8 //调用Web服务 9 System.out.println(hello.sayHello("world")); 10 } 11 }
7.运行客户端类
此时运行HelloWorldClient即会输出如下信息:
6.打包JAXWSHelloWorldServer.zip和JAXWSHelloWorldClient.zip
可直接导入项目运行它
浙公网安备 33010602011771号