WebService 理论详解、JWS(Java Web Service) 快速入门

时间:2024-04-17 14:39:09

目录

WebService (web服务)概述

WebService 平台技术

WebService 工作原理

WebService 开发流程

常见 Web Service 框架

JWS(Java Web Service) 概述

JWS(Java Web Service) 快速入门


WebService (web服务)概述

1、WebService(Web服务)是一种跨语言、跨平台的远程调用技术。

A、跨语言:服务器与客户端可以使用不同的语言开发,客户端都能调用服务器开放的接口,服务器只需要写一遍,任意语言的客户端都能进行调用。

B、跨平台:服务端程序和客户端程序可以运行在不同的操作系统上。

C、远程调用:指计算机 A(客户端) 上的程序可以调用计算机 B(服务器) 上的对象的方法。如火车站进出站需要刷身份证,参加大型展会、演唱会时也可以刷身份证,显然火车站以及展览会、演唱会这些刷身份证的系统自己是不可能有全国人民的身份证数据的,它们都在*局的数据库里,所以就可以理解成是*身份证系统使用 webService 向外提供了接口,各地刷身份证的系统作为客户端调用而已。

2、WebService 是可互操作的分布式应用程序的一个平台、一个标准,它定义了应用程序如何在 Web 上实现互操作性,可以用任何语言在任何平台上写 Web Service 服务端,然后可以通过 Web service 标准对这些服务进行操作。 

3、如果系统需要为任意的第三方客户提供服务,那么服务器系统就可以使用 webService 技术,这样方便数据交互。需要注意的是如果服务端接口方为webservice,则客户端也必须使用 webservice 。

web Service 应用场景?

1. 同一家公司的新旧应用之间,子系统之间,如校内的招生系统、就业系统、缴费系统、考试系统等

2. 不同公司的业务应用之间,如天猫网与中通物流系统交互

3. 一些提供数据的内容聚合服务应用,如天气预报、股票行情、机票、邮政编码等

如何发布一个 webService?

1、定义 SEI(Service Endpoint Interface)服务终端接口,即 webService 提供的服务接口

2、定义 SIB(Service Implemention Bean)服务实现类,即 webService 提供的服务接口的实现类

3、发布 webService 服务  Endpoint publish(String address, Object implementor)

如何请求一个 webService?

1、根据服务的提供的 wsdl 文档生成客户端代码,可以使用 Java Jdk自带的 wsimport.exe工具,或者 使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服务端代码,也能生成客户端代码。

2、根据生成的客户端代码调用 webService

一次 web service 请求的本质(流程)?

1、客户端向服务器端发送了一个 soap消息 (http 请求+ xml 片断)

2、服务器端处理完请求后, 向客户端返回一个 soap 消息(结果)

3、整个请求与应答都是围绕着 wsdl 文件,每次请求都是靠解析 wsdl 文件来确定调用哪个具体的方法,参数以及返回值等,所以如果调用的过程中,如果 wsdl 文件无法访问,或者文件错误,都会导致调用失败。

WebService 平台技术

XML+XSD ,SOAP,WSDL 构成 WebService 平台的三大技术。

1)XML+XSD

WebService 采用 HTTP 协议传输数据,采用 XML 格式封装数据(XML中说明调用远程服务中哪个对象的方法,传递的参数、返回结果等)。XML 的主要优点在于它与平台无关。

XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD),作用是定义 XML 文档的合法构建模块,类似 DTD,最重要的能力之一就是对数据类型的支持。WebService 平台就是用 XSD 来作为其数据类型系统的,当用某种语言(如VB、.NET、C#、Java等)来构造一个 Web service 时,为了符合 WebService 标准,所有使用的数据类型都必须被转换为XSD类型。

2)SOAP

SOAP(Simple Object Access Protocol)是基于 XML 的简单对象访问协议,可使应用程序在 HTTP 之上进行信息交换。

