实现WebService几种方式之JAX-WS详解

介绍

前文提到了WebService是一种跨语言和操作系统的远程调用技术,WebService如此强大,市面上关于它的技术也是层出不穷,下面便是WebService的JAVA原生实现–JAX-WS:

JAX-WS(Java API for XML Web Services)规范是一组XML web services的JAVA
API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。

JDK6开始支持WebService,JAX-WS是Sun公司完全基于schema标准实现的WebService协议栈,是非常易于适用的轻量级框架。虽然JWS可以轻松实现JAVA平台与其他平台的互操作,但是其他语言无法使用JAX-WS发布WebService服务,这也是JAX-WS的缺憾之一。

实例-服务发布

JAX-WS的服务发布方式很简单,只需要使用@WebService注解便能够完成服务的发布:

首先,编写待发布服务的接口,通过@WebService注解来表明这是一个SEI(Service Endpoint Interface),这是强制性的,缺少该注解会引发RuntimeModelerException异常:
在这里插入图片描述

/**
 * @program: webservice-server
 * @description:
 * @author: Lucifinil
 * @create: 2019-12-19
 **/
@WebService
public interface IMapWebService {
    /**
     * 根据地名获取国家名
     * @param placeName 地名
     * @return 国家名
     */
    String getCountry(String placeName);
}

SEI的实现类使用@WebService注解来表明这是一个SIB(Service Implements Bean),网上许多资料提到实现类可以不使用@WebService注释,经过试验,我发现在JDK1.8中实现类不添加@WebService会抛出IllegalArgumentException异常:
在这里插入图片描述
事实上,该注解对于SEI和SIB都是强制性的,但其中的参数是非必需的。

/**
 * @program: webservice-server
 * @description:
 * @author: Lucifinil
 * @create: 2019-12-19
 **/
@WebService(endpointInterface = "com.pers.IMapWebService", serviceName = "IMapWebService")
public class MapWebService implements IMapWebService {
    private static final String CHENGDU = "成都";
    private static final String SAN_FRANCISCO = "旧金山";
    @Override
    public String getCountry(String placeName) {
        if (CHENGDU.equals(placeName)) {
            return "中国";
        } else if (SAN_FRANCISCO.equals(placeName)) {
            return "美国";
        } else {
            return "该地名暂不支持查询";
        }
    }
}

以上代码模拟了一个查询国名的服务,只要传入数据库(假装有数据库)中存在的地名,便会返回相应国名:)
接下来,万事大吉,只差发布了,定义一个发布器:

/**
 * @program: webservice-server
 * @description:
 * @author: Lucifinil
 * @create: 2019-12-19
 **/
public class WebServicePublisher {
    public static void main(String[] args) {
        System.out.println("启动发布服务...");
        IMapWebService mapWebService =  new MapWebService();
        String mapWebServiceAddress = "http://localhost:9999/map";
        Endpoint.publish(mapWebServiceAddress,mapWebService);
        System.out.println("正在提供国名查询服务...");
    }
}

Endpoint是JAX-WS中发布服务的关键类,提供的静态方法 publish(String address, Object implementor) 可以在给定的地址创建并发布指定的实现者对象的端点。
OK!运行:
实现WebService几种方式之JAX-WS详解_第1张图片
说好的JAX-WS简单呢…怎么发布都这么多!!!
只是看着多啦,发布完成后,便给广大粉丝生成说明书吧。
打开浏览器,访问发布器定义的发布地址加上"?wsdl":

"http://localhost:9999/map?wsdl";

如果出现这一步,WebService服务就已经成功发布了》。》
实现WebService几种方式之JAX-WS详解_第2张图片

实例-客户端调用

在之前生成的WSDL,虽然我们也可以人为阅读,但出于效率与正确性,肯定不如机器。
JAVA提供了wsimport来为我们阅读WSDL并生成相应的调用客户端,所以JAX-WS是相当简单无脑的,不过,我喜欢,嘿嘿嘿(^)。
wsimport通过命令行使用:
实现WebService几种方式之JAX-WS详解_第3张图片
比较常用的几个参数:

  • -keep:是否生成java源文件

  • -d:指定.class文件的输出目录

  • -s:指定.java文件的输出目录

  • -p:定义生成类的包名,不定义的话有默认包名

  • -verbose:在控制台显示输出信息

  • -b:指定jaxws/jaxb绑定文件或额外的schemas

  • -encoding : 指定编码格式

实例:

wsimport -encoding utf-8   -d D:\webservice -p com.pers -keep   -verbose  http://127.0.0.1:9999/map?wsdl

对上述命令做一个小小解析:
-encoding utf-8 表示wsimport使用utf8编码;
-d D:\webservice表示将编译文件输出到D:\webservice;
-p com.pers指定生成的程序代码的包为com.pers,可以不配置,默认包名为服务端的包名;
-keep表示在编译目录下同时生成java源文件,否则只有编译文件,等价于:

wsimport -encoding utf-8   -d D:\webservice -p com.pers -s D:\webservice   -verbose  http://127.0.0.1:9999/map?wsdl

-verbose表示在控制台显示过程信息。
大家可以根据实际情况配置参数:)
最终效果:
实现WebService几种方式之JAX-WS详解_第4张图片
一般来说,我们只使用源文件就行了:

wsimport -encoding utf-8  -p com.pers -s D:\webservice   -verbose  http://127.0.0.1:9999/map?wsdl

