目录

webservice介绍

webservice概述

WebService解决的问题

  • 解决不同系统、不同平台、不同语言之间的通信访问和调用
  • 解决应用程序的集成,不同业务的整合

WebService定义

  • WebService是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。
  • 表面上看WebService就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的方法API,能用编程的方法通过Web调用来实现某个功能的应用程序。
  • 深层次上看WebService是一种新的Web应用程序分支,它们是自包含、自描述模块化的应用,可以在网络中被描述、发布、查找以及通过Web来调用。
  • Web Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。它可以使用标准的互联网协议,像超文本传输协议HTTP和XML,将功能体现在互联网和企业内部网上。

小结:WebService是一套运行在网络应用程序上的标准,它定义了应用程序如何在Web上实现互操作性。你可以用你喜欢的任何语言,在你喜欢的任何平台上写Web Service。

WebService的运行模式和整体结构

20201109152320

webservice核心组件

  • XML和HTTP
  • SOAP: 简单对象访问协议
  • WSDL: websevice描述语言
  • UDDI: 统一描述、发现和集成协议

小结: webservice就是异构系统间的访问和互调

WebService主流框架

20201109152617

webservice不是局限于一种技术,更多是一种理念,Axis1/Axis2,XFire,CXF是实现这一理念的落地技术框架。本篇重点介绍CXF,一个不亚于springmvc的框架。

AXIS

已寿终正寝,不建议再使用。

Axis (Apache extensible Interaction System)阿帕奇可扩展交互系统,是一款开源的WebService运行引擎,本质上就是一个SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。

Axis分为1.x系列和2系列,两个系列体系结构和使用上有较大的区别,相对而言,Axis1.x更加稳定,文档也比较齐全。

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

XFire

07年左右很火

XFire是下一代的javaSOAP框架。XFire提供了非常方便的API,使用这些API可以开发面向服务(SOA)的程序。它支持各种标准,性能优良(基于低内存的STAX模型)。

官网: http://xfire.codehaus.org/

CXF

Apache CXF = Celtix+XFire

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

官网: http://cxf.apache.org/

CXF之HelloWorld

操作步骤

  1. 引入maven依赖

    参考:Index > Tools > Using CXF with maven

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
       
        <groupId>org.eh.webservice</groupId>
        <artifactId>webservice-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
       
        <properties>
            <cxf.version>3.4.0</cxf.version>
        </properties>
       
        <dependencies>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-frontend-jaxws</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-transports-http</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <!-- Jetty is needed if you're are not using the CXFServlet -->
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-transports-http-jetty</artifactId>
                <version>${cxf.version}</version>
            </dependency>
       
            <!--
            服务器需要依赖servlet-api,
            注意将provided改成compile, 因为jetty服务器不像tomcat自带servlet-api
            -->
            <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>compile</scope>
            </dependency>
       
        </dependencies>
    </project>
    
  2. 创建webservice接口和实现类,接口上需要加@WebService注解

    接口

    1
    2
    3
    4
    5
    6
    7
    8
    
    package com.eh.webservice.demo;
       
    import javax.jws.WebService;
       
    @WebService
    public interface HelloService {
        String sayHello(String who);
    }
    

    实现类

    1
    2
    3
    4
    5
    6
    7
    8
    
    package com.eh.webservice.demo;
       
    public class HelloServiceImpl implements HelloService {
        @Override
        public String sayHello(String who) {
            return "hello, " + who;
        }
    }
    
  3. 服务启动类

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    package com.eh.webservice.demo;
       
    import org.apache.cxf.endpoint.Server;
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
       
    public class MainServer {
        public static void main(String[] args) {
            // 创建Server工厂
            JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
            // 绑定服务器地址
            jaxWsServerFactoryBean.setAddress("http://localhost:9999/cxf");
            // 绑定要暴露的服务实现类
            jaxWsServerFactoryBean.setServiceClass(HelloServiceImpl.class);
            // 创建Server
            Server server = jaxWsServerFactoryBean.create();
            // 启动Server
            server.start();
        }
    }
    
  4. 验证

    访问:http://localhost:9999/cxf?wsdl

    http://img.cana.space/picStore/20201109170157.png

  5. 客户端调用

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    package com.eh.webservice.demo;
       
    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
       
    public class ClientTest {
        public static void main(String[] args) {
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            jaxWsProxyFactoryBean.setAddress("http://localhost:9999/cxf");
            jaxWsProxyFactoryBean.setServiceClass(HelloService.class);
            HelloService helloService = (HelloService) jaxWsProxyFactoryBean.create();
            String result = helloService.sayHello("cxf client");
            System.out.println("result from server =======> " + result);
        }
    }
    

    控制台输出:

    1
    2
    
    信息: Creating Service {http://demo.webservice.eh.com/}HelloServiceService from class com.eh.webservice.demo.HelloService
    result from server =======> hello, cxf client
    

JaxWsProxyFactoryBean 与 JaxWsDynamicClientFactory

JaxWsProxyFactoryBean

调用方式采用了和RMI类似的机制,即客户端直接服务器端提供的服务接口(interface),CXF通过运行时代理生成远程服务的代理对象,在客户端完成对webservice的访问; 几个必填的字段:setAddress-这个就是我们发布webservice时候的地址保持一致

缺点: 这种调用service的好处在于调用过程非常简单,就几行代码就完成一个webservice的调用,但是客户端也必须依赖服务器端的接口,这种调用方式限制是很大的,要求服务器端的webservice必须是java实现–这样也就失去了使用webservice的意义

JaxWsDynamicClientFactory

只要指定服务器端wsdl文件的位置,然后指定要调用的方法和方法的参数即可,不关心服务端的实现方式。

示例程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.eh.webservice.demo;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public class ClientTest {
    public static void main(String[] args) throws Exception {
        JaxWsDynamicClientFactory jaxWsDynamicClientFactory = JaxWsDynamicClientFactory.newInstance();
        // 根据wsdlUrl创建Client
        Client client = jaxWsDynamicClientFactory.createClient("http://localhost:9999/cxf?wsdl");
        Object[] result = client.invoke("sayHello", "cxf client");
        System.out.println("result from server =======> " + result[0]);
    }
}

控制台输出结果

1
2
objc[84774]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/bin/java (0x107aee4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x107b644e0). One of the two will be used. Which one is undefined.
result from server =======> hello, cxf client