Web Service初探

Web Service初探

简介

​ 简单地说WebService就是一种Web服务,他是一种跨编程语言和操作系统的远程调用技术。WebService的传输依赖于HTTP协议,通过SOAP协议使用XML格式进行数据传输。

​ WebService的三要素如下:

  • SOAP (Simple Object Access Protocol): 简易对象访问协议,soap用来描述传递信息的格式
  • WSDL (WebServices Description Language):Web服务描述语言,用来描述如何访问具体的接口,大多数情况下由软件自动生成
  • UDDI (Universal Description Discovery and Integration):通用描述、发现及整合,用来管理、分发、查询webService

Web Service实例

​ 下面直接给出一个WebService的具体实例来说明原生态的WebService开发

服务端开发

WebService接口和实现类代码编写

​ 具体代码如下:

@WebService
public interface HelloService {
    @WebMethod
    String sayHello(String name);
}

@WebService     // 实现类必须要添加@WebService注解
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        return "你好:" + name;
    }
}

服务发布代码编写

​ 以上我们定义了需要发布的接口,接下来就是将接口发布到注册中心使其成为WebService服务。具体代码如下:

public class WebServicePublisher {
    public static void main(String[] args) {
        // STEP1: 定义服务发布的地址
        String address = "http://localhost:9999/WS/HelloService";
        
        // STEP2: 发布WebService服务
        Endpoint.publish(address, new HelloServiceImpl());  // 第一个参数表示发布到注册中心的地址 第二个参数表示当有客户端向该地址发送请求的时候,服务器端对应的处理类
    
        // STEP3: 打印发布服务成功信息
        System.out.println("HelloService发布成功!");
    }
}   

通过URL访问WSDL文件

​ 服务发布成功之后,我们直接在浏览器输入:http://localhost:9999/WS/HelloService?wsdl即可获取注册中心的WSDL文件:

<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.webservice.rampage.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://server.webservice.rampage.com/" name="HelloServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://server.webservice.rampage.com/" schemaLocation="http://localhost:9999/WS/HelloService?xsd=1"/>
</xsd:schema>
</types>
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<portType name="HelloServiceImpl">
<operation name="sayHello">
<input message="tns:sayHello"/>
<output message="tns:sayHelloResponse"/>
</operation>
</portType>
<binding name="HelloServiceImplPortBinding" type="tns:HelloServiceImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="sayHello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HelloServiceImplService">
<port name="HelloServiceImplPort" binding="tns:HelloServiceImplPortBinding">
<soap:address location="http://localhost:9999/WS/HelloService"/>
</port>
</service>
</definitions>

​ WSDL文档的相关说明如下:

  • Types : 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。(入参和出参的数据类型)
  • Message: 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构(入参和出参)
  • Operation: 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对(方法)
  • PortType:对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持(服务类)
  • Binding: 特定服务访问点与具体服务类的绑定(不看内容,看关系)
  • Port:定义为webservice单个服务访问点
  • Service:相关服务访问点的集合

客户端开发

自动生成客户端代码

​ 我们有两种方式可以生成客户端代码

​ 1. 如果服务端已经启动,我们可以在CMD中使用wsimport命令来自动生成代码:

wsimport -s E:\workspacce\myWebServiceClient\src -keep http://localhost:9999/WS/HelloService?wsdl

​ 其中-s参数指定的是生成的源码路径,这里我指定客户端代码路径(不需要指定到具体包路径,生成代码的时候会自动生成到与服务器端的同路径文件夹下)。最终生成的文件结构如下:

​ 此时我们写的客户端测试代码为:

    public static void main(String[] args) {
        // STEP1: 实例化WebService工厂
        HelloServiceImplService serviceFactory = new HelloServiceImplService();
        
        // STEP2: 得到远程的Service实例
        HelloServiceImpl serviceImpl = serviceFactory.getHelloServiceImplPort();
        
        // STEP3: 远程调用WebService方法
        System.out.println(serviceImpl.sayHello("KiDe"));
    }
  1. 如果服务端没有启动,我们只有WSDL文件,那我们可以通过在eclipse中新建Web Service Client项目,并且选中WSDL文件,然后一路Next。最终生成的代码结构为:

