一、远程通讯协议的基本原理
网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协议,网络 IO ,主要有 bio 、 nio 、 aio 三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
二、应用级协议Binary-RPC
Binary-RPC(Remote Procedure Call Protocol,远程过程调用协议)是一种和RMI(Remote Method Invocation,远程方法调用)类似的远程调用的协议,它和RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。
Binary -RPC 协议的一次远程通信过程:
1 、客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充;
2 、填充完毕后将二进制格式文件转化为流,通过传输协议进行传输;
3 、接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理;
4 、处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回。
问题总结:
1 、传输的标准格式是:标准格式的二进制文件。
2 、怎么样将请求转化为传输的流?将二进制格式文件转化为流。
3 、怎么接收和处理流?通过监听的端口获取到请求的流,转化为二进制文件,根据协议获取请求的信息,进行处理并将结果写入 XML 中返回。
4 、传输协议是?http
三、Hessian介绍
Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协议,所以它很适合于发送二进制数据,同时又具有防火墙穿透能力。Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们用的 WebService。只是它不使用SOAP协议,但相比webservice而言更简单、快捷。
Hessian官网:http://hessian.caucho.com/
Hessian 可通过Servlet提供远程服务,需要将匹配某个模式的请求映射到Hessian服务。也可Spring框架整合,通过它的 DispatcherServlet可以完成该功能,DispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类, 用来处理发送的请求,而Hessian的这个远程过程调用,完全使用动态代理来实现的,,建议采用面向接口编程,Hessian服务通过接口暴露。
Hessian处理过程示意图:客户端——>序列化写到输出流——>远程方法(服务器端)——>序列化写到输出流 ——>客户端读取输入流——>输出结果
四、Hessian入门范例
4.1下载Hessian
去Hessian官网:http://hessian.caucho.com/下载最新的Hessian包,如下图所示:
下载完成之后,得到如下图所示的jar文件
4.2、搭建Hessian测试服务端web项目
新建一个名为HessianServer的web project。将hessian-4.0.37.jar放入WEB-INF/lib文件夹中,如下图所示:
在进行基于Hessian的项目开发时,应当注意以下几点:
JAVA服务器端必须具备以下几点:
- 包含Hessian的jar包。
- 设计一个接口,用来给客户端调用。
- 实现该接口的功能。
- 配置web.xml,配好相应的servlet。
- 对象必须实现Serializable 接口。
- 对于复杂对像可以使用Map的方法传递。
客户端必须具备以下几点:
- java客户端包含Hessian.jar的包。
- 具有和服务器端结构一样的接口。
- 利用HessianProxyFactory调用远程接口。
4.3、设计一个提供服务接口来给客户端调用
IService接口的代码如下:
1 package gacl.hessian.service; 2 3 import gacl.hessian.model.User; 4 5 /** 6 * <p>ClassName: IService<p> 7 * <p>Description: 定义对外提供服务的接口<p> 8 * @author xudp 9 * @version 1.0 V 10 * @createTime 2014-8-7 下午05:29:23 11 */ 12 public interface IService { 13 14 /** 15 * MethodName: getUser 16 * Description: 获取用户 17 * @author xudp 18 * @return User对象 19 */ 20 public User getUser(); 21 }
IService接口中用到了一个User类
User类的代码如下:
1 package gacl.hessian.model; 2 3 import java.io.Serializable; 4 5 /** 6 * <p>ClassName: User<p> 7 * <p>Description: 创建一个User类,实现序列化接口, 8 * User实现了序列化接口后就可以进行序列化, 9 * 然后就可以通过网络将序列化后的user传输到另一台计算机上<p> 10 * @author xudp 11 * @version 1.0 V 12 * @createTime 2014-8-7 下午05:25:09 13 */ 14 public class User implements Serializable{ 15 16 private static final long serialVersionUID = 1692800630322115854L; 17 //name属性 18 private String name; 19 20 public User() { 21 22 } 23 24 public User(String name) { 25 this.name = name; 26 } 27 28 public String getName() { 29 return name; 30 } 31 32 public void setName(String name) { 33 this.name = name; 34 } 35 36 37 }
4.4、编写IService接口的具体实现类
ServiceImpl实现类的代码如下:
1 package gacl.hessian.service.impl; 2 3 import gacl.hessian.model.User; 4 import gacl.hessian.service.IService; 5 6 /** 7 * <p>ClassName: ServiceImpl<p> 8 * <p>Description: IService接口的具体实现类<p> 9 * @author xudp 10 * @version 1.0 V 11 * @createTime 2014-8-7 下午05:32:15 12 */ 13 public class ServiceImpl implements IService { 14 15 /* (non-Javadoc) 16 * @MethodName getUser 17 * @Description 实现IService接口的getUser方法 18 * @author xudp 19 * @return 返回一个User对象 20 * @see gacl.hessian.service.IService#getUser() 21 */ 22 public User getUser() { 23 return new User("孤傲苍狼"); 24 } 25 }
4.5、配置web.xml,添加对HessianServlet的配置
如下面的红色部分所示:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 6 <welcome-file-list> 7 <welcome-file>index.jsp</welcome-file> 8 </welcome-file-list> 9 10 <servlet> 11 <!-- 配置 HessianServlet,Servlet的名字随便配置,例如这里配置成ServiceServlet--> 12 <servlet-name>ServiceServlet</servlet-name> 13 <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> 14 15 <!-- 配置接口的具体实现类 --> 16 <init-param> 17 <param-name>service-class</param-name> 18 <param-value>gacl.hessian.service.impl.ServiceImpl</param-value> 19 </init-param> 20 </servlet> 21 <!-- 映射 HessianServlet的访问URL地址--> 22 <servlet-mapping> 23 <servlet-name>ServiceServlet</servlet-name> 24 <url-pattern>/ServiceServlet</url-pattern> 25 </servlet-mapping> 26 27 </web-app>
到此,Hessian的服务端编写就算是完成了。
配置完成之后,启动项目,在地址栏输入:http://localhost:端口号/项目名/ServiceServlet,如果显示结果如下,说明配置和接口编写正确:
Hessian Requires POST
4.6、编写Hessian的测试客户端
新建一个HessianTestClient的普通Java项目作为测试客户端,需引入上述的hessian-4.0.37.jar,还需要服务端导出IService和User两个类的jar,放入lib。或创建两个一摸一样的类,这里是采用将服务端的IService和User两个类打包成jar包提供给客户端进行调用,打成Jar包的过程如下图所示:
选中要打包的类
这样就将IService类和User类打包成了一个Hessian_Common.jar包,如下图所示:
创建好的HessianTestClient工程如下所示:
HessianTestClient项目引入上述的hessian-4.0.37.jar和IService和User两个类的jar,编写HessianClient客户端,HessianClient类的代码如下所示:
1 package hessian.test.client; 2 3 import java.net.MalformedURLException; 4 5 import gacl.hessian.model.User; 6 import gacl.hessian.service.IService; 7 8 import com.caucho.hessian.client.HessianProxyFactory; 9 10 /** 11 * <p>ClassName: HessianClient<p> 12 * <p>Description: 调用Hessian的客户端<p> 13 * @author xudp 14 * @version 1.0 V 15 * @createTime 2014-8-7 下午07:05:42 16 */ 17 public class HessianClient { 18 19 public static void main(String[] args) throws MalformedURLException { 20 /* 21 <servlet> 22 <!-- 配置 HessianServlet,Servlet的名字随便配置,例如这里配置成ServiceServlet--> 23 <servlet-name>ServiceServlet</servlet-name> 24 <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> 25 26 <!-- 配置接口的具体实现类 --> 27 <init-param> 28 <param-name>service-class</param-name> 29 <param-value>gacl.hessian.service.impl.ServiceImpl</param-value> 30 </init-param> 31 </servlet> 32 <!-- 映射 HessianServlet的访问URL地址--> 33 <servlet-mapping> 34 <servlet-name>ServiceServlet</servlet-name> 35 <url-pattern>/ServiceServlet</url-pattern> 36 </servlet-mapping> 37 */ 38 //在服务器端的web.xml文件中配置的HessianServlet映射的访问URL地址 39 String url = "http://192.168.1.144:8080/HessianServer/ServiceServlet"; 40 HessianProxyFactory factory = new HessianProxyFactory(); 41 IService service = (IService) factory.create(IService.class, url);//创建IService接口的实例对象 42 User user = service.getUser();//调用Hessian服务器端的ServiceImpl类中的getUser方法来获取一个User对象 43 System.out.println(user.getName()); 44 } 45 }
将HessianServer项目部署到tomcat服务器,启动tomcat服务器,然后运行HessianClient客户端,运行结果如下:
从运行结果中可以看到,在HessianClient客户端中已经成功获取到远程的HessianServer服务器端传输过来的User对象,然后打印出User对象的名字。
以上就是Hessian的一个入门级别的案例!
4.7、测试项目下载
Hessian服务端:HessianServer,Hessian测试客户端:HessianTestClient