接下来便是调用了,把整个包cv到客户端工程:
实现WebService几种方式之JAX-WS详解_第5张图片
调用客户端的接口来获取数据:

/**
 * @program: webservice-client
 * @description:
 * @author: Lucifinil
 * @create: 2019-12-19
 **/
public class Client {
    public static void main(String[] args) {
        IMapWebService iMapWebService = new IMapWebService();
        IMapServer iMapServer = iMapWebService.getMapWebServicePort();
        String country = iMapServer.getCountry("旧金山");
        System.out.println(country);
    }
}

结果如下:
实现WebService几种方式之JAX-WS详解_第6张图片

解析:IMapWebService并非所谓的服务器类,IMapWebService类继承自javax.xml.ws.Service类,提供Web服务的客户端视图。
getMapWebServicePort()方法是对Service中getPort()的封装,其返回值实际是指定服务端点接口的对象代理实例。
通过iMapServer调用服务端提供的查询接口getCountry(),得到查询结果。
到这里,JAX-WS的发布服务于服务调用流程就结束了。

注解

@webservice(javax.jws.WebService),作用于Class,用于描述一个JWS文件实现一个webservice时候的细节,提供以下参数:

属性 说明
serviceName XML:, 对外发布的服务名:,缺省值为 Java 类的简单名称 + Service。
name XML:,此属性的值包含XML Web Service的名称。缺省值为 Java 类或接口的非限定名称。
portName XML:,缺省值为 WebService.name+Port。
endpointInterface 服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口 。
targetNamespace 指定你想要的名称空间,默认是使用接口实现类的包名的反缀
wsdlLocation 指定用于定义 Web Service 的 WSDL 文档的 Web 地址。Web 地址可以是相对路径或绝对路径。

@WebMethod(javax.jws.WebMethod),作用于方法,表示作为一项 Web Service 操作的方法,提供以下参数:

属性 说明
operationName XML:元素operation名称,缺省值为该方法名称。
action 对于SOAP绑定,确定XML:SOAP:action中header的值,定义此操作的行为,缺省值为该方法名称。
exclude 是否拒绝该方法的发布,缺省值为 false。

@Oneway注解,javax.jws.Oneway,作用于方法,注释将一个方法表示为只有输入消息而没有输出消息的 Web Service 单向操作。
实现WebService几种方式之JAX-WS详解_第7张图片
该注解须和@WebMethod配合使用,且必须用于void修饰的方法。
@WebParam(javax.jws.WebParam),该注解作用于方法入参,表示单个参数至 Web Service 消息部件和 XML 元素的映射或者参数行为。

属性 说明
name 对于RPC风格的操作,如果未指定partName,该属性与映射;对于document风格的操作来说,name与XML元素的local name映射,如果参数类型为 BARE 并且方式为 OUT 或 INOUT,那么必须指定此属性。缺省值为方法参数名称。
partName XML:,对于RPC风格的操作可用,或者对于document风格的操作且参数样式为 BARE 时可用
targetNamespace 参数的XML命名空间。这个值只在document风格的webservice使用,从而参数映射为XML元素。默认值是这个webservice的targetNamespace。
mode 参数的流向(IN、OUT 或 INOUT 之一,对应enum为WebParam.Mode.IN,WebParam.Mode.OUT,WebParam.Mode.INOUT。)缺省值为WebParam.Mode.IN。
header 指定参数是在SOAP header还是SOAP body中,缺省值为 false。

@WebResult(javax.jws.WebResult),该注解作用于SEI和SIB上,指定返回值到 WSDL 部分和 XML 元素的映射关系。

属性 说明
name 指定该返回值的名称。对于 RPC 绑定,该属性与映射。对于document绑定,name与XML元素的local name映射。对于 RPC 和 DOCUMENT/WRAPPED 绑定,缺省值为 return。对于 DOCUMENT/BARE 绑定,缺省值为方法名 + Response。
partName XML:,只在document风格的操作且参数样式为 BARE 时可用
targetNamespace 指定返回值的 XML 名称空间。只在document风格的操作且参数样式为 BARE 时可用
header 指定参数是在SOAP header还是SOAP body中,缺省值为 false。

@SOAPBinding(javax.jws.SOAPBinding),该注解作用于SEI和SIB上,指定 Web Service 与 SOAP 消息协议之间的映射。

属性 说明
use 定义用于发送至 Web Service 和来自 Web Service 的消息的格式,缺省值为 LITERAL。ENCODED 在 Feature Pack for Web Services 中不受支持。
style 定义发送至 Web Service 和来自 Web Service 的消息的编码样式,有效值为DOCUMENT 和 RPC。缺省值为DOCUMENT。
parameterStyle 确定方法的参数是否表示整个消息体,或者参数是否是封装在执行操作之后命名的顶级元素中的元素。有效值为 WRAPPED 或 BARE。对于DOCUMENT 类型的绑定只能使用BARE 值。缺省值为 WRAPPED。

@HandlerChain :已过时

结束语

总的来说,JAX-WS还是蛮简单的,不用导入任何包,使用注解便能完成服务的发布,JAX-WS并非一蹴而就的,最开始的版本是JAX-RPC,在它的发展历程中,也经历了许多的迭代,有兴趣可以了解一下。
转载请注明出处,来自路西菲尔的博客https://blog.csdn.net/csdn_1364491554/article/details/103613414!

你可能感兴趣的:(RPC,#,WebService)