开发JAX-WS 2.0 Web服务

实现一个Web服务的过程,大概有3个基本的过程:

  • Web服务提供者设计并开发Web服务
  • Web服务提供者发布Web服务
  • Web服务请求者调用Web服务

下面,我通过一个例子,来实现上述过程:
假设一个Web服务提供者提供一个对域名进行探测解析的服务,给定一个域名,可以给出改域名解析后对应的IP地址列表。Web服务提供者设计并开发这个Web服务,然后将服务发布出去,并可以让Web服务请求者进行调用。

开发Web服务

服务接口文件DetectionService.java代码如下所示:

package org.shirdrn.server.webservices.jaxws;
 
public interface DetectService {
       DetectedResult detect(String domain); 
}

对应的实现类DomainDetectionService.java,如下所示:

package org.shirdrn.server.webservices.jaxws;
 
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
 
import org.xbill.DNS.Address;
 
@WebService(serviceName = "DomainDetector",portName = "DomainDetectorPort",  
targetNamespace = "http://ws.shirdrn.org/jaxws/WSDomainDetector")
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
public class DomainDetectService implements DetectService {
 
       @WebMethod
       public DetectedResult detect(String domain) {
              DetectedResult result = new DetectedResult();
              result.setStartTime(new Date());
              try {
                     InetAddress[] addresses = Address.getAllByName(domain);
                     for(InetAddress addr : addresses) {
                            result.getIpAddresses().add(addr.getHostAddress());
                     }
              } catch (UnknownHostException e) {
                     e.printStackTrace();
              } finally {
                     result.setFinishTime(new Date());
                     result.setTimeTaken(result.getFinishTime().getTime() - result.getStartTime().getTime());
              }
              return result;
       }
 
}

上面用到一个DtectedResult类,如下所示:

package org.shirdrn.server.webservices.jaxws;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
public class DetectedResult {
 
       private Date startTime;
       private Date finishTime;
       private long timeTaken;
       private List<String> ipAddresses = new ArrayList<String>();
 
       public Date getStartTime() {
              return startTime;
       }
 
       public void setStartTime(Date startTime) {
              this.startTime = startTime;
       }
 
       public Date getFinishTime() {
              return finishTime;
       }
 
       public void setFinishTime(Date finishTime) {
              this.finishTime = finishTime;
       }
 
       public long getTimeTaken() {
              return timeTaken;
       }
 
       public void setTimeTaken(long timeTaken) {
              this.timeTaken = timeTaken;
       }
 
       public List<String> getIpAddresses() {
              return ipAddresses;
       }
       
       public void setIpAddresses(List<String> ipAddresses) {
              this.ipAddresses = ipAddresses;
       }
 
}

生成Web Service描述文件(WSDL),如下所示:

shirdrn@SYJ:~$ cd ~/programs/eclipse-java-juno/workspace/self_practice/bin
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ wsgen -cp . org.shirdrn.server.webservices.jaxws.DomainDetectService -wsdl
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ ls
com DomainDetector_schema1.xsd DomainDetector.wsdl log4j.properties main org server.xml test
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ cp DomainDetect* /home/shirdrn/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/server/webservices/jaxws/wsdl

经过上面步骤,生成了两个文件:DomainDetect_schema1.xsd和DomainDetect.wsdl,内容分别如下所示:

  • DomainDetector_schema1.xsd内容
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
       xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
       <xs:element name="detect" type="tns:detect" />
 
       <xs:element name="detectResponse" type="tns:detectResponse" />
 
       <xs:complexType name="detect">
              <xs:sequence>
                     <xs:element name="arg0" type="xs:string" minOccurs="0" />
              </xs:sequence>
       </xs:complexType>
 
       <xs:complexType name="detectResponse">
              <xs:sequence>
                     <xs:element name="return" type="tns:detectedResult" minOccurs="0" />
              </xs:sequence>
       </xs:complexType>
 
       <xs:complexType name="detectedResult">
              <xs:sequence>
                     <xs:element name="finishTime" type="xs:dateTime" minOccurs="0" />
                     <xs:element name="ipAddresses" type="xs:string" nillable="true"
                            minOccurs="0" maxOccurs="unbounded" />
                     <xs:element name="startTime" type="xs:dateTime" minOccurs="0" />
                     <xs:element name="timeTaken" type="xs:long" />
              </xs:sequence>
       </xs:complexType>
</xs:schema>
  • DomainDetector.wsdl内容