SOAP 指简易对象访问协议
SOAP 是一种通信协议
SOAP 用于应用程序之间的通信
SOAP 是一种用于发送消息的格式
SOAP 被设计用来通过因特网进行通信
SOAP 独立于平台
SOAP 独立于语言
SOAP 基于 XML
SOAP 很简单并可扩展
SOAP 允许您绕过防火墙
SOAP 将被作为 W3C 标准来发展

WebService 通过 HTTP 协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP 消息头,以说明 HTTP 消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC 方法来调用 Web Service 。

更多 SOAP 可以参考:http://www.w3school.com.cn/soap/index.asp

3)WSDL

WSDL(Web Services Description Language) 是基于 XML web服务描述语言,用于描述 Web Service 及其函数、参数和返回值等,这样客户端才能方便调用。一些开发工具既能根据 Web service 生成 WSDL 文档,又能导入 WSDL 文档,生成调用相应 WebService 的代理类代码。

WSDL 文件保存在Web服务器上,通过一个 url 地址即可访问。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址,WebService 服务提供商通常通过两种方式来暴露它的 WSDL 文件地址:1、注册到UDDI服务器,以便被人查找;2、直接告诉给客户端调用者。

WebService 工作原理

1、客户端 API 通过服务器的 wsdl 文件的 url 地址,创建出底层的代理类,客户端调用这些代理,就可以访问到 webservice 服务。代理类把客户端的方法调用变成 soap 格式的请求数据再通过 HTTP 协议发出去,并把接收到的 soap 数据变成返回值返回。

2、对服务端而言,各类 WebService 框架的本质就是一个大大的 Servlet,当远程客户端给它通过 http 协议发送过来 soap 格式的请求数据时,它分析这个数据,就知道要调用哪个 java 类的哪个方法,于是去查找或创建这个对象,并调用其方法,再把方法返回的结果包装成 soap 格式的数据,通过 http 响应消息回给客户端。

WebService 开发流程

WebService 开发可以分为服务器端开发和客户端开发两个方面。

1)服务端开发

把公司内部系统的业务方法发布成 WebService 服务,供远程合作单位和个人调用。

借助一些 WebService 框架可以很轻松地把自己的业务对象发布成 WebService 服务,Java 语言常用的第三方 WebService 框架有:axis,xfire,cxf 等。

当然还以 Java 自己的 JWS 。JWS 是 Java 语言对 WebService 服务的一种实现,用来开发和发布服务,不需要任何第三方库,为 Java 开发者提供便捷发布和调用 WebService 服务的途径。

2)客户端开发 

调用别人发布的 WebService 服务,例如调用天气预报 WebService 服务、调用门票服务、地图服务等。

因为是远程调用服务端的对象方法,所以需要在客户端也生成服务器提供的服务类,这通常有如下几种方式:

1、使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服务端代码,也能生成客户端代码;

2、直接使用服务提供商的提供的客户端编程 API 类;

3、Java JDK 在 bin 目录下提供了一个 wsimport.exe 程序,用于生成 WebService 客户端代码,然后调用 WebService;

常见 Web Service 框架

1)JWS

JWS 是 Java 语言对 WebService 服务的一种实现,用来开发和发布服务,为 Java 开发者提供便捷发布和调用WebService服务的功能。Java 1.6 开始推出 JWS,在 javax.jws 包下。

在线 JDK 文档:https://docs.oracle.com/javase/6/docs/api/

2)Axis2

Axis2 是 Apache 中一个重量级 WebService 框架,它是一个 Web Services / SOAP / WSDL 的引擎,是 WebService 框架的集大成者,不但能制作和发布 WebService,而且可以生成 Java 和其它语言版本的 WebService 客户端和服务端代码。

它的优势不可避免的导致了Axis2 的复杂性,所依赖的包数量多,体积大,打包部署发布也比较麻烦,不能很好的与现有应用整合为一体。但是如果是要开发 Java 以外的语言客户端,Axis2 提供的丰富工具将是不二的选择。

官网地址:http://axis.apache.org/

Axis2 Java 版本官网地址:http://axis.apache.org/axis2/java/core/

3)XFire

