webservice 客户端、服务端程序

末鹿安然 提交于 2019-12-01 14:12:35

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 文档,包含下列元素:

  1. Envelope(必需):标识XML 文档为一条 SOAP 消息
  2. Header(可选):包含头部信息:一般为消息指定某些特征信息:例如指定自定义标签过滤某些参数
  3. Body(必需):包含所有的调用和响应信息
  4. Fault(可选):提供有关在处理此消息所发生错误的信息

xmlns:soap

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

SOAP Header

为相互通信的团体之间提供了一种很灵活的机制,在无需预先协定的情况下,以分散但标准的方式扩展消息。可以在SOAP.Header中添加条目实现这种扩展,如认证、事务管理、支付等。:Header元素是SOAP封装元素的第一个直接子元素。Header元素的所有直接子元素称作条目,条目的编码规则如下:

  • 1个条目有完整元素名(包括名域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>
        <ns1:sayHello xmln1:ns2="http://inter.ws.zhiwei.com/">
            <arg0>china</arg0>
        </ns1: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属性指定输入输出的编码方式,这里没有指定编码。

  1. 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客户端程序

  1. 使用JAX-WS实现对webservice的访问
  2. JDK自带的“wsimport -keep wsdl网址”自动生成
  3. 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服务成功。

方式2:wsimport

wsimport:自动生成的层次结构:

wsimport自动生成代码测试:

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

结果:测试成功

方式3:wsdl2java

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

生成代码结构层次:

测试代码:

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

结果:测试成功

Hello --->China!!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!