• hessian原理解析二(服务端分析)


    hessian 服务端源码分析

      我们在回头看看 web.xml 中 servlet 配置

      <servlet>

        <servlet-name>HelloHessian</servlet-name>

        <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>

        <init-param>

          <param-name>service-class</param-name>

          <param-value>com.hessian.server.HelloHessianImpl</param-value>

        </init-param>

      </servlet>

      服务端HessianServlet 处理hessian 请求 ,HessianServlet 继承HttpServlet, 每个servlet有两个重要的方法 init 和 service

    1、void init(ServletConfig config) 初始化远程服务实现类、远程服务接口类以及HessianSkeleton

    a、初始化远程服务实现类, home-class 、service-class

     if (getInitParameter("home-class") != null) {

      String className = getInitParameter("home-class");

       Class<?> homeClass = loadClass(className);

      _homeImpl = homeClass.newInstance();

      init(_homeImpl);

    } else if (getInitParameter("service-class") != null) {

      String className = getInitParameter("service-class");

      Class<?> homeClass = loadClass(className);

      _homeImpl = homeClass.newInstance(); init(_homeImpl);

    }

    b 、初始化远程服务接口

    if (getInitParameter("home-api") != null) {

       String className = getInitParameter("home-api");

       _homeAPI = loadClass(className);

    } else if (getInitParameter("api-class") != null) {

       String className = getInitParameter("api-class");

      _homeAPI = loadClass(className);

    } else if (_homeImpl != null) {

       _homeAPI = _homeImpl.getClass();

    }

    c 、初始化 HessianSkeleton

    _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);

    // 取服务类的方法

    Method []methodList = apiClass.getMethods()

    // 遍历 服务类的方法,放入_methodMap

    for (int i = 0; i < methodList.length; i++) {

    Method method = methodList[i];

    Class []param = method.getParameterTypes();

    String mangledName = method.getName() + "__" + param.length;

    _methodMap.put(method.getName(), methodList[i]);

    _methodMap.put(mangledName, methodList[i]);

    _methodMap.put(mangleName(method, false), methodList[i]);

    }

    hessian 支持重载处理,关键点: 比如对于一个方法 public void sayHello(User user), 那么在_methodMap中会存放三个key sayHello sayHello_1, sayHello_User

    2、service(ServletRequest request, ServletResponse response) 重写父类的service 方法

    2.1、 检查请求方式是否为POST

    if (! req.getMethod().equals("POST")) {

      res.setStatus(500); //  "Hessian Requires POST"

       return;

    }

    2.2、获取输入输出流、对象的序列化工厂 执行目标目标服务方法

    ServletInputStream e = request.getInputStream();

    ServletOutputStream os = response.getOutputStream();

    SerializerFactory serializerFactory = this.getSerializerFactory();

    hessianSkeleton.invoke(is, os, serializerFactory)

    hessianServlet 处理请求时序图

     

    HessianSkeleton invoke 方法解析:

      public void invoke(Object service,AbstractHessianInput in,AbstractHessianOutput out){

      //读取方法调用名

      String methodName = in.readMethod();

      int argLength = in.readMethodArgLength();

      Method method = this.getMethod(methodName + "_" + argLength);

       //读取调用方法参数

       Class[] args = method.getParameterTypes();

       Object[] values = new Object[args.length];

          for(int i= 0; i < args.length; ++i) {

         values[i] = in.readObject(args[i]);

       }

      //执行目标方法调用

         result = method.invoke(service, values)

         //结果输出

        out.writeReply(result);

        out.close();

          输出格式:

        

          此处为16进制数表示

          72 01 00 53 00 05 74 69 67 65 72 7A

           r            s              t   i   g    e   r   z 

  • 相关阅读:
    AjaxControlToolKit(整理)三.......(35个控件)简单介绍
    C#多线程学习
    《深入浅出WPF》视频列表
    【Redis】Redis功能及性能
    MySQL性能优化
    【Redis】Redis常用命令
    php项目相关资源
    JAVA基础知识总结:十一
    JAVA基础知识总结:九
    JAVA基础知识总结:十
  • 原文地址:https://www.cnblogs.com/wwg168/p/6337067.html
Copyright © 2020-2023  润新知