<?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.1.6 in JDK 6. -->
<definitions targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
       name="DomainDetector" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
       <types>
              <xsd:schema>
                     <xsd:import namespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
                            schemaLocation="DomainDetector_schema1.xsd" />
              </xsd:schema>
       </types>
       <message name="detect">
              <part name="parameters" element="tns:detect" />
       </message>
       <message name="detectResponse">
              <part name="parameters" element="tns:detectResponse" />
       </message>
       <portType name="DomainDetectService">
              <operation name="detect">
                     <input message="tns:detect" />
                     <output message="tns:detectResponse" />
              </operation>
       </portType>
       <binding name="DomainDetectorPortBinding" type="tns:DomainDetectService">
              <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
                     style="document" />
              <operation name="detect">
                     <soap:operation soapAction="" />
                     <input>
                            <soap:body use="literal" />
                     </input>
                     <output>
                            <soap:body use="literal" />
                     </output>
              </operation>
       </binding>
       <service name="DomainDetector">
              <port name="DomainDetectorPort" binding="tns:DomainDetectorPortBinding">
                     <soap:address location="REPLACE_WITH_ACTUAL_URL" />
              </port>
       </service>
</definitions>

可以看到,在wsdl文件中通过import引用了前面的schema文件,这个schema文件用于定义类型。

发布Web服务

我们可以发布我们上面开发的Web服务,代码如下所示:

package org.shirdrn.server.webservices.jaxws;
 
import javax.xml.ws.Endpoint;
 
public class PublishingServer {
 
       
       public static void main(String[] args) {
              String address = "http://172.0.8.212:9033/ws/services/DomainDetectService";
              DetectService domainDetectService = new DomainDetectService();
              
              Endpoint.publish(address, domainDetectService);
       }
 
}

可以查看本地运行的Web服务进程:

shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/server/webservices/jaxws$ sudo netstat -nap | grep 9033
tcp6       0      0 172.0.8.212:9033        :::*                    LISTEN      8302/java      
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/server/webservices/jaxws$ jps
8302 PublishingServer
8358 Jps

可见,服务发布成功。
也可以在浏览器中打开链接:http://172.0.8.212:9033/ws/services/DomainDetectService?wsdl,就能看到发布的WSDL,内容如下所示:

<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is  JAX-WS RI 2.1.6 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is  JAX-WS RI 2.1.6 in JDK 6. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
	name="DomainDetector">
	<types>
		<xsd:schema>
			<xsd:import namespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
				schemaLocation="http://172.0.8.212:9033/ws/services/DomainDetectService?xsd=1" />
		</xsd:schema>
	</types>
	<message name="detect">
		<part name="parameters" element="tns:detect" />
	</message>
	<message name="detectResponse">
		<part name="parameters" element="tns:detectResponse" />
	</message>
	<portType name="DomainDetectService">
		<operation name="detect">
			<input message="tns:detect" />
			<output message="tns:detectResponse" />
		</operation>
	</portType>
	<binding name="DomainDetectorPortBinding" type="tns:DomainDetectService">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
			style="document" />
		<operation name="detect">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
	</binding>
	<service name="DomainDetector">
		<port name="DomainDetectorPort" binding="tns:DomainDetectorPortBinding">
			<soap:address
				location="http://172.0.8.212:9033/ws/services/DomainDetectService" />
		</port>
	</service>
</definitions>

调用Web服务

首先要根据服务提供者发布的Web服务,生成服务请求者客户端代码,如下所示:

shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ wsimport -keep -p org.shirdrn.client.webservices.jaxws http://172.0.8.212:9033/ws/services/DomainDetectService?wsdl
parsing WSDL...

generating code...

compiling code...
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ cd org/shirdrn/client/webservices/jaxws/
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin/org/shirdrn/client/webservices/jaxws$ cp *.java /home/shirdrn/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/client/webservices/jaxws
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin/org/shirdrn/client/webservices/jaxws$ cd ~/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/client/webservices/jaxws/
shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/client/webservices/jaxws$ ls
DetectedResult.java  DetectResponse.java      DomainDetector.java       ObjectFactory.java
Detect.java      DomainDetectService.java  package-info.java

上面自动生成了客户端代码的骨架,如下几个文件:

  • DetectedResult.java
  • DetectResponse.java
  • DomainDetector.java
  • ObjectFactory.java
  • Detect.java
  • DomainDetectService.java
  • package-info.java

基于这些代码,就可以实现服务请求者对服务提供者发布服务的调用。我们实现了一个简单的调用,代码如下所示:

package org.shirdrn.client.webservices.jaxws;
 
public class DomainDetectClient {
 
       public static void main(String[] args) {
              DomainDetector detector = new DomainDetector();
              String domain = "baidu.com";
              DetectedResult result = detector.getDomainDetectorPort().detect(domain);
              System.out.println(result.getIpAddresses());
       }
 
}

调用后可以返回对域名进行解析后得到的IP地址列表,结果如下所示:

 [220.181.111.86, 123.125.114.144, 220.181.111.85]

到此为止,我们完成了一个简单的Web Service的开发、发布、调用的过程。

参考链接

Creative Commons License

本文基于署名-非商业性使用-相同方式共享 4.0许可协议发布,欢迎转载、使用、重新发布,但务必保留文章署名时延军(包含链接:http://shiyanjun.cn),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>