Web Service 学习知识点总结

1、Web service是什么?

通过使用 Web Services,您的应用程序可以向全世界发布信息,或提供某项功能。Web Services 脚本平台需支持 XML + HTTP。

①、基于Web服务,服务器端整出一些资源让客户端应用访问(获取数据)。②、一个跨语言、跨平台的规范(抽象)③、多个跨平台、跨语言应用通信整合的方案(实际)

Web services 有两种类型的应用

可重复使用的应用程序组件

Web services 可以把应用程序组件作为服务来提供,比如汇率转换、天气预报或者甚至是语言翻译等等。

连接现有的软件

通过为不同的应用程序提供一种链接其数据的途径,Web services有助于解决协同工作的问题。通过使用 Web services,您可以在不同的应用程序与平台之间来交换数据。

2、Web services 平台的几个概念。稍后会有相关详解

①、WSDL(Web Services Description Language) :web Service 的定义语言。

  1、对应一种类型的文件.wsdl

  2、定义了web service的服务器端与客户端应用交互传递请求和相应数据的格式和方式。

  3、一个 web service 对应一个唯一的 wsdl文档。

②、SOAP(simple object access protocal):简易对象访问协议

  1、一种简单的、基于HTTP和XML的协议,用于在WEB上交换结构化的数据。

  2、soap消息:请求消息和响应消息

  3、http+xml片段

③、SEI(Webservice EndPointInterface):web service的终端接口

  1、Web Service 服务器用来处理请求的接口

④、CXF:Celtix +XFire:一个Apache的用于开发Webservice服务端和客户端的框架。

3、开发Web service

  开发方式:①使用jdk开发(版本1.6以上) ②使用CXF框架开发(工作中)

  组成:客户端、服务端

  •   使用Jdk开发

     1、开发服务端:

        Webservice 编码 :@WebService(SEI 和SEI的实现类)、@WebMethod(SEI中所有的方法)

        发布Webservice: EndPoint(终端,发布webservice)

/*
 * SEI
 */
@WebService
public interface HelloWS {
 @WebMethod
 public String sayHello(String str1);
}
/*
 * SEI实现
 */
@WebService
public class HelloWSImpl implements HelloWS {

    @Override
    public String sayHello(String str1) {
        System.out.println("hello"+str1);
        return "hello"+str1;
    }

}
/*
 * 发布web service
 * address:发布地址 http://ip地址:端口号/访问名
 * implementor:SEI实现类实例
 */
public class ServerTest {

    public static void main(String[] args){
        String address="http://localhost:8989/20171017/hellows";
        //Endpoint.publish(address, implementor)
        Endpoint.publish(address, new HelloWSImpl());
        System.out.println("发布成功");
    }
}

      2、开发客户端

        ①、使用myeclipse自带的 web service浏览器访问

          -查看对应的wsdl文档:服务器端发布的address?wsdl(一般浏览器)

          -请求 webservice并查看请求和响应消息(webservice浏览器)步骤如下:(服务器启动的状态下)

1、

2、

3、

4、

5、

 一次Web Service请求的流程:①、客户端向服务器发送一个soap消息(http消息和xml片段)②、服务器端处理完请求之后向客户端返回一个soap消息。

        ②、创建客户端应用编码方式访问

          借助jdk的wsimport.exe工具生成客户端代码。 方式:wsimport -keep url  //url是.wsdl文件的路径。可以是网址路径http://localhost:8989/20171017/hellows?wsdl 也可以是.wsdl保存在本地目录下的路径F:workws_Client1hellows.wsdl。

          借助生成的代码编写请求代码

        如图所示:

切换到你客户端工程的SRC路径下执行以下命令。(我在环境变量当中添加了wsimport)。运行成功如下,刷新项目工程代码,可以看到。

  

