一、简介
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协议的工作原理。通过这个示例,你可以深入理解如何在Java环境中搭建和使用Hessian服务,以及如何在...
首先,我们来了解**Hessian服务端**的工作原理。服务端通常会暴露一个或多个接口,这些接口定义了可供客户端调用的方法。在Java中,我们可以创建一个实现特定业务逻辑的类,然后通过HessianServlet或者...
在这个“hessian小例(java)”中,我们将深入探讨如何在Java Web项目中使用Hessian进行服务端和客户端的交互。 首先,我们要理解Hessian的工作原理。Hessian基于HTTP协议,能够将Java对象序列化为二进制流,从而在...
通过这个简单的Demo,你将能够深入理解Hessian的工作原理和使用方式。在实际项目中,你可以根据需要调整Hessian的配置,例如设置超时时间、添加安全验证等,以满足更复杂的需求。记住,Hessian是提高Web服务性能的一...
本文将深入探讨Hessian的应用及其原理,帮助读者理解如何在实际项目中有效地利用这一工具。 首先,我们要明确Hessian的目标:提供一种简单的远程调用方式,使得服务端和客户端之间能进行高效的通信。与常见的基于...
Hessian是一种高效的二进制序列...通过理解Hessian协议的原理和选择合适的库,你可以构建一个高效的C++客户端来与Hessian服务端进行交互。在实际项目中,确保对各种异常情况有充分的考虑,以提高软件的稳定性和可靠性。
**三、Hessian工作原理** 1. **序列化**:在服务端,Hessian将Java对象转换为二进制流,这个过程称为序列化。 2. **网络传输**:序列化后的二进制流被发送到客户端,通过HTTP协议进行传输。 3. **反序列化**:在...
Hessian服务端的创建是整个流程的起点。在服务端,我们需要定义一个服务接口和其实现类。例如,我们可以创建一个名为`UserService`的接口,其中包含一些远程调用的方法,如`getUserInfo()`。然后,我们需要实现这个...
在Hessian服务端,我们可以利用Servlet API来获取这些信息。例如,`HttpServletRequest`对象提供了`getRemoteAddr()`方法来获取客户端的IP地址,`getQueryString()`获取请求参数,而`getRequestURL()`则返回不带查询...
Hessian服务端的序列化和反序列化过程、HTTP请求处理以及异常处理等都是关键部分。而Spring框架如何与Hessian进行集成,包括服务注册、请求处理和代理创建等,也值得研究。 **工具支持** 为了方便调试和测试,可以...
实现一个简单的Hessian服务端和客户端,首先我们需要引入Hessian库。在Java中,你可以通过Maven或Gradle添加依赖。 1. **创建服务端(Server)** ```java import com.caucho.hessian.server.HessianServlet; ...
在【标签】中,"源码"可能指的是查看或分析Hessian协议的底层实现,这对于理解其工作原理和优化性能非常有帮助。"工具"可能指的是使用Hessian相关的开发工具或框架,例如HessianProxyFactory、HessianServlet等。 ...
**Hessian的基本原理** Hessian基于HTTP协议,它将Java对象转换为高效的二进制格式,以减少网络传输的数据量。它同时支持服务端和客户端之间的方法调用,包括同步调用和异步调用。Hessian通过序列化和反序列化技术...
下面我们将深入探讨Hessian的工作原理、优势以及如何在实际项目中应用。 Hessian的核心概念在于其二进制序列化机制,这使得数据传输更为紧凑,减少了网络传输的开销。与基于XML的SOAP协议相比,Hessian的数据格式更...
Hessian的工作原理可以分为以下步骤: 1. 客户端通过Hessian提供的API发起请求。 2. Hessian将请求信息进行序列化,产生二进制流。 3. Hessian基于Http协议将二进制流传输至服务端。 4. 服务端根据Hessian提供的API...
### Hessian的基本原理 Hessian协议的核心是它的二进制编码,这种编码方式能够将Java对象转换为紧凑的字节序列。在服务调用时,客户端通过HTTP发送一个Hessian编码的请求到服务端,服务端接收并解码这个请求,执行...
Hessian的工作原理是将Java对象序列化为二进制格式,然后通过HTTP传输。这种序列化方式相比基于文本的XML或JSON,数据传输更加高效。在服务端,Hessian会将接收到的二进制数据反序列化回Java对象,并执行相应的服务...
在IT行业中,Hessian是一种二进制协议,它被广泛用于远程方法...这个案例对于理解Hessian的工作原理及其在实际开发中的应用非常有帮助。通过深入学习和实践,开发者可以更好地利用Hessian来提升项目的性能和可维护性。
这个简单的实例旨在帮助开发者快速理解Hessian的工作原理,并将其应用于实际项目中。通过运行`hessian-server`和`hessian-client`,你可以亲身体验到Hessian的高效和便捷。在实际开发中,你可能需要根据具体需求进行...