XFire 是一个高性能的 WebService 框架,在 Java6 之前,它的知名度甚至超过了Apache 的 Axis2,XFire 的优点是开发方便,与现有的 Web 整合很好,可以融为一体,并且开发也很方便。

XFire 对 Java 之外的语言,没有提供相关的代码工具,XFire 后来被 Apache 收购了,在此基础上开发出了更强大的 CXF。

官网地址:https://xfireclient.en.softonic.com/

4)CXF

1、CXF(Celtix + XFire) 是 Apache 旗下重磅的 SOA (Service Oriented Architecture) 面向服务的框架,它实现了 ESB(企业服务总线),能很好的和 Spring 进行集成。

2、CXF 由 Celtix 和 XFire 两个框架合并而来,就像目前的 Struts2 来自 WebWork 一样。可以看出 XFire 的命运会和 WebWork 的命运一样,最终会淡出人们的视线。

3、CXF 不但是一个优秀的 Web Services / SOAP / WSDL 引擎,也是一个不错的 ESB 总线,为 SOA 的实施提供了一种选择方案。
4、虽然 Axis2 出现的时间较早,但 CXF 的追赶速度快。

5、CXF 官网:http://cxf.apache.org/

总结:
1、如果应用程序需要多语言的支持,Axis2 应当是首选了; 
2、如果应用程序是遵循 Spring 哲学路线的话,Apache CXF 是一种更好的选择,特别对嵌入式的 Web Services 应用; 
3、如果应用程序没有新的特性需要,项目不大的话,可以任意采用 Axis1,XFire,或者 Java 自带的  Jws。

JWS(Java Web Service) 概述

1、Java Web Service 是 Java 语言对 WebService 服务的一种实现,用来开发和发布服务,为 Java 开发者提供便捷发布和调用WebService服务的功能。无需借助任何第三方库。

2、Java 1.6 开始推出 JWS,在 javax.jws 包下,在线 JDK 文档:https://docs.oracle.com/javase/6/docs/api/

3、开发过程十分简单:

1、服务端创建接口

2、服务端创建接口具体实现

3、服务端开启服务

4、客户端调用

4、编码也十分简单,因为整个 javax.jws 包一共也没多少 API。

5、因为 webservice 以 xml 格式进行传输数据,同时也会涉及一些 javax.xml 包下的 API。

JWS(Java Web Service) 快速入门

1、创建一个服务器项目(Java SE)、同时创建一个客户端项目(Java SE),服务端创建一个接口和其实现类,其中提供数据相加与数据相乘的两个方法,然后对外提供这个数据计算的服务,客户端通过 webService 技术可以直接调用服务端系统中的计算方法。

2、无论是 Java SE 应用还是 Java Web 应用,对于使用 jws 的 API 都是一样的,这里为了简单以创建 Java SE 项目进行演示。

ws 服务端

新建一个 Java SE 项目如下,名称 web_server,其中的代码结构如下。

1、第一步创建 CalculatorService 接口,这是需要对外提供服务的接口,客户端需要知道其中的内容。

2、第二步创建实现类 CalculatorServiceImpl,这是接口的具体实现,客户端是无法知道其中的内容的。

3、第三步创建 Web_Service 类,用于启动 webService 服务。

具体的 API 已经在注释解释的很详细了。

1、CalculatorService 接口内容如下:

  1. import javax.jws.*;
  2. /**
  3. * Created by Administrator on 2019/1/25 0025.
  4. * 计算器接口
  5. * SEI(Service Endpoint Interface):服务终端接口,即webService提供的服务接口
  6. * SIB(Service Implemention Bean):服务实现类,即webService提供的服务接口的实现类
  7. *
  8. * @javax.jws.WebService : 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口
  9. * 不过是服务端还是客户端,接口上都必须写上此注解
  10. */
  11. @WebService
  12. public interface CalculatorService {
  13. //加法
  14. //@WebService 中的方法上可以加上 @WebMethod 注解,也可以不加
  15. //@WebMethod 注解写或不写,服务端都会将 @WebSerivce 中的所有方法提供给客户端掉
  16. //写上的好处就是看起来更加直观而已,如同 @Override 重写注解意义,删除也无影响
  17. public float addition(float a, float b);
  18. //乘法
  19. public float multiplication(float a, float b);
  20. }