public class ClientTest {
    public static void main(String[] args) {
        /**
         * <service name="HelloWSImplService">
         *         <port name="HelloWSImplPort" binding="tns:HelloWSImplPortBinding">
         *             <soap:address location="http://localhost:8989/20171017/hellows"/>
         *         </port>
         * </service>
         */
        HelloWSImplService service = new HelloWSImplService();
        HelloWSImpl helloWS = service.getHelloWSImplPort();
        System.out.println(helloWS.getClass());
        System.out.println(helloWS.sayHello("wang"));
    }
}

 监听请求:使用MyEclipse的TCP/IP工具(端口转发)

    1、将.wsdl文件保存在客户端本地 2、修改文档将端口号8989改为8080 3、根据本地.wsdl文档生成客户端代码  4、配置MyEclipse的TCP/IP,启动监听

      

      

 

点击start。运行客户端代码

  • 使用CXF开发Web Service 只需要加入apache-cxf-3.0.13.zip/lib里的jar包即可,其他不需要改动。

4、解析.wsdl文档

 WSDL 是一种 XML 文档

WSDL 文档是利用这些主要的元素来描述某个 web service 的:

元素定义
<portType> web service 执行的操作
<message> web service 使用的消息
<types> web service 使用的数据类型
<binding> web service 使用的通信协议
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. -->
 4 
 5 <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. -->
 6 
 7 <definitions name="HelloWSImplService" targetNamespace="http://ws.com/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
 8 
 9 
10   <types>
11 
12 
13     <xsd:schema>
14 
15       <xsd:import schemaLocation="http://localhost:8989/20171017/hellows?xsd=1" namespace="http://ws.com/"/>
16 
17     </xsd:schema>
18 
19   </types>
20 
21     <!-- 请求消息格式<sayHello> -->
22   <message name="sayHello">
23 
24     <part name="parameters" element="tns:sayHello"/>
25 
26   </message>
27 
28   <!-- 响应消息格式<sayHelloResponse> -->
29   <message name="sayHelloResponse">
30 
31     <part name="parameters" element="tns:sayHelloResponse"/>
32 
33   </message>
34 
35   <!-- portType 定义服务器端的SEI -->
36   <portType name="HelloWSImpl">
37 
38     <!-- 用来指定SEI中处理请求的方法 -->
39     <operation name="sayHello">
40       <!-- 指定客户端应用传来的数据 会引用上面请求<message>定义的格式-->
41       <input message="tns:sayHello"/> 42       <!-- 指定福区段应用传出的数据 会引用上面响应<message>定义的格式--> 43       <output message="tns:sayHelloResponse"/> 44 45     </operation> 46 47   </portType> 48 49   <!-- 用于定义SEI实现类 type:使用上面<portType>--> 50   <binding name="HelloWSImplPortBinding" type="tns:HelloWSImpl"> 51     <!-- 绑定数据是一个document(xml)--> 52     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 53 54     <!-- 定义实现的方法 --> 55     <operation name="sayHello"> 56 57       <soap:operation soapAction=""/> 58 59 60       <input> 61           <!-- literal:文本数据--> 62           <soap:body use="literal"/> 63 64       </input> 65 66 67       <output> 68 69           <soap:body use="literal"/> 70 71       </output> 72 73     </operation> 74 75   </binding> 76 77   <!-- 一个Web service容器。name:用于指定客户端容器类 因此客户端会 HelloWSImplService service = new HelloWSImplService();--> 78   <service name="HelloWSImplService"> 79 80     <!-- 用来指定客户端处理请求的入口 :HelloWSImpl helloWS = service.getHelloWSImplPort(); --> 81     <port name="HelloWSImplPort" binding="tns:HelloWSImplPortBinding"> 82       <!-- web service 请求地址--> 83       <soap:address location="http://localhost:8989/20171017/hellows"/> 84 85     </port> 86 87   </service> 88 89 </definitions>

 5、CXF拦截器的使用

為了能够动态的操作请求和响应返回数据,cxf设计了拦截器。

