Web Service应用之JAX-WS开发[通俗易懂]

2022-09-14 13:22:10 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

1.什么是Web Service

Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执行远程系统的请求服务。

2.Web Service解决什么问题

Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。

3.术语

Web Service的三要素:SOAP、WSDL、UDDI,soap用来描述传递信息的格式,WSDL 用来描述如何访问具体的接口,uddi用来管理,分发,查询Web Service。

WSDL

Web Service描述语言WSDL(Seb Service Desciption Language)就是用机器能阅读的方式提供的一个正式描述文档而基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。

SOAP

SOAP即简单对象访问协议(SimpleObject Access Protocol),它是用于交换XML(标准通用标记语言下的一个子集)编码信息的轻量级协议。它有三个主要方面:XML-envelope为描述信息内容和如何处理内容定义了框架,将程序对象编码成为XML对象的规则,执行远程过程调用(RPC)的约定。SOAP可以运行在任何其他传输协议上。

SEI

SEI(Web ServiceEndPoint Interface)是Web Service服务器端用来处理请求的接口。

UDDI

UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。

4.优劣点

优点

采用XML,支持跨平台远程调用;基于http的soap协议,可以跨越防火墙;支持面向对象开发;有利于软件和数据重用,实现松耦合。

缺点

由于soap是基于xml传输,本身使用xml传输会传输一些无关内容从而影响效率,随着soap协议的完善,soap协议增加了许多内容,这样就导致了使用soap去完成简单的数据传输而携带的信息更多效率再受影响;

Web Service作为web跨平台访问的标准技术,很多公司都限定要求使用Web Service,但如果是简单的接口可以直接使用http传输自定义数据格式,开发更快捷。

适用场景:

1.跨越防火墙

2.应用程序集成

3.B2B集成

4.软件重用

不适用场景:

1.单机应用程序

2.局域网上的同构应用程序

5.JAX-WS

JAX-WS(Java APIfor XML Web Services)规范是一组XML Web Services的JAVA API;即JDK内置的Web Service实现,用来开发和发布Web Service服务。

在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。