​ 我们写的客户端测试代码为:

public class WebServiceInvoker {
    public static void main(String[] args) throws ServiceException, RemoteException {
        /**
         * Method1: 通过HelloServiceImplServiceLocator来获取远程接口
         */
        /*// STEP1: 实例化WebService工厂
        HelloServiceImplService serviceFactory = new HelloServiceImplServiceLocator();
        
        // STEP2: 得到远程的Service实例
        HelloServiceImpl serviceImpl = serviceFactory.getHelloServiceImplPort();
        
        // STEP3: 远程调用WebService方法
        System.out.println(serviceImpl.sayHello("KiDe"));*/
        
        /**
         * Method2: 通过代理类来获取远程接口
         */
        // STEP1: 实例化WebService工厂
        HelloServiceImplProxy serviceProxy = new HelloServiceImplProxy();
        
        // STEP2: 得到远程的Service实例
        HelloServiceImpl serviceImpl = serviceProxy.getHelloServiceImpl();
        
        // STEP3: 远程调用WebService方法
        System.out.println(serviceImpl.sayHello("KiDe"));
        // System.out.println(serviceProxy.sayHello("KiDe")); // 也可以直接通过代理类调用服务
    }
}

​ 同理我们也可以通过指定远程接口实现类的方式自动生成服务端代码。其实通过eclipse创建客户端或者服务端的方式是使用了CXF框架。会发现此时WSDL生成的测试类调用远程WebService服务相当慢,并且在运行的时候会出现如下警告:

警告: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.

​ 网上搜索发现时因为少了activation.jar和mail.jar,将这两个jar添加进入项目的build path之后发现告警消除,但是执行还是耗时很长。这说明CXF框架虽然简化了开发,但是执行效率大打折扣。


使用CXF来进行WebService开发

​ 百科上关于CXF的解释如下:

Apache CXF是开源的,CXF是两个项目的结合:由IONA技术公司(现在是Progress的一部分)开发的Celtix和由Codehaus主持的团队开发的XFire,合并是由人们在Apache软件基金会共同完成的。CXF的名字来源于"Celtix"和"XFire"的首字母

​ 官网上的说明如下:

Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.

下载Apache CXF

​ 直接去官网http://cxf.apache.org/下载,这里我下载的版本为: 3.2.1。解压之后文件目录结构如下:

​ 具体目录说明如下:

  • licenses: 引用的第三方jar包的相关许可协议
  • modules:包含了 CXF 框架根据不同特性分开进行编译的二进制包文件。发布基于 CXF 框架的 Web 项目时,可以选择使用该目录下的所有 .jar 文件,也可以选择 lib 目 录中的 cxf-2.0.2-incubator.jar 文件
  • samples:包含了所有随 CXF 二进制包发布的示例,包含这些示例的源代码和相关 Web 应用配置文件,可以方便地用 Ant 来编译运行测试这些示例,来了解 CXF 的开发和使用的方法。可以通过 samples 目录和它各个子目录下的 README.txt 的文件来详细了解示例的编译与运行的步骤
  • lib: 基于CXF框架开发可能需要用到的相关jar包
  • bin:CXF框架提供的相关工具包

开发WebService服务器端

引入相关jar包

​ 直接新建一个Java项目,然后将CXF的lib目录下的所有jar包添加到项目的build path。

编写服务接口并发布

​ 直接上代码:

@WebService
@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface HelloService {
    String sayHello(String name);
}


@WebService
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "你好:" + name;
    }
}


public class ServicePublisher {
    public static void main(String[] args) {
        // STEP1: 创建Bean工厂
        JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
        
        // STEP2: 设置服务发布地址已经发布的接口
        factoryBean.setAddress("http://localhost:8888/ws/HelloService");
        factoryBean.setServiceClass(HelloService.class);
        factoryBean.setServiceBean(new HelloServiceImpl());
        
        // STEP3: 发布服务
        factoryBean.create();
        
        System.out.println("HelloService服务发布成功!");
    }
}