拦截器分类:按位置分:服务器拦截器、客户端拦截器

      按消息方向分:入拦截器、出拦截器

      按定义分:系统拦截器、自定义拦截器

拦截器API:Interceptor(拦截器接口)

      AbstractPhaseInterceptor(自定义拦截器继承类)

 例子:服务器端系统拦截器

/*
 * 发布web service
 */
public class ServerTest {

    public static void main(String[] args) {
        String address = "http://localhost:8888/20171025cxf/hellows";
        Endpoint publish = Endpoint.publish(address, new HelloWSImpl());
        System.out.println(publish);
      
        EndpointImpl endpointImpl=(EndpointImpl) publish;
        List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
     系统日志入拦截器: inInterceptors.add(
new LoggingInInterceptor()); List<Interceptor<? extends Message>> outInterceptors = endpointImpl.getOutInterceptors();
     系统日志出拦截器 outInterceptors.add(
new LoggingOutInterceptor()); System.out.println(endpointImpl); System.out.println("发布成功"); } }

客户端发送请求时:服务器端出现如下消息log

2017-10-26 11:38:51 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
信息: Inbound Message
----------------------------
ID: 1
Address: http://localhost:8888/20171025cxf/hellows?wsdl
Http-Method: GET
Content-Type:
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Type=[null], Host=[localhost:8888], Pragma=[no-cache], User-Agent=[Apache CXF 3.0.13]}
--------------------------------------
2017-10-26 11:38:52 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
信息: Inbound Message
----------------------------
ID: 2
Address: http://localhost:8888/20171025cxf/hellows
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[182], content-type=[text/xml; charset=UTF-8], Host=[localhost:8888], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.13]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws1.com/"><arg0>cxf</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
hellocxf
2017-10-26 11:38:52 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
信息: Outbound Message
---------------------------
ID: 2
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://ws1.com/"><return>hellocxf</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
--------------------------------------

public class Test {

    public static void main(String[] args) {
        HelloWSImplService helloWSImplService = new HelloWSImplService(); 
        HelloWS helloWSImplPort = helloWSImplService.getHelloWSImplPort();
        //发送请求的客户端对象
        Client client = ClientProxy.getClient(helloWSImplPort);
        //客户端的日志的出拦截器的集合
        List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
        outInterceptors.add(new LoggingOutInterceptor());
        
        //客户端的日志的日拦截器的集合
        List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();
        inInterceptors.add(new LoggingInInterceptor());
        System.out.print(helloWSImplPort.sayHello("cxf"));
    }

}

客户端配置拦截器后,请求服务,客户端出现如下log

2017-10-26 11:43:09 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://ws1.com/}HelloWSImplService from WSDL: http://localhost:8888/20171025cxf/hellows?wsdl
2017-10-26 11:43:10 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
信息: Outbound Message
---------------------------
ID: 1
Address: http://localhost:8888/20171025cxf/hellows
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws1.com/"><arg0>cxf</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
2017-10-26 11:43:10 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
信息: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {Content-Length=[207], content-type=[text/xml;charset=UTF-8], Server=[Jetty(8.1.19.v20160209)]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://ws1.com/"><return>hellocxf</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
--------------------------------------
hellocxf

自定义拦截器的使用

    参照ApacheCXFWebServiceDevelopment书138-144页

 6、SOAP

<soap:Envelope  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws1.com/"><arg0>cxf</arg0></ns2:sayHello></soap:Body></soap:Envelope>

一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:

  • 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息。
  • 可选的 Header 元素,包含头部信息。如果 Header 元素被提供,则它必须是 Envelope 元素的第一个子元素。
  • 必需的 Body 元素,包含所有的调用和响应信息
  • 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息。如果已提供了 Fault 元素,则它必须是 Body 元素的子元素。在一条 SOAP 消息中,Fault 元素只能出现一次。
原文地址:https://www.cnblogs.com/huadiyatou/p/7735340.html