在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI(serviceendpoint interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。

在客户端,用户可以通过JAX-WS的API创建一个代理(用本地对象来替代远程的服务)来实现对于远程服务器端的调用。

当然 JAX-WS 也提供了一组针对底层消息进行操作的API调用,你可以通过Dispatch 直接使用SOAP消息或XML消息发送请求或者使用Provider处理SOAP或XML消息。

5.1.JAX-RPC 和 JAX-WS

Sun最开始的web services的实现是JAX-RPC 1.1 (JSR 101)。这个实现是基于Java的RPC,并不完全支持schema规范,同时没有对Binding和Parsing定义标准的实现。

JAX-WS2.0 (JSR 224)是Sun新的web services协议栈,是一个完全基于标准的实现。在binding层,使用的是the Java Architecture for XML Binding (JAXB, JSR 222),在parsing层,使用的是theStreaming API for XML (StAX, JSR 173),同时它还完全支持schema规范。

5.2.Apache-CXF和JAX-WS

ApacheCXF = Celtix XFire,开始叫 ApacheCeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。Apache CXF已经是一个正式的Apache顶级项目。

ApacheCXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。

代码语言:javascript复制
官网:http://cxf.apache.org/
代码语言:javascript复制
百度百科:https://baike.baidu.com/item/CXF/9622340?fr=aladdin

6.JAX-WS开发Web Service接口

6.1.导包

由于JAX-WS是JDK提供的对Web Service支持的API所以不用导入包,直接使用JDK1.6以上就可以开发。

6.2.发布WebService服务

6.2.1.接口

代码语言:javascript复制
package com.rabbit.jaxws;

/**
 * Created by vip on 2018/1/17.
 */
public interface Calculator {

    public int computeSumOf(int ...x);

}

6.2.2.实现

代码语言:javascript复制
package com.rabbit.jaxws;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

/**
 * Created by vip on 2018/1/17.
 */
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class CalculatorImpl implements Calculator {

    public int computeSumOf(int... x) {
        int result = 0;
        for (int index = 0; index < x.length; index  ) {
            result  = x[index];
        }
        return result;
    }

}

6.2.3.发布接口

代码语言:javascript复制
package com.rabbit.jaxws;

import javax.xml.ws.Endpoint;

/**
 * Created by vip on 2018/1/17.
 */
public class WebServiceExample {

    public static void main(String[] args) {
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/calculator", new CalculatorImpl());
        System.out.println("WebService接口服务已经启动......");
    }

}

6.2.4.查看发布的接口

首先要启动main方法对接口实行发布,再浏览器中输入:http://localhost:8080/calculator?wsdl。查看任何的WebService接口的WSDL说明文档只需要在地址后面加上?wsdl即可。下面就是接口的说明包括了方法和参数返回值等信息。

代码语言:javascript复制
  <definitions targetnamespace="http://jaxws.rabbit.com/" name="CalculatorImplService">
   <types>
    <xsd:schema>
     <xsd:import namespace="http://jaxb.dev.java.net/array" schemalocation="http://localhost:8080/calculator?xsd=1" />
    </xsd:schema>
   </types>
   <message name="computeSumOf">
    <part name="arg0" type="ns1:intArray" />
   </message>
   <message name="computeSumOfResponse">
    <part name="return" type="xsd:int" />
   </message>
   <porttype name="CalculatorImpl">
    <operation name="computeSumOf">
     <input wsam:action="http://jaxws.rabbit.com/CalculatorImpl/computeSumOfRequest" message="tns:computeSumOf" />
     <output wsam:action="http://jaxws.rabbit.com/CalculatorImpl/computeSumOfResponse" message="tns:computeSumOfResponse"></output>
    </operation>
   </porttype>
   <binding name="CalculatorImplPortBinding" type="tns:CalculatorImpl">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
    <operation name="computeSumOf">
     <soap:operation soapaction="" />
     <input />
     <soap:body use="literal" namespace="http://jaxws.rabbit.com/" />
     <output>
      <soap:body use="literal" namespace="http://jaxws.rabbit.com/" /></output>
    </operation>
   </binding>
   <service name="CalculatorImplService">
    <port name="CalculatorImplPort" binding="tns:CalculatorImplPortBinding">
     <soap:address location="http://localhost:8080/calculator" />
    </port>
   </service>
  </definitions>

6.2.5.总结

发布一个简单的Web Service服务并提供对外的wsdl文档:

1)编写服务器类,并添加@WebService注解

2)调用EndPoint.publish启动并发布服务

6.3.创建客户端

SEI是用于在消费者和服务者之间共享代码的。创建方式有两种:1)使用命令根据WSDL去生成。2)通过Java由开发人员创建。

6.3.1.wsimport

wsimport是JDK自带的工具,在JDK的bin文件夹中;主要功能是根据服务端生成的WSDL文件生成客户端代码。生成java客户端代码常使用的命令参数说明:

参数

说明

-p

指定客户端生成类的包路径;值如:cn.abc

-s

指定客户端执行类的源文件存放目录

-d

指定客户端执行类的class文件的存放目录

-keep

表示保留源文件

-b

指定jaxws/jaxb绑定文件或额外的schemas

-extension

扩展来支持SOAP1.2

6.3.2.命令生成客户端

注意:1)先启动服务,否则无法逆向生成客户端代码。2)如果电脑环境变量已经配置好了JDK和JRE直接win R -> cmd输入wsimport的命令信息即可,如果没有配置好请进入控制台界面后进入到安装好的JDK环境的bin目录下。

生成的客户端代码:

注意:生成的客户端代码已经编写好了调用服务端的代码,就好比帮我们写好了接口一样,我们只要调用即可。不清楚的可以简单看下生成的几个文件。不同的代码生成的文件会不一样,但是用法是一样的。

6.3.3.利用客户端调用服务

代码语言:javascript复制
package com.rabbit.jaxws.service;

import java.util.List;

/**
 * Created by vip on 2018/1/17.
 */
public class ClientMain {