需注意这里需用到JDK1.8

开发WebService客户端

使用CXF的工具生成客户端代码

​ 在CXF工具的bin目录下执行下面命令:

wsdl2java –d . http://localhost:8888/ws/HelloService?wsdl

​ 会在bin目录下生成对应客户端代码,代码与直接通过wsimport一致

编写客户端测试代码

​ 与前面一致,这里不再说明


WebService调用流程分析

​ 实现一个完整的WebService服务包括以下步骤:

◆ Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册(发布) ◆ Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务(发现) ◆ Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读(发现) ◆ 利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用(绑定) ◆ Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者(绑定)


在Web应用中使用WebService

  1. 在服务接口上添加@WebService注解
  2. 创建服务接口实现类
  3. 在web.xml中添加CXF的Servlet配置

xml <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>

  1. 配置cxf-servlet.xml

xml <jaxws:server id="bye" address="/bye" serviceClass="com.rl.cxf.web.inter.ByeInter"> <jaxws:serviceBean> <bean class="com.rl.cxf.web.inter.ByeInterImpl"></bean> </jaxws:serviceBean> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> </jaxws:outInterceptors> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:inInterceptors> </jaxws:server>

  1. 使用wsdl2java根据WSDL地址创建客户端代码
  2. 写客户端用例进行调用

其他

通过pom引入WebService相关jar包

​ 一般来说如果web项目想集成CXF框架来进行WebService调用,至少需要引入CXF相关的jaxws和http协议的支持

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>3.2.1</version>
</dependency>

参考链接

http://blog.csdn.net/jiandanfeng2/article/details/53439748 http://blog.csdn.net/qq_14852397/article/details/52761425 http://blog.csdn.net/aqsunkai/article/details/51711087 http://blog.csdn.net/qq32933432/article/details/51394749 http://blog.csdn.net/qq_35712358/article/details/71244342 https://www.cnblogs.com/fengwenzhee/p/6915606.html http://blog.csdn.net/yangwenxue_admin/article/details/51059125

与Spring框架集成请看后续更新的Spring官方文档解读之远程调用和WebService篇

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯NEXT学位

前端需要了解的 SSO 与 CAS 知识

46114
来自专栏点滴积累

geotrellis使用(二)geotrellis-chatta-demo以及geotrellis框架数据读取方式初探

在上篇博客(geotrellis使用初探)中简单介绍了geotrellis-chatta-demo的大致工作流程,但是有一个重要的问题就是此demo如何调取数据...

3706
来自专栏我是攻城师

Spring Boot开发之明月千城(一)

3233
来自专栏WindCoder

JSON Web Token(JWT)教程:一个基于Laravel和AngularJS的例子

这是一篇介绍JSON Web Token(JWT)的文章,虽然可能用到的例子和Laravel和AngularJS有关,但知道了原理便能写出适用于自己的。同时,由...

891
来自专栏编程坑太多

springboot(16)Shiro

2026
来自专栏Jaycekon

Spring-boot:快速搭建微框架服务

前言: Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配...

45812
来自专栏WeaponZhi

不求服务端,自己改接口!Charles抓包工具的应用

这篇文章主要是介绍 Charles 在开发阶段的使用方式,突出实用性,至于Charles 的介绍和配置,不是我们本文的重点,还没配置的同学可以参考这篇博文,很详...

28710
来自专栏blackpiglet

如何使用 Gin 和 Gorm 搭建一个简单的 API 服务 (一)

  今天工作上的事情比较多,所以就把工作中参考的英文文章搬运过来了,这是我参考文章的链接: Developing a simple CRUD API with...

895
来自专栏纯洁的微笑

springboot(十四):整合shiro-登录认证和权限管理

这篇文章我们来学习如何使用Spring Boot集成Apache Shiro。安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求。在Java...

5757
来自专栏信安之路

审计 tinyshop 中风险

审计该 CMS 中的内容只涉及到前台,后台中有存安全问题但对我来说没什么意义,所以没有过多的关注,感兴趣的朋友可以自己动动手。

450

扫码关注云+社区