2、CalculatorServiceImpl 实现类内容如下:

  1. import javax.jws.WebService;
  2. import java.util.logging.Logger;
  3. /**
  4. * Created by Administrator on 2019/1/25 0025.
  5. * SEI(Service Endpoint Interface):服务终端接口,即webService提供的服务接口
  6. * SIB(Service Implemention Bean):服务实现类,即webService提供的服务接口的实现类
  7. *
  8. * @javax.jws.WebService : 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口
  9. * endpointInterface:终端接口,定义服务抽象 Web Service 协定的服务端点接口的完整名称,通常设置为服务实现类的全路径
  10. * 接口要写,实现类也必须写 @WebService
  11. * @WebService 接口一共提供了以下属性,而且都有默认值,它们将来都会出现在 wsdl 的 xml 文件中
  12. * String name() default "";
  13. * String targetNamespace() default "";
  14. * String serviceName() default "";
  15. * String portName() default "";
  16. * String wsdlLocation() default "";
  17. * String endpointInterface() default "";
  18. */
  19. @WebService(endpointInterface = "com.lct.web_service.CalculatorService")
  20. public class CalculatorServiceImpl implements CalculatorService {
  21. //日志记录器
  22. public static final Logger logger = Logger.getGlobal();
  23. @Override
  24. public float addition(float a, float b) {
  25. logger.info("加法计算:" + a + " + " + b + " = " + (a + b));
  26. return a + b;
  27. }
  28. @Override
  29. public float multiplication(float a, float b) {
  30. logger.info("乘法计算:" + a + " x " + b + " = " + (a * b));
  31. return a * b;
  32. }
  33. }

3、Web_Service 启动 webService 服务类内容如下:

  1. import javax.xml.ws.Endpoint;
  2. /**
  3. * Created by Administrator on 2019/1/25 0025.
  4. * webServer 启动类
  5. */
  6. public class Web_Service {
  7. public static void main(String[] args) {
  8. /**webService服务器提供给客户端访问的地址
  9. * 192.168.1.20 为服务器 ip、3333为指定的端口号、web_server 为应用名称、calculator为标识
  10. * 这个地址符合 http 地址即可,为了看起来更像是 web访问,所以才写了应用名,其实 http://192.168.1.20:3333/xxx 都是可以的
  11. */
  12. String wsUrl = "http://192.168.1.20:3333/web_server/calculator";
  13. /**
  14. * javax.xml.ws.Endpoint 表示一个 web service 终端,这是一个抽象类,其中提供了静态方法可以直接调用
  15. * Endpoint publish(String address, Object implementor)
  16. * address:传输协议的 url 地址;
  17. * implementor(实现者):web service 终端的实现类,因为一个 ws 接口可能会有多个实现类
  18. */
  19. Endpoint.publish(wsUrl, new CalculatorServiceImpl());
  20. }
  21. }

浏览器访问

1、webService 服务启动成功之后,根据提供 wsdl 地址,直接通过浏览器即可访问,看到服务端提供的接口(服务),客户端只需要解析这个 xml 文件即可进行服务调用。

2、注意地址最后的 wsdl 参数必须加上。

此 xml 文件全部内容如下:https://gitee.com/wangmx1993/my-document/blob/master/docs/WebService%20%20WSDL%20%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84.xml

客户端

1、调用别人发布的 WebService 服务,例如调用天气预报 WebService 服务、调用门票服务、地图服务等。因为是远程调用服务端的对象方法,所以需要在客户端也生成与服务器一致的服务接口,这通常有如下几种方式:

1、使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服务端代码,也能生成客户端代码;

2、Java JDK 在 bin 目录下提供了一个 wsimport.exe 工具,用于根据 wsdl 文件生成 WebService 客户端代码,然后调用 WebService;

3、直接使用服务提供商的提供的客户端编程 API 接口;

