Hessian源码浅析-HessianSkeleton

 

Hessian服务端核心对象HessianSkeleton 主要做两件事

1.把客户端请求的流反序列化  得到 对应的方法名称 参数

2. 服务类(service)对应方法执行完成 把结果序列化到输出流

hessian服务端暴露服务是通过HessianServlet 

  1. public class HessianServlet extends GenericServlet {  
  2. }  
public class HessianServlet extends GenericServlet {
}

HessianServlet 的init方法主要初始化服务类(service) 和HessianSkeleton  每一个服务类对应一个HessianSkeleton  在HessianSkeleton中持有业务类的引用

  1. public void init(ServletConfig config) throws ServletException {  
  2.     super.init(config);  
  3.   
  4.     //web.xml中home-class,service-class配置服务的实现类   
  5.     if (_homeImpl != null) {  
  6.           
  7.     } else if (getInitParameter("home-class") != null) {  
  8.         String className = getInitParameter("home-class");  
  9.   
  10.         Class homeClass = loadClass(className);  
  11.   
  12.         _homeImpl = homeClass.newInstance();  
  13.   
  14.         init(_homeImpl);  
  15.     } else if (getInitParameter("service-class") != null) {  
  16.         String className = getInitParameter("service-class");  
  17.   
  18.         Class homeClass = loadClass(className);  
  19.   
  20.         _homeImpl = homeClass.newInstance();  
  21.   
  22.         init(_homeImpl);  
  23.     } else {  
  24.         if (getClass().equals(HessianServlet.class))  
  25.             throw new ServletException(  
  26.                     "server must extend HessianServlet");  
  27.   
  28.         _homeImpl = this;  
  29.     }  
  30.     //web.xml配置的 服务类实现接口    
  31.     if (_homeAPI != null) {  
  32.     } else if (getInitParameter("home-api") != null) {  
  33.         String className = getInitParameter("home-api");  
  34.   
  35.         _homeAPI = loadClass(className);  
  36.     } else if (getInitParameter("api-class") != null) {  
  37.         String className = getInitParameter("api-class");  
  38.   
  39.         _homeAPI = loadClass(className);  
  40.     } else if (_homeImpl != null) {  
  41.         //如果没有配置服务实现类的接口  递归 找到服务类最顶层的接口   
  42.         _homeAPI = findRemoteAPI(_homeImpl.getClass());  
  43.   
  44.         if (_homeAPI == null)  
  45.             _homeAPI = _homeImpl.getClass();  
  46.     }  
  47.     //TODO    
  48.     _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);  
  49. }  
	public void init(ServletConfig config) throws ServletException {
		super.init(config);

		//web.xml中home-class,service-class配置服务的实现类
		if (_homeImpl != null) {
			
		} else 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);
		} else {
			if (getClass().equals(HessianServlet.class))
				throw new ServletException(
						"server must extend HessianServlet");

			_homeImpl = this;
		}
		//web.xml配置的 服务类实现接口 
		if (_homeAPI != null) {
		} else 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 = findRemoteAPI(_homeImpl.getClass());

			if (_homeAPI == null)
				_homeAPI = _homeImpl.getClass();
		}
		//TODO 
		_homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);
	}

service方法 

  1. public void service(ServletRequest request, ServletResponse response)  
  2.         throws IOException, ServletException {  
  3.     HttpServletRequest req = (HttpServletRequest) request;  
  4.     HttpServletResponse res = (HttpServletResponse) response;  
  5.     //必须是post方式   
  6.     if (!req.getMethod().equals("POST")) {  
  7.         res.setStatus(500"Hessian Requires POST");  
  8.         PrintWriter out = res.getWriter();  
  9.         res.setContentType("text/html");  
  10.         out.println("<h1>Hessian Requires POST</h1>");  
  11.         return;  
  12.     }  
  13.     String serviceId = req.getPathInfo();  
  14.     String objectId = req.getParameter("id");  
  15.     if (objectId == null)  
  16.         objectId = req.getParameter("ejbid");  
  17.     //保存到ThreadLocal中   
  18.     ServiceContext.begin(req, serviceId, objectId);  
  19.     try {  
  20.         InputStream is = request.getInputStream();  
  21.         OutputStream os = response.getOutputStream();  
  22.         response.setContentType("application/x-hessian");  
  23.         SerializerFactory serializerFactory = getSerializerFactory();  
  24.         //交给HessianSkeleton invoke方法处理   
  25.         invoke(is, os, objectId, serializerFactory);  
  26.     } finally {  
  27.         ServiceContext.end();  
  28.     }  
  29. }  
	public void service(ServletRequest request, ServletResponse response)
			throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		//必须是post方式
		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");
		//保存到ThreadLocal中
		ServiceContext.begin(req, serviceId, objectId);
		try {
			InputStream is = request.getInputStream();
			OutputStream os = response.getOutputStream();
			response.setContentType("application/x-hessian");
			SerializerFactory serializerFactory = getSerializerFactory();
			//交给HessianSkeleton invoke方法处理
			invoke(is, os, objectId, serializerFactory);
		} finally {
			ServiceContext.end();
		}
	}

HessianSkeleton invoke方法核心代码 

  1.  public void invoke(Object service,  
  2.                     AbstractHessianInput in,  
  3.                     AbstractHessianOutput out)  
  4.    throws Exception  
  5.  {  
  6.    //..略   
  7. //反序列化 获得方法名称   
  8.    String methodName = in.readMethod();  
  9.    int argLength = in.readMethodArgLength();  
  10.   
  11.    Method method;  
  12.    //_methodMap中获得对应的方法    
  13.    method = getMethod(methodName + "__" + argLength);  
  14.    // ..略   
  15.    Class<?> []args = method.getParameterTypes();  
  16.    //获得方法参数   
  17.    Object []values = new Object[args.length];  
  18.    for (int i = 0; i < args.length; i++) {  
  19.      // XXX: needs Marshal object   
  20.      values[i] = in.readObject(args[i]);  
  21.    }  
  22.    Object result = null;  
  23.    try {  
  24.      result = method.invoke(service, values);  
  25.    } catch (Exception e) {  
  26.     //...略   
  27.      return;  
  28.    }  
  29.    in.completeCall();  
  30.    // AbstractHessianOutput 序列化方法返回值   
  31.    out.writeReply(result);  
  32.    out.close();  
  33.  }  
  public void invoke(Object service,
                     AbstractHessianInput in,
                     AbstractHessianOutput out)
    throws Exception
  {
    //..略
	//反序列化 获得方法名称
    String methodName = in.readMethod();
    int argLength = in.readMethodArgLength();

    Method method;
    //_methodMap中获得对应的方法 
    method = getMethod(methodName + "__" + argLength);
    // ..略
    Class<?> []args = method.getParameterTypes();
    //获得方法参数
    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) {
    	//...略
      return;
    }
    in.completeCall();
    // AbstractHessianOutput 序列化方法返回值
    out.writeReply(result);
    out.close();
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值