`
leixbo
  • 浏览: 33904 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hessian之服务端原理

    博客分类:
  • Java
阅读更多

 

一、简介 

 

     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服务端 客户端 可运行"的压缩包提供了一个方便的平台,让开发者能够快速了解和测试Hessian协议的工作原理。通过这个示例,你可以深入理解如何在Java环境中搭建和使用Hessian服务,以及如何在...

    hessian demo 包括服务端和客户端

    首先,我们来了解**Hessian服务端**的工作原理。服务端通常会暴露一个或多个接口,这些接口定义了可供客户端调用的方法。在Java中,我们可以创建一个实现特定业务逻辑的类,然后通过HessianServlet或者...

    hessian小例(java)

    在这个“hessian小例(java)”中,我们将深入探讨如何在Java Web项目中使用Hessian进行服务端和客户端的交互。 首先,我们要理解Hessian的工作原理。Hessian基于HTTP协议,能够将Java对象序列化为二进制流,从而在...

    Hessian Binary Web Service Protocol远程接口调用入门Demo

    通过这个简单的Demo,你将能够深入理解Hessian的工作原理和使用方式。在实际项目中,你可以根据需要调整Hessian的配置,例如设置超时时间、添加安全验证等,以满足更复杂的需求。记住,Hessian是提高Web服务性能的一...

    Hessian应用

    本文将深入探讨Hessian的应用及其原理,帮助读者理解如何在实际项目中有效地利用这一工具。 首先,我们要明确Hessian的目标:提供一种简单的远程调用方式,使得服务端和客户端之间能进行高效的通信。与常见的基于...

    hessian vc实现

    Hessian是一种高效的二进制序列...通过理解Hessian协议的原理和选择合适的库,你可以构建一个高效的C++客户端来与Hessian服务端进行交互。在实际项目中,确保对各种异常情况有充分的考虑,以提高软件的稳定性和可靠性。

    Hessian

    **三、Hessian工作原理** 1. **序列化**:在服务端,Hessian将Java对象转换为二进制流,这个过程称为序列化。 2. **网络传输**:序列化后的二进制流被发送到客户端,通过HTTP协议进行传输。 3. **反序列化**:在...

    hessian入门实例,导入就可以直接运行

    Hessian服务端的创建是整个流程的起点。在服务端,我们需要定义一个服务接口和其实现类。例如,我们可以创建一个名为`UserService`的接口,其中包含一些远程调用的方法,如`getUserInfo()`。然后,我们需要实现这个...

    Hessian实战应用之获取客户端请求URL和重新转发客户端请求

    在Hessian服务端,我们可以利用Servlet API来获取这些信息。例如,`HttpServletRequest`对象提供了`getRemoteAddr()`方法来获取客户端的IP地址,`getQueryString()`获取请求参数,而`getRequestURL()`则返回不带查询...

    Spring中集成Hessian的问题

    Hessian服务端的序列化和反序列化过程、HTTP请求处理以及异常处理等都是关键部分。而Spring框架如何与Hessian进行集成,包括服务注册、请求处理和代理创建等,也值得研究。 **工具支持** 为了方便调试和测试,可以...

    hessian示例远程轻量级传输

    实现一个简单的Hessian服务端和客户端,首先我们需要引入Hessian库。在Java中,你可以通过Maven或Gradle添加依赖。 1. **创建服务端(Server)** ```java import com.caucho.hessian.server.HessianServlet; ...

    hessian

    在【标签】中,"源码"可能指的是查看或分析Hessian协议的底层实现,这对于理解其工作原理和优化性能非常有帮助。"工具"可能指的是使用Hessian相关的开发工具或框架,例如HessianProxyFactory、HessianServlet等。 ...

    Hessian的Spring配置

    **Hessian的基本原理** Hessian基于HTTP协议,它将Java对象转换为高效的二进制格式,以减少网络传输的数据量。它同时支持服务端和客户端之间的方法调用,包括同步调用和异步调用。Hessian通过序列化和反序列化技术...

    hessian-example

    下面我们将深入探讨Hessian的工作原理、优势以及如何在实际项目中应用。 Hessian的核心概念在于其二进制序列化机制,这使得数据传输更为紧凑,减少了网络传输的开销。与基于XML的SOAP协议相比,Hessian的数据格式更...

    Hessian的学习笔记

    Hessian的工作原理可以分为以下步骤: 1. 客户端通过Hessian提供的API发起请求。 2. Hessian将请求信息进行序列化,产生二进制流。 3. Hessian基于Http协议将二进制流传输至服务端。 4. 服务端根据Hessian提供的API...

    hessian 使用实例

    ### Hessian的基本原理 Hessian协议的核心是它的二进制编码,这种编码方式能够将Java对象转换为紧凑的字节序列。在服务调用时,客户端通过HTTP发送一个Hessian编码的请求到服务端,服务端接收并解码这个请求,执行...

    Hessian实例下载

    Hessian的工作原理是将Java对象序列化为二进制格式,然后通过HTTP传输。这种序列化方式相比基于文本的XML或JSON,数据传输更加高效。在服务端,Hessian会将接收到的二进制数据反序列化回Java对象,并执行相应的服务...

    Hessian案列代码

    在IT行业中,Hessian是一种二进制协议,它被广泛用于远程方法...这个案例对于理解Hessian的工作原理及其在实际开发中的应用非常有帮助。通过深入学习和实践,开发者可以更好地利用Hessian来提升项目的性能和可维护性。

    hessian简单实例

    这个简单的实例旨在帮助开发者快速理解Hessian的工作原理,并将其应用于实际项目中。通过运行`hessian-server`和`hessian-client`,你可以亲身体验到Hessian的高效和便捷。在实际开发中,你可能需要根据具体需求进行...

Global site tag (gtag.js) - Google Analytics