Webservice 学习笔记


概述

1. 什么是 Webservice?

Webservice 即 web 服务,是一种跨操作系统,跨语言的远程调用技术,例如,服务提供方是使用 Java 开发的服务,客户端使用 Webservice 去调用就无需关心自身是使用何种平台或语言

2. Webservice 三要素

SOAP:简单对象协议,是一种基于 XML 的协议,使得应用程序可以通过 HTTP 交换信息,可以简单理解为 SOAP = HTTP + XML

WSDL:Webservice 描述语言,基于 XML 格式,用户描述 Webservice 及其函数,参数和返回值,可通俗理解为 Webservice 说明书

UDDI:目录服务,企业可以使用它对 Webservice 进行注册和搜索,从而达到资源共享的作用


JAX-WS

1. 服务端开发

Java 在 1.6 版本以后已经支持开发 Webservice,即 JAX-WS。高版本的 JDK 中 JAX-WS 则不再与 JDK 捆绑在一起,需要自行引入。以天气查询服务为例,根据地名返回对应的天气

引入依赖,建议按照这里的版本,高版本存在问题

<dependency>
    <groupId>javax.jws</groupId>
    <artifactId>javax.jws-api</artifactId>
    <version>1.1</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.3.1</version>
</dependency>

开发服务接口

@Webservice	// 标识该接口是一个 Webservice 类
public interface WeatherWebservice {
    public String queryWeatherByCity(String cityName);
}

开发服务实现类

@Webservice
public class WeatherWebserviceImpl implements WeatherWebservice {
    public String queryWeatherByCity(String cityName) {
        // 进行业务处理,返回天气
    }
}

发布服务

public class TestPublished {
    public static void main(String[] args) {
        // 发布服务
        // 参数一: 服务地址
        // 参数二: 服务实现类
        Endpoint.publish("http://localhost:8888/ws", new WeatherWebserviceImpl());
    }
}
2. 客户端开发

首先查看 Webservice 的服务说明书,访问 http://localhost:8888/ws?wsdl

根据 wsdl 地址生成客户端调用代码

wsimport -s . -p com.yeeq.client [wsdl地址]

我使用的 JDK11 已经移除了 wsimport,可是使用 Maven 插件

<build>
        <plugins>
            <plugin>
                <groupId>com.helger.maven</groupId>
                <artifactId>jaxws-maven-plugin</artifactId>
                <version>2.6.2</version>
                <configuration>
                    <packageName>
                        com.yeeq.web.client
                    </packageName>
                    <wsdlUrls>
                        <wsdlUrl>http://localhost:8888/ws?wsdl</wsdlUrl>
                    </wsdlUrls>
                    <keep>true</keep>
                    <verbose>true</verbose>
                    <sourceDestDir>src\main\java</sourceDestDir>
                    <vmArgs>
                        <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
                    </vmArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

将生成的客户端代码拷贝到项目中,调用方法有两种:

  • 基于服务视图对象的调用方式

    public class TestClient {
    
        public static void main(String[] args) {
            // 1.创建服务视图对象
            WeatherWebserviceImplService weatherWebserviceImplService = new WeatherWebserviceImplService();
            // 2.根据服务视图对象直接获取服务核心类对象
            WeatherWebserviceImpl weatherServicePorType = weatherWebserviceImplService.getWeatherWebserviceImplPort();
            // 3.调用服务方法
            String weather = weatherServicePorType.queryWeatherByCity("北京");
        }
    }
    
  • 标准的调用方式

    public class TestClient {
    
        public static void main(String[] args) throws Exception {
            // 1.创建命名空间对象
            // 参数一:wsdl中的目标命名空间 targetNamespace
            // 参数二:服务视图名
            QName qName = new QName("http://impl.service.web.yeeq.com/", "WeatherWebserviceImplService");
            // 2.通过JDK提供的通用服务对象进行调用
            // 参数一:wsdl地址
            // 参数二:wsdl命名空间对象
            Service service = Service.create(new URL("http://localhost:8888/ws?wsdl"), qName);
            // 3.获取服务核心类对象
            WeatherWebserviceImpl weatherServicePorType  = service.getPort(WeatherWebserviceImpl.class);
            // 4.调用服务方法
            String weather = weatherServicePorType.queryWeatherByCity("北京");
            System.out.println(weather);
        }
    }
    

相比第一种方式,第二种方式更为复杂,但耦合度更低,当服务端路径发生变化,只需要修改为对应的路径即可,不需要重新生成代码。但无论是第一种还是第二种方式,当服务端的方法声明发生了变化,就必须重新生成代码


CXF 框架

CXF 框架是 Apache 组织开源的 Webservice 框架,最大的特点就是可以与 Spring 框架无缝整合

以 SpringBoot 整合 CXF 为例,需要先引入依赖

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.5.1</version>
</dependency>

和之前一样,开发服务接口

@WebService
public interface WeatherService {
    public String queryWeatherByCity(String cityName);
}
@Component
public class WeatherServiceImpl implements WeatherService {
    @Override
    public String queryWeatherByCity(String cityName) {
        if ("北京".equals(cityName)) {
            return "晴转多云";
        }
        return "多云转晴";
    }
}

开发配置类

@Configuration
public class CXFConfig {

    @Autowired
    private Bus bus;

    @Autowired
    private WeatherService weatherService;

    // 高版本cxf框架不在这里配置,而在配置文件配置
    /*@Bean
    public ServletRegistrationBean dispatcherServlet(){
        // 以cxf前缀的请求为Webservice请求,springmvc不做处理
        return new ServletRegistrationBean(new CXFServlet(),"/cxf/*");
    }*/

    @Bean
    public Endpoint userEndpoint(){
        EndpointImpl endpoint = new EndpointImpl(bus,weatherService);
        // 指定服务地址
        endpoint.publish("/weather");
        return endpoint;
    }
}
server.port=8080
spring.application.name=cxf-webservice-server
cxf.path=/cxf

运行服务,访问 http://localhost:8080/cxf/weather?wsdl,查看服务说明书

对于 CXF 开发的服务,也可以用传统的方式调用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值