开发JAX-WS 2.0 Web服务

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

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

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

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

开发Web服务

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

1 package org.shirdrn.server.webservices.jaxws;
2
3 public interface DetectService {
4 DetectedResult detect(String domain);
5 }

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

01 package org.shirdrn.server.webservices.jaxws;
02
03 import java.net.InetAddress;
04 import java.net.UnknownHostException;
05 import java.util.Date;
06
07 import javax.jws.WebMethod;
08 import javax.jws.WebService;
09 import javax.jws.soap.SOAPBinding;
10
11 import org.xbill.DNS.Address;
12
13 @WebService(serviceName = "DomainDetector",portName = "DomainDetectorPort",
14 targetNamespace = "http://ws.shirdrn.org/jaxws/WSDomainDetector")
15 @SOAPBinding(style=SOAPBinding.Style.DOCUMENT,use=SOAPBinding.Use.LITERAL,
16 parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
17 public class DomainDetectService implements DetectService {
18
19 @WebMethod
20 public DetectedResult detect(String domain) {
21 DetectedResult result = new DetectedResult();
22 result.setStartTime(new Date());
23 try {
24 InetAddress[] addresses = Address.getAllByName(domain);
25 for(InetAddress addr : addresses) {
26 result.getIpAddresses().add(addr.getHostAddress());
27 }
28 } catch (UnknownHostException e) {
29 e.printStackTrace();
30 } finally {
31 result.setFinishTime(new Date());
32 result.setTimeTaken(result.getFinishTime().getTime() - result.getStartTime().getTime());
33 }
34 return result;
35 }
36
37 }

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

01 package org.shirdrn.server.webservices.jaxws;
02
03 import java.util.ArrayList;
04 import java.util.Date;
05 import java.util.List;
06
07 public class DetectedResult {
08
09 private Date startTime;
10 private Date finishTime;
11 private long timeTaken;
12 private List<String> ipAddresses = new ArrayList<String>();
13
14 public Date getStartTime() {
15 return startTime;
16 }
17
18 public void setStartTime(Date startTime) {
19 this.startTime = startTime;
20 }
21
22 public Date getFinishTime() {
23 return finishTime;
24 }
25
26 public void setFinishTime(Date finishTime) {
27 this.finishTime = finishTime;
28 }
29
30 public long getTimeTaken() {
31 return timeTaken;
32 }
33
34 public void setTimeTaken(long timeTaken) {
35 this.timeTaken = timeTaken;
36 }
37
38 public List<String> getIpAddresses() {
39 return ipAddresses;
40 }
41
42 public void setIpAddresses(List<String> ipAddresses) {
43 this.ipAddresses = ipAddresses;
44 }
45
46 }

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

1 shirdrn@SYJ:~$ cd ~/programs/eclipse-java-juno/workspace/self_practice/bin
2 shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ wsgen -cp . org.shirdrn.server.webservices.jaxws.DomainDetectService -wsdl
3 shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ ls
4 com DomainDetector_schema1.xsd DomainDetector.wsdl log4j.properties main org server.xml test
5 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内容
01 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
02 <xs:schema version="1.0"targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
03 xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector"xmlns:xs="http://www.w3.org/2001/XMLSchema">
04
05 <xs:element name="detect" type="tns:detect" />
06
07 <xs:element name="detectResponse" type="tns:detectResponse" />
08
09 <xs:complexType name="detect">
10 <xs:sequence>
11 <xs:element name="arg0" type="xs:string" minOccurs="0" />
12 </xs:sequence>
13 </xs:complexType>
14
15 <xs:complexType name="detectResponse">
16 <xs:sequence>
17 <xs:element name="return" type="tns:detectedResult" minOccurs="0"/>
18 </xs:sequence>
19 </xs:complexType>
20
21 <xs:complexType name="detectedResult">
22 <xs:sequence>
23 <xs:element name="finishTime" type="xs:dateTime" minOccurs="0" />
24 <xs:element name="ipAddresses" type="xs:string" nillable="true"
25 minOccurs="0" maxOccurs="unbounded" />
26 <xs:element name="startTime" type="xs:dateTime" minOccurs="0" />
27 <xs:element name="timeTaken" type="xs:long" />
28 </xs:sequence>
29 </xs:complexType>
30 </xs:schema>
  • DomainDetector.wsdl内容
01 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
02 <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS
03 RI 2.1.6 in JDK 6. -->
04 <definitions targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
05 name="DomainDetector" xmlns="http://schemas.xmlsoap.org/wsdl/"xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector"
06 xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
07 <types>
08 <xsd:schema>
09 <xsd:importnamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
10 schemaLocation="DomainDetector_schema1.xsd" />
11 </xsd:schema>
12 </types>
13 <message name="detect">
14 <part name="parameters" element="tns:detect" />
15 </message>
16 <message name="detectResponse">
17 <part name="parameters" element="tns:detectResponse" />
18 </message>
19 <portType name="DomainDetectService">
20 <operation name="detect">
21 <input message="tns:detect" />
22 <output message="tns:detectResponse" />
23 </operation>
24 </portType>
25 <binding name="DomainDetectorPortBinding" type="tns:DomainDetectService">
26 <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
27 style="document" />
28 <operation name="detect">
29 <soap:operation soapAction="" />
30 <input>
31 <soap:body use="literal" />
32 </input>
33 <output>
34 <soap:body use="literal" />
35 </output>
36 </operation>
37 </binding>
38 <service name="DomainDetector">
39 <port name="DomainDetectorPort" binding="tns:DomainDetectorPortBinding">
40 <soap:address location="REPLACE_WITH_ACTUAL_URL" />
41 </port>
42 </service>
43 </definitions>

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

发布Web服务

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

01 package org.shirdrn.server.webservices.jaxws;
02
03 import javax.xml.ws.Endpoint;
04
05 public class PublishingServer {
06
07
08 public static void main(String[] args) {
09 String address ="http://172.0.8.212:9033/ws/services/DomainDetectService";
10 DetectService domainDetectService = new DomainDetectService();
11
12 Endpoint.publish(address, domainDetectService);
13 }
14
15 }

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

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

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

01 <!-- 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. -->
02 <!-- 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. -->
03 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
04 xmlns:tns="http://ws.shirdrn.org/jaxws/WSDomainDetector"xmlns:xsd="http://www.w3.org/2001/XMLSchema"
05 xmlns="http://schemas.xmlsoap.org/wsdl/"targetNamespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
06 name="DomainDetector">
07 <types>
08 <xsd:schema>
09 <xsd:import namespace="http://ws.shirdrn.org/jaxws/WSDomainDetector"
10 schemaLocation="http://172.0.8.212:9033/ws/services/DomainDetectService?xsd=1" />
11 </xsd:schema>
12 </types>
13 <message name="detect">
14 <part name="parameters" element="tns:detect" />
15 </message>
16 <message name="detectResponse">
17 <part name="parameters" element="tns:detectResponse" />
18 </message>
19 <portType name="DomainDetectService">
20 <operation name="detect">
21 <input message="tns:detect" />
22 <output message="tns:detectResponse" />
23 </operation>
24 </portType>
25 <binding name="DomainDetectorPortBinding" type="tns:DomainDetectService">
26 <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
27 style="document" />
28 <operation name="detect">
29 <soap:operation soapAction="" />
30 <input>
31 <soap:body use="literal" />
32 </input>
33 <output>
34 <soap:body use="literal" />
35 </output>
36 </operation>
37 </binding>
38 <service name="DomainDetector">
39 <port name="DomainDetectorPort" binding="tns:DomainDetectorPortBinding">
40 <soap:address
41 location="http://172.0.8.212:9033/ws/services/DomainDetectService" />
42 </port>
43 </service>
44 </definitions>

调用Web服务

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

01 shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ wsimport -keep -p org.shirdrn.client.webservices.jaxwshttp://172.0.8.212:9033/ws/services/DomainDetectService?wsdl
02 parsing WSDL...
03
04 generating code...
05
06 compiling code...
07 shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/bin$ cd org/shirdrn/client/webservices/jaxws/
08 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
09 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/
10 shirdrn@SYJ:~/programs/eclipse-java-juno/workspace/self_practice/src/org/shirdrn/client/webservices/jaxws$ ls
11 DetectedResult.java DetectResponse.java DomainDetector.java ObjectFactory.java
12 Detect.java DomainDetectService.java package-info.java

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

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

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

01 package org.shirdrn.client.webservices.jaxws;
02
03 public class DomainDetectClient {
04
05 public static void main(String[] args) {
06 DomainDetector detector = new DomainDetector();
07 String domain = "baidu.com";
08 DetectedResult result = detector.getDomainDetectorPort().detect(domain);
09 System.out.println(result.getIpAddresses());
10 }
11
12 }

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

1 [220.181.111.86, 123.125.114.144, 220.181.111.85]

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

目录
相关文章
|
8天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
46 3
|
14天前
|
设计模式 测试技术 持续交付
开发复杂Web应用程序
【10月更文挑战第3天】开发复杂Web应用程序
28 2
|
16天前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
35 3
|
15天前
|
前端开发 Java API
JAVA Web 服务及底层框架原理
【10月更文挑战第1天】Java Web 服务是基于 Java 编程语言用于开发分布式网络应用程序的一种技术。它通常运行在 Web 服务器上,并通过 HTTP 协议与客户端进行通信。
14 1
|
16天前
|
应用服务中间件 网络安全 nginx
nginx作为web服务以及nginx.conf详解
nginx作为web服务以及nginx.conf详解
|
6天前
|
XML 关系型数据库 MySQL
Web Services 服务 是不是过时了?创建 Web Services 服务实例
本文讨论了WebServices(基于SOAP协议)与WebAPI(基于RESTful)在开发中的应用,回顾了WebServices的历史特点,比较了两者在技术栈、轻量化和适用场景的差异,并分享了使用VB.net开发WebServices的具体配置步骤和疑问。
11 0
|
1月前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
56 3
|
1月前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
57 1
|
1月前
|
JSON API 开发者
惊!Python Web开发新纪元,RESTful API设计竟能如此性感撩人?
在这个Python Web开发的新纪元里,RESTful API的设计已经超越了简单的技术实现,成为了一种追求极致用户体验和开发者友好的艺术表达。通过优雅的URL设计、合理的HTTP状态码使用、清晰的错误处理、灵活的版本控制以及严格的安全性措施,我们能够让RESTful API变得更加“性感撩人”,为Web应用注入新的活力与魅力。
45 3
|
16天前
|
云安全 SQL 安全
数字时代下的Web应用程序安全:漏洞扫描服务的功能与优势
在当今这个数字化时代,Web应用程序不仅是企业与用户之间互动的桥梁,更是企业展示服务、传递价值的核心平台。然而,随着技术的不断进步,Web应用程序的复杂性也在不断增加,这为恶意攻击者提供了可乘之机。安全漏洞的频发,如SQL注入、跨站脚本攻击(XSS)、跨站请求伪造(CSRF)等,严重威胁着企业的数据安全、服务稳定性乃至经济利益。在这样的背景下,漏洞扫描服务作为一道重要的安全防线,显得尤为重要。本文将深入探讨漏洞扫描服务在面对Web应用程序安全问题时,所具备的功能优势。