2、简单的说就是客户端调用 webService 服务器的接口,客户端自己也要有与服务器一致的接口,但是客户端不需要服务端接口的实现类,显然人家服务提供商自然也不会连实现类都提供出来,再者说,如果连接口和实现都提供了,则远程调用就没有意义了,就是再调用自己了

3、新建客户端项目(Java SE )如下,其中 CalculatorService 是与服务端一样的接口,Web_service 类用于调用服务器上的方法。

1、CalculatorService 接口内容如下,如果服务端、客户端都是 Java 开发,则完全可以联系服务器开发人员直接把这个接口的代码发过来即可。所以下面的代码与服务端完全是一样的。

  1. import javax.jws.WebService;
  2. /**
  3. * Created by Administrator on 2019/1/25 0025.
  4. * 计算器接口
  5. * SEI(Service Endpoint Interface):服务终端接口,即webService提供的服务接口
  6. * SIB(Service Implemention Bean):服务实现类,即webService提供的服务接口的实现类
  7. *
  8. * @javax.jws.WebService : 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口
  9. * 无论作为服务端还是客户端都必须写 @WebService 注解
  10. */
  11. @WebService
  12. public interface CalculatorService {
  13. //加法
  14. public float addition(float a, float b);
  15. //乘法
  16. public float multiplication(float a, float b);
  17. }

2、Web_service 类用于调用 webService 服务,内容如下:

  1. import javax.xml.namespace.QName;
  2. import javax.xml.ws.Service;
  3. import java.net.MalformedURLException;
  4. import java.net.URL;
  5. import java.util.logging.Logger;
  6. /**
  7. * Created by Administrator on 2019/1/25 0025.
  8. */
  9. public class Web_service {
  10. //日志记录器
  11. public static final Logger logger = Logger.getGlobal();
  12. public static void main(String[] args) {
  13. try {
  14. /** url:webservice 服务端提供的服务地址,结尾必须加 "?wsdl"*/
  15. URL url = new URL("http://192.168.1.20:3333/web_server/calculator?wsdl");
  16. /** QName 表示 XML 规范中定义的限定名称,QName 的值包含名称空间 URI、本地部分和前缀。
  17. * QName(final String namespaceURI, final String localPart):指定名称空间 URI 和本地部分的 QName 构造方法。
  18. * 如下所示的两个数据都可以浏览器访问服务端时返回 xml 中第一行找到,如:
  19. * <definitions xmlns:wsu=xxxxxxx targetNamespace="http://web_service.lct.com/" name="CalculatorServiceImplService">
  20. */
  21. QName qName = new QName("http://web_service.lct.com/", "CalculatorServiceImplService");
  22. /**
  23. * Service 对象提供 Web 服务的客户端视图
  24. * Service 作为以下内容的工厂:1、目标服务端点的代理,2、用于远程操作的动态面向消息调用的 javax.xml.ws.Dispatch 实例。
  25. * create(java.net.URL wsdlDocumentLocation,QName serviceName):创建 Service 实例。
  26. * wsdlDocumentLocation : 服务 WSDL 文档位置的 URL
  27. * serviceName : 服务的 QName
  28. */
  29. Service service = Service.create(url, qName);
  30. /**
  31. * 使用 getPorts 方法可以对服务上可用的端口/接口进行枚举
  32. * getPort(Class<T> serviceEndpointInterface):获取支持指定服务端点接口的对象实例
  33. * serviceEndpointInterface:指定返回的代理所支持的服务端点接口
  34. */
  35. CalculatorService calculatorService = service.getPort(CalculatorService.class);
  36. float added = calculatorService.addition(100, 80);
  37. float multied = calculatorService.multiplication(2.5F, 100);
  38. logger.info("added:" + added);
  39. logger.info("multied:" + multied);
  40. } catch (MalformedURLException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }

调用测试

1、先运行服务器开启 webService 服务,然后运行客户端看是否能调用服务端上的实现类进行计算,如果可以则说明 webService 服务提供成功。

由上可见完全成功。

出处:https://blog.****.net/wangmx1993328/article/details/86646656