`

Hessian源码分析和Hack --让Hessian携带远程调用端的信息(上)

 
阅读更多

项目选定Hessian作为web service的实现方式,确实很轻量级,速度就跟直接用socket差不多,全是二进制传送节约了不少开销。但是在使用过程中有业务需要是必须获得远程端的ip地址,主机名等信息的。翻便Hessian的文档和google了n次未果,迫不得已到caucho和spring论坛去问,都没有得到答复。今天心一横把hessian的源代码加入到项目中单步跟踪,总算有点小收获。献丑分享出来,一方面给需要的朋友,主要还是希望各位找找是否存在bug,以及是否有更好的改良。 

一:先撇开Spring不谈,来看看纯Hessian的调用 
按照hessian文档里边介绍的demo,在web.xml里边如下配置 

Java代码  收藏代码
  1.  <servlet>  
  2.  <servlet-name>hello</servlet-name>  
  3.  <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>  
  4.   <init-param>  
  5.     <param-name>home-class</param-name>  
  6.     <param-value>example.BasicService</param-value>  
  7.   </init-param>  
  8.   <init-param>  
  9.     <param-name>home-api</param-name>  
  10.     <param-value>example.Basic</param-value>  
  11.   </init-param>  
  12. </servlet>  
  13.   
  14. <servlet-mapping>  
  15.   <url-pattern>/hello</url-pattern>  
  16.   <servlet-name>hello</servlet-name>  
  17. </servlet-mapping>  



由此可知Hessian调用的入口是HessianServlet这个Servlet,进去看看 

Java代码  收藏代码
  1. /** 
  2.  * Servlet for serving Hessian services. 
  3.  */  
  4. public class HessianServlet extends GenericServlet {  
  5.   private Class _homeAPI;  
  6.   private Object _homeImpl;  
  7.     
  8.   private Class _objectAPI;  
  9.   private Object _objectImpl;  
  10.     
  11.   private HessianSkeleton _homeSkeleton;  
  12.   private HessianSkeleton _objectSkeleton;  
  13.   
  14.   private SerializerFactory _serializerFactory;  
  15.   
  16.   public String getServletInfo()  
  17.   {  
  18.     return "Hessian Servlet";  
  19.   }  
  20.   
  21.   /** 
  22.    * Sets the home api. 
  23.    */  
  24.   public void setHomeAPI(Class api)  
  25.   {  
  26.     _homeAPI = api;  
  27.   }  
  28.   
  29.   /** 
  30.    * Sets the home implementation 
  31.    */  
  32.   public void setHome(Object home)  
  33.   {  
  34.     _homeImpl = home;  
  35.   }  
  36.   
  37.   /** 
  38.    * Sets the object api. 
  39.    */  
  40.   public void setObjectAPI(Class api)  
  41.   {  
  42.     _objectAPI = api;  
  43.   }  
  44.   
  45.   /** 
  46.    * Sets the object implementation 
  47.    */  
  48.   public void setObject(Object object)  
  49.   {  
  50.     _objectImpl = object;  
  51.   }  
  52.   
  53.   /** 
  54.    * Sets the service class. 
  55.    */  
  56.   public void setService(Object service)  
  57.   {  
  58.     setHome(service);  
  59.   }  
  60.   
  61.   /** 
  62.    * Sets the api-class. 
  63.    */  
  64.   public void setAPIClass(Class api)  
  65.   {  
  66.     setHomeAPI(api);  
  67.   }  
  68.   
  69.   /** 
  70.    * Gets the api-class. 
  71.    */  
  72.   public Class getAPIClass()  
  73.   {  
  74.     return _homeAPI;  
  75.   }  
  76.   
  77.   /** 
  78.    * Sets the serializer factory. 
  79.    */  
  80.   public void setSerializerFactory(SerializerFactory factory)  
  81.   {  
  82.     _serializerFactory = factory;  
  83.   }  
  84.   
  85.   /** 
  86.    * Gets the serializer factory. 
  87.    */  
  88.   public SerializerFactory getSerializerFactory()  
  89.   {  
  90.     if (_serializerFactory == null)  
  91.       _serializerFactory = new SerializerFactory();  
  92.   
  93.     return _serializerFactory;  
  94.   }  
  95.   
  96.   /** 
  97.    * Sets the serializer send collection java type. 
  98.    */  
  99.   public void setSendCollectionType(boolean sendType)  
  100.   {  
  101.     getSerializerFactory().setSendCollectionType(sendType);  
  102.   }  
  103.   
  104.   /** 
  105.    * Initialize the service, including the service object. 
  106.    */  
  107.   public void init(ServletConfig config)  
  108.     throws ServletException  
  109.   {  
  110.     super.init(config);  
  111.       
  112.     try {  
  113.       if (_homeImpl != null) {  
  114.       }  
  115.       else if (getInitParameter("home-class") != null) {  
  116.     String className = getInitParameter("home-class");  
  117.       
  118.     Class homeClass = loadClass(className);  
  119.   
  120.     _homeImpl = homeClass.newInstance();  
  121.   
  122.     init(_homeImpl);  
  123.       }  
  124.       else if (getInitParameter("service-class") != null) {  
  125.     String className = getInitParameter("service-class");  
  126.       
  127.     Class homeClass = loadClass(className);  
  128.   
  129.     _homeImpl = homeClass.newInstance();  
  130.       
  131.     init(_homeImpl);  
  132.       }  
  133.       else {  
  134.     if (getClass().equals(HessianServlet.class))  
  135.       throw new ServletException("server must extend HessianServlet");  
  136.   
  137.     _homeImpl = this;  
  138.       }  
  139.   
  140.       if (_homeAPI != null) {  
  141.       }  
  142.       else if (getInitParameter("home-api") != null) {  
  143.     String className = getInitParameter("home-api");  
  144.       
  145.     _homeAPI = loadClass(className);  
  146.       }  
  147.       else if (getInitParameter("api-class") != null) {  
  148.     String className = getInitParameter("api-class");  
  149.   
  150.     _homeAPI = loadClass(className);  
  151.       }  
  152.       else if (_homeImpl != null) {  
  153.     _homeAPI = findRemoteAPI(_homeImpl.getClass());  
  154.   
  155.     if (_homeAPI == null)  
  156.       _homeAPI = _homeImpl.getClass();  
  157.       }  
  158.         
  159.       if (_objectImpl != null) {  
  160.       }  
  161.       else if (getInitParameter("object-class") != null) {  
  162.     String className = getInitParameter("object-class");  
  163.       
  164.     Class objectClass = loadClass(className);  
  165.   
  166.     _objectImpl = objectClass.newInstance();  
  167.   
  168.     init(_objectImpl);  
  169.       }  
  170.   
  171.       if (_objectAPI != null) {  
  172.       }  
  173.       else if (getInitParameter("object-api") != null) {  
  174.     String className = getInitParameter("object-api");  
  175.       
  176.     _objectAPI = loadClass(className);  
  177.       }  
  178.       else if (_objectImpl != null)  
  179.     _objectAPI = _objectImpl.getClass();  
  180.   
  181.       _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);  
  182.       if (_objectAPI != null)  
  183.     _homeSkeleton.setObjectClass(_objectAPI);  
  184.   
  185.       if (_objectImpl != null) {  
  186.     _objectSkeleton = new HessianSkeleton(_objectImpl, _objectAPI);  
  187.     _objectSkeleton.setHomeClass(_homeAPI);  
  188.       }  
  189.       else  
  190.     _objectSkeleton = _homeSkeleton;  
  191.     } catch (ServletException e) {  
  192.       throw e;  
  193.     } catch (Exception e) {  
  194.       throw new ServletException(e);  
  195.     }  
  196.   }  
  197.   
  198.   private Class findRemoteAPI(Class implClass)  
  199.   {  
  200.     if (implClass == null || implClass.equals(GenericService.class))  
  201.       return null;  
  202.       
  203.     Class []interfaces = implClass.getInterfaces();  
  204.   
  205.     if (interfaces.length == 1)  
  206.       return interfaces[0];  
  207.   
  208.     return findRemoteAPI(implClass.getSuperclass());  
  209.   }  
  210.   
  211.   private Class loadClass(String className)  
  212.     throws ClassNotFoundException  
  213.   {  
  214.     ClassLoader loader = Thread.currentThread().getContextClassLoader();  
  215.   
  216.     if (loader != null)  
  217.       return Class.forName(className, false, loader);  
  218.     else  
  219.       return Class.forName(className);  
  220.   }  
  221.   
  222.   private void init(Object service)  
  223.     throws ServletException  
  224.   {  
  225.     if (service instanceof Service)  
  226.       ((Service) service).init(getServletConfig());  
  227.     else if (service instanceof Servlet)  
  228.       ((Servlet) service).init(getServletConfig());  
  229.   }  
  230.     
  231.   /** 
  232.    * Execute a request.  The path-info of the request selects the bean. 
  233.    * Once the bean's selected, it will be applied. 
  234.    */  
  235.   public void service(ServletRequest request, ServletResponse response)  
  236.     throws IOException, ServletException  
  237.   {  
  238.     HttpServletRequest req = (HttpServletRequest) request;  
  239.     HttpServletResponse res = (HttpServletResponse) response;  
  240.   
  241.     if (! req.getMethod().equals("POST")) {  
  242.       res.setStatus(500"Hessian Requires POST");  
  243.       PrintWriter out = res.getWriter();  
  244.   
  245.       res.setContentType("text/html");  
  246.       out.println("<h1>Hessian Requires POST</h1>");  
  247.         
  248.       return;  
  249.     }  
  250.   
  251.     String serviceId = req.getPathInfo();  
  252.     String objectId = req.getParameter("id");  
  253.     if (objectId == null)  
  254.       objectId = req.getParameter("ejbid");  
  255.   
  256.     ServiceContext.begin(req, serviceId, objectId);  
  257.   
  258.     try {  
  259.       InputStream is = request.getInputStream();  
  260.       OutputStream os = response.getOutputStream();  
  261.   
  262.       Hessian2Input in = new Hessian2Input(is);  
  263.       AbstractHessianOutput out;  
  264.   
  265.       SerializerFactory serializerFactory = getSerializerFactory();  
  266.         
  267.       in.setSerializerFactory(serializerFactory);  
  268.   
  269.       int code = in.read();  
  270.   
  271.       if (code != 'c') {  
  272.     // XXX: deflate  
  273.     throw new IOException("expected 'c' in hessian input at " + code);  
  274.       }  
  275.   
  276.       int major = in.read();  
  277.       int minor = in.read();  
  278.   
  279.       if (major >= 2)  
  280.     out = new Hessian2Output(os);  
  281.       else  
  282.     out = new HessianOutput(os);  
  283.         
  284.       out.setSerializerFactory(serializerFactory);  
  285.   
  286.       if (objectId != null)  
  287.     _objectSkeleton.invoke(in, out);  
  288.       else  
  289.     _homeSkeleton.invoke(in, out);  
  290.   
  291.       out.close();  
  292.     } catch (RuntimeException e) {  
  293.       throw e;  
  294.     } catch (ServletException e) {  
  295.       throw e;  
  296.     } catch (Throwable e) {  
  297.       throw new ServletException(e);  
  298.     } finally {  
  299.       ServiceContext.end();  
  300.     }  
  301.   }  
  302. }  



先看init()函数,功能还是一样,初始话一些东西,读入init-param的内容,并且load这些init-param的class 

主要的还是service()函数 
在service函数里边会获得request和response对象的输入和输出流,用来构造Hessian2Input和Hessian2Output,Hessian就是解析这两个东西来执行函数调用的。当然,在service里边还有一个重要的语句 

Java代码  收藏代码
  1. ServiceContext.begin(req, serviceId, objectId);  


这个函数有点奇怪,我每次到这里serviceId和objectId都是空,不知道是不是历史遗留问题还存在这两个参数。 
进去这个类看看 

Java代码  收藏代码
  1. public class ServiceContext {  
  2.   private static final ThreadLocal _localContext = new ThreadLocal();  
  3.   
  4.   private ServletRequest _request;  
  5.   private String _serviceName;  
  6.   private String _objectId;  
  7.   private int _count;  
  8.   private HashMap _headers = new HashMap();  
  9.   
  10.   private ServiceContext()  
  11.   {  
  12.   }  
  13.     
  14.   /** 
  15.    * Sets the request object prior to calling the service's method. 
  16.    * 
  17.    * @param request the calling servlet request 
  18.    * @param serviceId the service identifier 
  19.    * @param objectId the object identifier 
  20.    */  
  21.   public static void begin(ServletRequest request,  
  22.                String serviceName,  
  23.                String objectId)  
  24.     throws ServletException  
  25.   {  
  26.     ServiceContext context = (ServiceContext) _localContext.get();  
  27.   
  28.     if (context == null) {  
  29.       context = new ServiceContext();  
  30.       _localContext.set(context);  
  31.     }  
  32.   
  33.     context._request = request;  
  34.     context._serviceName = serviceName;  
  35.     context._objectId = objectId;  
  36.     context._count++;  
  37.   }  
  38.   
  39.   /** 
  40.    * Returns the service request. 
  41.    */  
  42.   public static ServiceContext getContext()  
  43.   {  
  44.     return (ServiceContext) _localContext.get();  
  45.   }  
  46.   
  47.   /** 
  48.    * Adds a header. 
  49.    */  
  50.   public void addHeader(String header, Object value)  
  51.   {  
  52.     _headers.put(header, value);  
  53.   }  
  54.   
  55.   /** 
  56.    * Gets a header. 
  57.    */  
  58.   public Object getHeader(String header)  
  59.   {  
  60.     return _headers.get(header);  
  61.   }  
  62.   
  63.   /** 
  64.    * Gets a header from the context. 
  65.    */  
  66.   public static Object getContextHeader(String header)  
  67.   {  
  68.     ServiceContext context = (ServiceContext) _localContext.get();  
  69.   
  70.     if (context != null)  
  71.       return context.getHeader(header);  
  72.     else  
  73.       return null;  
  74.   }  
  75.   
  76.   /** 
  77.    * Returns the service request. 
  78.    */  
  79.   public static ServletRequest getContextRequest()  
  80.   {  
  81.     ServiceContext context = (ServiceContext) _localContext.get();  
  82.   
  83.     if (context != null)  
  84.       return context._request;  
  85.     else  
  86.       return null;  
  87.   }  
  88.   
  89.   /** 
  90.    * Returns the service id, corresponding to the pathInfo of the URL. 
  91.    */  
  92.   public static String getContextServiceName()  
  93.   {  
  94.     ServiceContext context = (ServiceContext) _localContext.get();  
  95.   
  96.     if (context != null)  
  97.       return context._serviceName;  
  98.     else  
  99.       return null;  
  100.   }  
  101.   
  102.   /** 
  103.    * Returns the object id, corresponding to the ?id= of the URL. 
  104.    */  
  105.   public static String getContextObjectId()  
  106.   {  
  107.     ServiceContext context = (ServiceContext) _localContext.get();  
  108.   
  109.     if (context != null)  
  110.       return context._objectId;  
  111.     else  
  112.       return null;  
  113.   }  
  114.   
  115.   /** 
  116.    * Cleanup at the end of a request. 
  117.    */  
  118.   public static void end()  
  119.   {  
  120.     ServiceContext context = (ServiceContext) _localContext.get();  
  121.   
  122.     if (context != null && --context._count == 0) {  
  123.       context._request = null;  
  124.   
  125.       context._headers.clear();  
  126.     }  
  127.   }  
  128.   
  129.   /** 
  130.    * Returns the service request. 
  131.    * 
  132.    * @deprecated 
  133.    */  
  134.   public static ServletRequest getRequest()  
  135.   {  
  136.     ServiceContext context = (ServiceContext) _localContext.get();  
  137.   
  138.     if (context != null)  
  139.       return context._request;  
  140.     else  
  141.       return null;  
  142.   }  
  143.   
  144.   /** 
  145.    * Returns the service id, corresponding to the pathInfo of the URL. 
  146.    * 
  147.    * @deprecated 
  148.    */  
  149.   public static String getServiceName()  
  150.   {  
  151.     ServiceContext context = (ServiceContext) _localContext.get();  
  152.   
  153.     if (context != null)  
  154.       return context._serviceName;  
  155.     else  
  156.       return null;  
  157.   }  
  158.   
  159.   /** 
  160.    * Returns the object id, corresponding to the ?id= of the URL. 
  161.    * 
  162.    * @deprecated 
  163.    */  
  164.   public static String getObjectId()  
  165.   {  
  166.     ServiceContext context = (ServiceContext) _localContext.get();  
  167.   
  168.     if (context != null)  
  169.       return context._objectId;  
  170.     else  
  171.       return null;  
  172.   }  
  173. }  



原来ServiceContext 是用来保存当前调用线程的上下文的,比如request对象等(不知道这个解释对不对)。有了这个东西就太好了,因为里边有request,就有了调用端的一切信息,呵呵。 

继续回来看那个Servlet,到了真正调用的时候了,也就是这段代码 

Java代码  收藏代码
  1. if (objectId != null)  
  2. ctSkeleton.invoke(in, out);  
  3. else  
  4. Skeleton.invoke(in, out);  



跟踪invoke方法看看真面目 

Java代码  收藏代码
  1. public void invoke(AbstractHessianInput in, AbstractHessianOutput out)  
  2.   throws Throwable  
  3. {  
  4.   ServiceContext context = ServiceContext.getContext();  
  5.     
  6.   String header;  
  7.   while ((header = in.readHeader()) != null) {  
  8.     Object value = in.readObject();  
  9.   
  10.     context.addHeader(header, value);  
  11.   }  
  12.   String ip = context.getContextRequest().getRemoteAddr();  
  13.   String methodName = in.readMethod();  
  14.   Method method = getMethod(methodName);  
  15.   
  16.   if (method != null) {  
  17.   }  
  18.   else if ("_hessian_getAttribute".equals(methodName)) {  
  19.     String attrName = in.readString();  
  20.     in.completeCall();  
  21.   
  22.     String value = null;  
  23.   
  24.     if ("java.api.class".equals(attrName))  
  25. alue = getAPIClassName();  
  26.     else if ("java.home.class".equals(attrName))  
  27. alue = getHomeClassName();  
  28.     else if ("java.object.class".equals(attrName))  
  29. alue = getObjectClassName();  
  30.   
  31.     out.startReply();  
  32.   
  33.     out.writeObject(value);  
  34.   
  35.     out.completeReply();  
  36.     return;  
  37.   }  
  38.   else if (method == null) {  
  39.     out.startReply();  
  40.     out.writeFault("NoSuchMethodException",  
  41.      "The service has no method named: " + in.getMethod(),  
  42.      null);  
  43.     out.completeReply();  
  44.     return;  
  45.   }  
  46.   
  47.   Class []args = method.getParameterTypes();  
  48.   Object []values = new Object[args.length];  
  49.     
  50.   //args[0]  
  51.   
  52.   for (int i = 0; i < args.length; i++){  
  53.     if(i == args.length-1){  
  54.         values[i] = in.readObject(args[i], ip);  
  55.     }else{  
  56.         values[i] = in.readObject(args[i]);  
  57.     }  
  58.       
  59.   }  
  60.       
  61.   
  62.   in.completeCall();  
  63.   
  64.   Object result = null;  
  65.     
  66.   try {  
  67.     result = method.invoke(_service, values);  
  68.   } catch (Throwable e) {  
  69.     if (e instanceof InvocationTargetException)  
  70.       e = ((InvocationTargetException) e).getTargetException();  
  71.   
  72.     log.log(Level.WARNING, e.toString(), e);  
  73.       
  74.     out.startReply();  
  75.     out.writeFault("ServiceException", e.getMessage(), e);  
  76.     out.completeReply();  
  77.     return;  
  78.   }  
  79.   
  80.   out.startReply();  
  81.   
  82.   out.writeObject(result);  
  83.     
  84.   out.completeReply();  
  85. }  



就是在这个方法里边,hessian把包装过的输入输出流当作参数传入并进行解析的,看看这个函数的第一句,正是取得ServiceContext的地方,此时应该就是把刚才Servlet里边保存的上下文取出来使用。 
这个时候出现了第一个hack的地方

Java代码  收藏代码
  1. String ip = context.getContextRequest().getRemoteAddr();  

在此处我取得远程的ip地址保存起来。然后在第二个hack的地方 

Java代码  收藏代码
  1. Class []args = method.getParameterTypes();  
  2. Object []values = new Object[args.length];  
  3.   
  4. //args[0]  
  5.   
  6. for (int i = 0; i < args.length; i++){  
  7.     if(i == args.length-1){  
  8.         values[i] = in.readObject(args[i], ip);  
  9.     }else{  
  10.         values[i] = in.readObject(args[i]);  
  11.     }  
  12.       
  13. }  


我用这个ip地址取代最后一个参数(web服务函数的参数,即远程端调用的函数的参数)。 
第三个hack的地方就是 in.readObject(args[i], ip); 这个方法。 这个方法是我自己加的,原本只有 
in.readObject(args[i]); 这个方法。 这个方法就是hessian读取参数值的地方 
进去看看 

Java代码  收藏代码
  1. /** 
  2.  * Reads an object from the input stream with an expected type. 
  3.  */  
  4. public Object readObject(Class cl, String ip)  
  5.   throws IOException  
  6. {  
  7.   if (cl == null || cl == Object.class)  
  8.     return readObject();  
  9.     
  10.   int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();  
  11.   
  12.   switch (tag) {  
  13.   case 'N':  
  14.     return null;  
  15.   
  16.   case 'M':  
  17.   {  
  18.     String type = readType();  
  19.     Deserializer reader;  
  20.     reader = findSerializerFactory().getObjectDeserializer(type);  
  21.   
  22.     if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))  
  23.       return reader.readMap(this);  
  24.   
  25.     reader = findSerializerFactory().getDeserializer(cl);  
  26.   
  27.     return reader.readMap(this);  
  28.   }  
  29.   
  30.   case 'O':  
  31.   {  
  32.     return readObjectDefinition(cl);  
  33.   }  
  34.   
  35.   case 'o':  
  36.   {  
  37.     int ref = readInt();  
  38.   
  39.     ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref - 1);  
  40.   
  41.     return readObjectInstance(cl, def);  
  42.   }  
  43.   
  44.   case 'V':  
  45.   {  
  46.     String type = readType();  
  47.     int length = readLength();  
  48.       
  49.     Deserializer reader;  
  50.     reader = findSerializerFactory().getObjectDeserializer(type);  
  51.       
  52.     if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))  
  53.       return reader.readList(this, length);  
  54.   
  55.     reader = findSerializerFactory().getDeserializer(cl);  
  56.   
  57.     Object v = reader.readList(this, length);  
  58.   
  59.     return v;  
  60.   }  
  61.   
  62.   case 'v':  
  63.   {  
  64.     int ref = readInt();  
  65.     String type = (String) _types.get(ref);  
  66.     int length = readInt();  
  67.       
  68.     Deserializer reader;  
  69.     reader = findSerializerFactory().getObjectDeserializer(type);  
  70.       
  71.     if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))  
  72.       return reader.readLengthList(this, length);  
  73.   
  74.     reader = findSerializerFactory().getDeserializer(cl);  
  75.   
  76.     Object v = reader.readLengthList(this, length);  
  77.   
  78.     return v;  
  79.   }  
  80.   
  81.   case 'R':  
  82.   {  
  83.     int ref = parseInt();  
  84.   
  85.     return _refs.get(ref);  
  86.   }  
  87.   
  88.   case 'r':  
  89.   {  
  90.     String type = readType();  
  91.     String url = readString();  
  92.   
  93.     return resolveRemote(type, url);  
  94.   }  
  95.   }  
  96.   
  97.   if (tag >= 0)  
  98.     _offset--;  
  99.   
  100.   Object value = findSerializerFactory().getDeserializer(cl).readObject(this);  
  101.   
  102.   if(value instanceof String){  
  103.     value = ip;  
  104.   }  
  105.   return value;  
  106. }  


我重载了这个方法,加入了一个String类型的参数,用来把ip地址传进去,并且最后返回这个值。到了这里,hack的原理大家应该知道了--就是强行修改远程调用端的调用函数里边的最后一个参数的值(规定为String类型),把这个值设为我想要的信息,那么服务端的服务函数就会获得这个值,并且进行后续处理。 
剩下的步骤就原封不动的是hessian来处理了,没有需要干涉的地方,你也就能在你的服务端service函数里边获得这个你想要的信息了。 

这就是Hessian的一个普通流程,不知道分析和Hack的对不对,我在这里是调试成功了,但是还没彻底测试有没有其它bug。 至于跟Spring的结合,待会儿跟帖来说。

 

转载自:http://www.iteye.com/topic/108611

分享到:
评论

相关推荐

    hessian-lite-3.2.1-fixed-2.jar

    com.alibaba:hessian-lite:jar:3.2.1-fixed-2 hessian-lite hessian-lite-3.2.1-fixed-2.jar

    Hessian源码分析和Hack.doc

    《Hessian源码分析与Hack:携带远程调用端信息》 Hessian作为一种轻量级的RPC(远程过程调用)框架,因其高效、简洁的二进制协议,被广泛应用于构建Web服务。然而,在实际应用中,有时我们需要获取到远程调用端的IP...

    hessian-4.0.63-API文档-中英对照版.zip

    赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.caucho:hessian:4.0.63; 标签:hessian、caucho、jar包、java、...

    java+hessian 远程调用

    - **配置详解**:文档通常会包含如何配置Hessian服务端和客户端的详细步骤,例如设置服务器端的监听端口,客户端的连接参数等。 - **示例代码**:提供服务端和服务端的代码示例,展示如何创建、注册服务以及如何...

    hessian-4.0.63-API文档-中文版.zip

    赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.caucho:hessian:4.0.63; 标签:hessian、caucho、jar包、java、中文文档;...

    Hessian多个版本打包下载

    Hessian是一种高效的二进制序列化协议,常用于远程过程调用(RPC)和服务之间的通信。这个压缩包包含了Hessian的多个版本,分别是Hessian3.1.6、Hessian3.2.1以及Hessian4.0.7。每个版本都有其特定的功能改进和优化...

    hessian-4.0.51-src

    在解压的"**hessian-4.0.51-src**"源码包中,主要包含两个关键文件:"**pom.xml**"和"**src**"。 1. **pom.xml**:这是Maven项目的配置文件,定义了项目依赖、构建过程等信息。通过这个文件,我们可以看到Hessian ...

    hessian-3.3.6-API文档-中英对照版.zip

    赠送jar包:hessian-3.3.6.jar 赠送原API文档:hessian-3.3.6-javadoc.jar 赠送源代码:hessian-3.3.6-sources.jar 包含翻译后的API文档:hessian-3.3.6-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven...

    hessian实现远程调用

    在IT行业中,远程调用是一种常见的技术,使得客户端可以跨网络调用远程服务器上的方法,就像调用本地方法一样方便。Hessian是Apache项目下的一个轻量级的RPC(Remote Procedure Call,远程过程调用)框架,它提供了...

    hessian-3.3.6-API文档-中文版.zip

    赠送Maven依赖信息文件:hessian-3.3.6.pom; 包含翻译后的API文档:hessian-3.3.6-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.alipay.sofa:hessian:3.3.6; 标签:sofa、hessian、alipay、jar包、java、...

    Hessian远程调用框架学习一

    Hessian远程调用框架是基于Java的轻量级RPC(Remote Procedure Call)解决方案,它允许开发者在分布式系统中实现高效、便捷的跨网络对象方法调用。本教程将引导你入门Hessian,通过一个简单的JAVA demo来理解其工作...

    hessian-3.0.20-src.jar

    hessian是一个轻量级的Java Remoting方案

    Hessian-4.0.7(Jar包 + 源码)

    Hessian是一种轻量级的二进制Web服务协议,它由Caucho Technology开发,用于提高远程调用的效率和速度。Hessian 4.0.7是该协议的一个版本,提供了一个Java库,允许开发者在Java应用之间进行高效的数据交换。这个版本...

    hessian-4.0.33.jar

    《深入理解Hessian框架:以hessian-4.0.33.jar为例》 Hessian是一种高效的二进制RPC(Remote Procedure Call)协议,由Caucho Technology开发,旨在提供轻量级、高效的远程调用服务。在这个专题中,我们将以hessian...

    轻量级远程服务调用Hessian的入门实例和与Spring整合的实例.zip

    在服务器端,通过HessianServlet来暴露这个服务,客户端则通过HessianProxyFactory来创建服务代理,从而能够调用远程服务的方法。这种简单设置可以让开发者快速理解Hessian的基本工作原理。 二、Hessian与Spring...

    hessian-lite-3.2.1-fixed-2-sources.jar

    java运行依赖jar包

    spring整合hessian进行远程通讯

    Spring会自动创建代理对象,使得客户端可以通过这个代理对象调用远程服务的方法,就像调用本地对象一样。 3. **使用源码分析**: Hessian库提供了`HessianProxyFactoryBean`和`HessianServiceExporter`这两个关键...

    hessian-lite

    1. **远程调用**:在Dubbo框架中,Hessian-lite用于实现服务调用的二进制序列化和反序列化,使得远程方法调用(RMI)更加高效。它将Java对象转换为二进制流,通过网络发送,然后在服务端反序列化回原来的对象,降低了...

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

    Hessian二进制Web服务协议(Hessian Binary Web Service Protocol)是一种高效的、轻量级的远程过程调用(RPC)协议,它主要用于提高Web服务之间的通信效率。Hessian由Caucho Technology公司开发,旨在解决XML-RPC在...

Global site tag (gtag.js) - Google Analytics