    public static void main(String[] args) {
        CalculatorImplService cis = new CalculatorImplService();
        CalculatorImpl cip = cis.getCalculatorImplPort();//里面有可以调用的方法
        /** 封装请求参数 */
        IntArray array = new IntArray();
        List<Integer> item = array.getItem();
        for (int index = 1; index < 10; index  ) {
            item.add(index * index);
        }
        int result = cip.computeSumOf(array);
        System.out.println(result);
    }

}

6.3.4.总结

调用Web Service应用:

1)使用JDK自带的wsimport工具根据别人提供的WSDL生成客户端代码。

2)根据生成的Java类调用服务提供的方法。

6.4.开发效率

这种方式开发接口是非常方便的,而且开发人员也不需要花费额外的时间去调试接口等。特别是对于开发文档是有误的情况下,花费大量的时间就非常的不划算。对于别人提供的接口方法只需要看文档参考名字就可以知道作用。

7.注解

7.1.@WebService

代码语言:javascript复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface WebService {
    String name() default "";

    String targetNamespace() default "";

    String serviceName() default "";

    String portName() default "";

    String wsdlLocation() default "";

    String endpointInterface() default "";
}

属性名称

说明

name

此属性的值包含XML Web Service的名称。在默认情况下,该值是实现XML Web Service的类的名称,wsdl:portType 的名称。缺省值为 Java 类或接口的非限定名称。

targetNamespace

指定命名空间,默认是使用接口实现类的包名的反缀。

serviceName

对外发布的服务名,指定 Web Service 的服务名称:wsdl:service。缺省值为 Java 类的简单名称 Service。

portName

缺省值为 WebService.name Port。

wsdlLocation

指定用于定义 Web Service 的 WSDL 文档的 Web 地址。Web 地址可以是相对路径或绝对路径。

endpointInterface

服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口。

7.2.@WebMethod

代码语言:javascript复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface WebMethod {
    String operationName() default "";

    String action() default "";

    boolean exclude() default false;
}

属性名称

说明

operationName

指定与此方法相匹配的wsdl:operation 的名称。缺省值为 Java 方法的名称。

action

定义此操作的行为。对于 SOAP 绑定,此值将确定 SOAPAction 头的值。缺省值为 Java 方法的名称。

exclude

指定是否从 Web Service 中排除某一方法。缺省值为 false。

7.3.@WebResult

代码语言:javascript复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface WebResult {
    String name() default "";

    String partName() default "";

    String targetNamespace() default "";

    boolean header() default false;
}

属性名称

说明

name

当返回值列示在 WSDL 文件中并且在连接上的消息中找到该返回值时,指定该返回值的名称。对于 RPC 绑定,这是用于表示返回值的 wsdl:part属性的名称。对于文档绑定,-name参数是用于表示返回值的 XML 元素的局部名。对于 RPC 和 DOCUMENT/WRAPPED 绑定,缺省值为 return。对于 DOCUMENT/BARE 绑定,缺省值为方法名 Response。

partName

指定返回值的 XML 名称空间。仅当操作类型为 RPC 或者操作是文档类型并且参数类型为 BARE 时才使用此参数。

targetNamespace

指定头中是否附带结果。缺省值为false。

header

指定 RPC 或 DOCUMENT/BARE 操作的结果的部件名称。缺省值为@WebResult.name。

7.4.@WebParam

代码语言:javascript复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface WebParam {
    String name() default "";

    String partName() default "";

    String targetNamespace() default "";

    WebParam.Mode mode() default WebParam.Mode.IN;

    boolean header() default false;

    public static enum Mode {
        IN,
        OUT,
        INOUT;

        private Mode() {
        }
    }
}

属性名称

说明

name

指定方法的参数名称在WSDL中显示

partName

指定参数是在消息头还是消息体中。缺省值为 false。

targetNamespace

指定参数的 XML 元素的 XML 名称空间。当属性映射至 XML 元素时,仅应用于文档绑定。缺省值为 Web Service 的 targetNamespace。

header

指定参数是在消息头还是消息体中。缺省值为 false。

mode

此值表示此方法的参数流的方向。有效值为 IN、INOUT 和 OUT。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/159661.html原文链接:https://javaforall.cn

0 人点赞