webservice客户端和服务端程序基础入门

时间:2021-05-09 13:06:05

webservice:主要实现跨平台的web数据通信
作用:

假设存在两个业务系统,一个使用C++编写,另外一个使用Java语言编写,如果要实现两个不同的业务系统之间的数据通信就必须进行跨平台处理,互联网毫无疑问就是最好的连接平台。但是不同的业务系统之间进行通信,就必须制定双方都认可的规定:通信协议,webservice正式基于soap简单对象服务协议实现不同业务系统之间跨平台通信的.

跨平台通信技术:Webservice、RMI等

webservice服务框架:CXF/AXIS

soap请求头:simple object access protocol:简单对象访问协议

SOAP 消息必须用 XML 来编码
SOAP 消息必须使用 SOAP Envelope 命名空间
SOAP 消息必须使用 SOAP Encoding 命名空间
SOAP 消息不能包含 DTD 引用
SOAP 消息不能包含 XML 处理指令

SOAP消息构建模块:

SOAP 消息就是一个普通的 XML 文档,包含下列元素:
①:Envelope(必需):标识XML 文档为一条 SOAP 消息
②:Header(可选):包含头部信息:一般为消息指定某些特征信息:例如指定自定义标签过滤某些参数
③:Body(必需):包含所有的调用和响应信息
④:Fault(可选):提供有关在处理此消息所发生错误的信息

xmlns:soap:xml namespace指定标签元素名称空间,避免冲突,并且只能放置于指定名称空间的根元素,一般名称空间的名称指定为URI,只是为了防止命名冲突,该根标签囊括的元素必须以前缀soap开头,如果soap服务器接收到SOAP消息,Envelope的命名空间不是 http://schemas.xmlsoap.org/soap/envelope/
则自动抛弃该信息

SOAP Header

为相互通信的团体之间提供了一种很灵活的机制,在无需预先协定的情况下,以分散但标准的方式扩展消息。可以在SOAP.Header中添加条目实现这种扩展,如认证、事务管理、支付等。:Header元素是SOAP封装元素的第一个直接子元素。Header元素的所有直接子元素称作条目。条目的编码规则如下:
. 一个条目有它的完整的元素名(包括名域URi和局部名)。SOAP Header的直接子元素必须有名称限制。
. SOAP encodingStyle属性可以用来指示条目所用的编码形式。
. SOAP mustLJnderstand属性和SOAPactor属性可以用来指示如何处理这个条目以及由谁来处理
http请求的请求头中包含SOAPAction属性,web端检测到后按照SOAP消息处理

soap请求头格式:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">    
<soap:Body>
<ns2:sayHello xmlns:ns2="http://inter.ws.zhiwei.com/">
<arg0>china</arg0>
</ns2:sayHello>
</soap:Body>
</soap:Envelope>

soap响应头格式:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body><ns1:sayHelloResponse xmlns:ns1="http://inter.ws.zhiwei.com/">
<return>Hello china</return>
</ns1:sayHelloResponse>
</soap:Body>
</soap:Envelope>

SOAP和WSDL的区别和联系:
》SOAP:提供请求的格式,告诉webservice服务器,自己需要干什么
WSDL:指明webservice服务的工作类型和提供的接口,供SOAP调用

WSDL文档组成部分:

1、types:指定了WebService用到的所有数据类型,上面用到了两种数据类型,int和datetime
2、message:指明一个操作所用到的数据类型。
3、portType:指出了这个WebService所有支持的操作,就是说有哪些方法可供调用。

4、binding:
soap12:binding元素的transport指明传输协议,这里是http协议。
operation 指明要暴露给外界调用的操作。
use属性指定输入输出的编码方式,这里没有指定编码。

5、services:指定服务的一些信息,主要是指定服务的访问路径。

创建Webservice服务端程序步骤:
①创建服务接口和服务实现类
服务接口

package com.zhiwei.cxf;

import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface IHelloWorld {
public String sayHello(@WebParam(name = "name") String name);
}

服务实现类:

package com.zhiwei.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService //标记该类为webservice的服务类
@SOAPBinding(style = Style.RPC)
public class HelloWorld {

//@WebParam:类似@RequestParam:将接口接受的参数暴露
public String sayHello(@WebParam(name = "name") String name) {
return name + " say: Hello World ";
}
}

②:发布webservice服务

package com.zhiwei.service;


import javax.xml.ws.Endpoint;
import com.zhiwei.cxf.*;

public class ServerDeploy {

public static void deployService() {

System.out.println("Server start .....");
HelloWorld service = new HelloWorld();
String address = "http://localhost:9000/helloWorld";

//绑定webservice的地址和服务接口,并发布服务
Endpoint.publish(address, service);
}

public static void main(String[] args) throws InterruptedException {

deployService();
System.out.println("server ready .....");
Thread.sleep(1000 * 600);
System.out.println("server exit .....");
System.exit(0);
}
}

测试:浏览器打开http://localhost:9000/helloWorld?wsdl 可以查看webservice的wsdl文件,这里面详细介绍了webservice服务接口的使用方法。
webservice客户端和服务端程序基础入门

webservice客户端程序创建:
①:使用JAX-WS实现对webservice的访问
②:JDK自带的“wsimport -keep wsdl网址”自动生成
③:CXF框架的wsdl2java工具自动生成

方式1:JAX-WS

/**
JaxWsProxyFactoryBean:Factory for creating JAX-WS proxies
JAX-WS:Java API for XML Web Services

功能:JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services ,在JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。
*/

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

/**
* SEI:Service Endpoint Interface,服务端接口
*/

factory.setServiceClass(IHelloWorld.class); // 指定服务端提供服务的接口
factory.setAddress("http://localhost:9000/helloWorld"); // 指定服务地址

// 指定内部故障拦截器
factory.getInFaultInterceptors().add(new LoggingInInterceptor());

// 指定外部故障拦截器
factory.getOutFaultInterceptors().add(new LoggingOutInterceptor());

// 创建JAX-WS服务的代理类,代理类可以直接调用webservice中的方法
IHelloWorld service = (IHelloWorld) factory.create();

// 调用服务接口方法
System.out.println("[result]--->" + service.sayHello("Python"));

客户端结果:
webservice客户端和服务端程序基础入门
结果表明客户端调用远程的webservice服务成功。

方式2:wsimport
webservice客户端和服务端程序基础入门

wsimport:自动生成的层次结构:
webservice客户端和服务端程序基础入门

wsimport自动生成代码测试:

HelloWorldService helloWorldService = new HelloWorldService();
HelloWorld helloWorld = helloWorldService.getHelloWorldPort();
System.out.println(helloWorld.sayHello("Java"));

结果:测试成功
webservice客户端和服务端程序基础入门

方式3:wsdl2java
命令:wsdl2java -d d:/temp -client http://localhost:9000/helloWorld?wsdl

生成代码结构层次:
webservice客户端和服务端程序基础入门

测试代码:

HelloWSImpService helloWSImpService=new HelloWSImpService();

HelloWS helloWS=helloWSImpService.getHelloWSImpPort();
String result=helloWS.sayHello("--->China!");
System.out.println(result);

结果:测试成功

Hello —>China!!