首页 > 代码库 > 理解WSDL,IDL

理解WSDL,IDL

很多RPC技术都会使用中间语言来定义接口描述,比如Web Service常用的WSDL, Thrift使用的IDL。


这类文件都是接口定义/描述语言 (Interface Definition/Description Language),有几个特点:

1. 采用中间语言来描述接口,以及接口使用到的数据结构(类)

2. 一般都采用文本文件,方便传递

3. 语法上可以使用XML,也可以自定义格式。使用XML的话有一堆工具可以进行读写和直接映射到类/对象。使用自定义格式的话需要自己写解析


需要理解的是,从RPC调用的过程来说,IDL不是RPC的必要组件,它的存在主要是为了支持跨语言调用,通过IDL,可以使用工具生成不同平台下的接口定义和相关的类定义,从本质上说IDL只是描述接口的数据结构的一种方式,更通俗的说,是描述消息的一种方式。

因为RPC本质上来说就是不同主机之间的消息传递,只是这种消息是一个方法而已。所以通过IDL可以让不同语言下的程序拿到统一含义的消息描述。


如果不是跨语言的RPC调用,根本不需要IDL来描述接口,可以直接把定义接口和相关数据结构的类打包,比如取名叫api.jar,服务发布方把api.jar直接发布出去。服务消费者拿到api.jar之后实际上就拿到了消息的数据结构,可以在本地直接使用这些数据结构,保证服务消费者向服务提供方发送的消息是符合约定的。


当然,使用IDL的话,可以让组织外部或者不方便拿到api.jar的人根据IDL来生产接口的数据结构,但请记住,IDL不是RPC的必要组件,它只是为了提供一种描述接口的数据结构,让服务的消费者可以根据它来生成本地的数据结构,从而发送正确格式的消息。


使用Web Service来举例,服务发布方直接使用POJO定义一个HelloService服务,不需要WSDL来描述接口

package test;


public interface HelloService {

	public String sayHello(String name);

}

服务发布方实现HelloService 服务

package test;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.cxf.frontend.ServerFactoryBean;

public class HelloServiceImpl implements HelloService{
	public String sayHello(String name) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("sayHello()... name:" + name);
		return sdf.format(new Date()) + " hello " + name;
	}

	public static void main(String[] args) {
		ServerFactoryBean bean = new ServerFactoryBean();

		// 服务的发布地址
		bean.setAddress("http://localhost:9001/HelloService");
		// 提供服务的类的类型
		bean.setServiceClass(HelloService.class);
		// 提供服务的实例
		bean.setServiceBean(new HelloServiceImpl());
		// 发布服务 publish()...
		bean.create();
		System.out.println("server ready...");
	}
}

服务消费方拿到服务发布方给的HelloService.class类,可以直接用HelloService的类型在本地生成代理,不需要先使用WSDL在本地来生成HelloService的数据结构。

package test;

import org.apache.cxf.frontend.ClientProxyFactoryBean;

public class HelloServiceClient {
	public static void main(String[] args) {
		// 创建WebService客户端代理工厂
		ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
		// 注册WebService接口
		factory.setServiceClass(HelloService.class);
		// 设置WebService地址
		factory.setAddress("http://localhost:9001/HelloService");
		HelloService iHelloWorld = (HelloService) factory.create();
		System.out.println("invoke webservice");
		System.out.println("message context is:" + iHelloWorld.sayHello("Josen"));
		System.exit(0);
	}
}

执行结果:











理解WSDL,IDL