一、简介
Hessian是一个由Caucho Technology开发的轻量级二进制RPC工具,与普通的RPC实现方式不同的是,它是基于 Http 协议进行的数据传输。
Hessian通常通过Web应用来提供服务,非常类似于WebService,但它不使用SOAP协议。相比WebService,Hessian更简单、快捷、轻量级。
与一般的RPC实现方式一样,它的处理过程如下:
客户端 -> 序列化写到输出流 -> 远程方法(服务器端)-> 序列化写到输出流 -> 客户端读取输入流 -> 输出结果
二、代码分析
hessian的服务端就是一个servlet,拦截请求,然后分析解析参数,调用对应的local服务。入口类为com.caucho.hessian.server.HessianServlet,该类基础自HttpServlet,就是一个普通的servlet,配置时将某个路径的请求映射到这个Servlet上(与Struts1的org.apache.struts.action.ActionServlet类似吧),既然是一个servlet,那我们看看service方法都做了些什么。
/** * Execute a request. The path-info of the request selects the bean. * Once the bean's selected, it will be applied. */ public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; if (! req.getMethod().equals("POST")) { res.setStatus(500); // , "Hessian Requires POST"); PrintWriter out = res.getWriter(); res.setContentType("text/html"); out.println("<h1>Hessian Requires POST</h1>"); return; } String serviceId = req.getPathInfo(); String objectId = req.getParameter("id"); if (objectId == null) objectId = req.getParameter("ejbid"); ServiceContext.begin(req, res, serviceId, objectId); try { InputStream is = request.getInputStream(); OutputStream os = response.getOutputStream(); response.setContentType("x-application/hessian"); SerializerFactory serializerFactory = getSerializerFactory(); invoke(is, os, objectId, serializerFactory); } catch (...Exception e) { //.... throw new ServletException(e); } finally { ServiceContext.end(); } }
1、请求方式的验证
我们可以看到该方法对请求方法进行了验证,非POST的请求方式将不进行处理(通过hessian客户端方式调用的为POST方式,二进制流都应该是post方式),可以在浏览器上测试,输入请求地址,应该会返回500错误码。
2、上下文数据保存
ServiceContext.begin(req, res, serviceId, objectId)进行了上下数据的保存
public static void begin(ServletRequest request, ServletResponse response, String serviceName, String objectId) throws ServletException { ServiceContext context = (ServiceContext) _localContext.get(); if (context == null) { context = new ServiceContext(); _localContext.set(context); } context._request = request; context._response = response; context._serviceName = serviceName; context._objectId = objectId; context._count++; }
_localContext是一个ThreadLocal对象,ServiceContext用来保存当前调用线程上下文的一些信息,如request、response等非常重要的数据
3、将输入输出流,序列化工厂传入invoke方法,进行调用invoke(is, os, objectId, serializerFactory)
这个方法内部实际上是调用了HessianSkeleton对象的invoke方法
protected void invoke(InputStream is, OutputStream os, String objectId, SerializerFactory serializerFactory) throws Exception { if (objectId != null) _objectSkeleton.invoke(is, os, serializerFactory); else _homeSkeleton.invoke(is, os, serializerFactory); }
_objectSkeleton与_homeSkeleton都为HessianSkeleton对象,暂时没看懂这两个对象有什么的区别
4、看看HessianSkeleton 的invoke(InputStream, OutputStream,SerializerFactory)方法做了什么
/** * Invoke the object with the request from the input stream. * * @param in the Hessian input stream * @param out the Hessian output stream */ public void invoke(InputStream is, OutputStream os, SerializerFactory serializerFactory) throws Exception { //...... HessianInputFactory.HeaderType header = _inputFactory.readHeader(is); AbstractHessianInput in; AbstractHessianOutput out; switch (header) { case CALL_1_REPLY_1: in = _hessianFactory.createHessianInput(is); out = _hessianFactory.createHessianOutput(os); break; case CALL_1_REPLY_2: in = _hessianFactory.createHessianInput(is); out = _hessianFactory.createHessian2Output(os); break; case HESSIAN_2: in = _hessianFactory.createHessian2Input(is); in.readCall(); out = _hessianFactory.createHessian2Output(os); break; default: throw new IllegalStateException(header + " is an unknown Hessian call"); } //.... invoke(_service, in, out); //.... }
invoke方法先解析请求头,因为hessian有不同的版本,并且分请求与相应的请求头,因此有多种hederType:( CALL_1_REPLY_1、CALL_1_REPLY_2、HESSIAN_2、REPLY_1、 REPLY_2)
然后根据不同的请求类型,构建不同的AbstractHessianInput、AbstractHessianOutput对象(不同的hederType,处理有所差别),然后最终也是调用invoke重载方法,把AbstractHessianInput、AbstractHessianOutput对象作为参数传递进去
5、看看真正做事的invoke方法
/** * Invoke the object with the request from the input stream. * * @param in the Hessian input stream * @param out the Hessian output stream */ public void invoke(Object service, AbstractHessianInput in, AbstractHessianOutput out) throws Exception { //.. Object []values = new Object[args.length]; for (int i = 0; i < args.length; i++) { // XXX: needs Marshal object values[i] = in.readObject(args[i]); } Object result = null; try { result = method.invoke(service, values); } catch (Exception e) { //.. } //.. }
可以看到通过AbstractHessianInput对象,进行了参数的获取,包括请求的方法,请求的参数,然后利用反射调用调用service的方法,最后将处理结果写回去
到此整个流程就完了,与一般的RPC处理方式类似吧,只是在参数的传递、解析时有所不同,但最终所达到的目的都是一样的
相关推荐
hessian 服务端 客户端 可运行
hessian demo 包括服务端和客户端,绝对能用,包括了jar包
【Android】使用Hessian与Java服务端通讯
包含了一个完整的hession结构开发的文件服务,并实现了基础的dao+service,并进行统一pom管理.
c#实现的hessian的服务端和客户端,iis亲测可以通过,
Hessian服务端 入门程序
spring springmvc hessian rpc客户端及服务端示例demo,可直接运行,适合hessian入门的同学们学习,仅供有需要的同学们参考
java hessian-3.0.38.jar。修改了原生的jar包,解决了hessian 序列化BigDecimal的精度问题。注意,请在hessian服务端和客户端中分别替换此jar包哦!! 只替换服务端hessian jar包还是会有问题。
java项目中使用hessian框架实现远程调用,该资源内附hessian服务端,hessian客户端和使用说明文档,以供使用参考,轻松教会你hessian远程调用!
此例子有两个工程,hessianServer(服务端工程),hessianClient(客户端工程),把 hessianServer工程 启动之后就可以通过 hessianClient 访问 服务端的服务了。
一个Spring整合Hessian的Demo,同时包含Hessian服务端与客户端。是一个Maven工程,IDE使用的Eclipse,运行前需要安装Eclipse的Maven插件。可以结合文章一起学习,地址是...
这篇文档讲解的是Hessian的实现原理,简单易懂,是一个很好用的可以实现远程访问的技术!!!
该案例有hessian java python,该案例有hessian java python,该案例有hessian java python
一个简单的例子学习hessian服务:服务端为Java,客户端为C#。 先要准备好C#和Java的第三方类库:http://hessian.caucho.com/ Hssiancharp.dll hessian-4.0.37.jar Hessian服务端(java) 打开eclipse...
Hessian协议是http://caucho.com/公司开发的一种实用的web服务技术,它采用二进制数据,传输效率比较高,简单易用,是C#.NET/IIS环境快速开发web服务应用的一种解决方案。...在服务端、客户端项目中引用此DLL文件即可。
Hessian多个版本下载,包括Hessian3.1.6,Hessian3.2.1,Hessian4.0.7
使用eclipse maven工程搭建hessian远程服务demo 分服务端的整合和客户端 建议阅读相关博客http://blog.csdn.net/heisemuyangquan/article/details/79460528
基于Hessian的冠状动脉血管造影分割方法
hessian资料3hessian资料3hessian资料3hessian资料3hessian资料3
struts2+ibatis+spring+Hessian 整合项目 web项目整合,服务端用hessian协议远程调用服务端的方法,hessian是用spring代理整合,struts2+ibatis+spring的整合项目,用作学习和开发基础平台构建很有用处,工程导入...