随笔-4  评论-0  文章-0  trackbacks-0

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

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

 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>
18
19

 

由此可知Hessian调用的入口是[color=red]HessianServlet[/color]这个Servlet,进去看看

 

  1/**
  2 * Servlet for serving Hessian services.
  3 */

  4public 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"