1、 Hessian源码分析和Hack --让Hessian携带远程调用端的信息 项目选定Hessian作为web service的实现方式,确实很轻量级,速度就跟直接用socket差不多,全是二进制传送节约了不少开销。但是在使用过程中有业务需要是必须获得远程端的ip地址,主机名等信息的。翻便Hessian的文档和google了n次未果,迫不得已到caucho和spring论坛去问,都没有得到答复。今天心一横把hessian的源代码加入到项目中单步跟踪,总算有点小收获。献丑分享出来,一方面给需要的朋友,主要还是希望各位找找是否存在bug,以及是否有更好的改良。 一:先撇开Spring
2、不谈,来看看纯Hessian的调用
按照hessian文档里边介绍的demo,在web.xml里边如下配置
Java代码
1.
3、mple.BasicService
7.
8.
4、16.
5、
6、 由此可知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;
7、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 Ser
8、vlet"; 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)
9、 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. */
10、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. /** 6
11、2. * 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
12、 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 Ser
13、ializerFactory 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.
14、 */ 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(Servl
15、etConfig 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 = getInitParam
16、eter("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
17、 = 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.cla
18、ss)) 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
19、 = 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
20、 } 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. }
21、 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(_object
22、Impl); 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. }
23、 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 (_
24、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
25、 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;
26、 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 classN
27、ame) 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
28、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.
29、 ((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, Servle
30、tResponse response) 236. throws IOException, ServletException 237. { 238. HttpServletRequest req = (HttpServletRequest) request; 239. HttpServletResponse res = (HttpServletResponse) response; 240. 241. if (! req.getMethod().equals("POST")) { 242. r
31、es.setStatus(500, "Hessian Requires POST"); 243. PrintWriter out = res.getWriter(); 244. 245. res.setContentType("text/html"); 246. out.println("
32、iceId = 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 =
33、request.getInputStream(); 260. OutputStream os = response.getOutputStream(); 261. 262. Hessian2Input in = new Hessian2Input(is); 263. AbstractHessianOutput out; 264. 265. SerializerFactory serializerFactory = getSerializerFactory(); 266.
34、 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 m
35、ajor = 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.
36、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
37、 e; 296. } catch (Throwable e) { 297. throw new ServletException(e); 298. } finally { 299. ServiceContext.end(); 300. } 301. } 302. } /** * Servlet for serving Hessian services. */ public class HessianServlet extends GenericServlet { p
38、rivate Class _homeAPI; private Object _homeImpl; private Class _objectAPI; private Object _objectImpl; private HessianSkeleton _homeSkeleton; private HessianSkeleton _objectSkeleton; private SerializerFactory _serializerFactory; public String getServletInfo() {
39、 return "Hessian Servlet"; } /** * Sets the home api. */ public void setHomeAPI(Class api) { _homeAPI = api; } /** * Sets the home implementation */ public void setHome(Object home) { _homeImpl = home; } /** * Sets the object api.
40、 */ public void setObjectAPI(Class api) { _objectAPI = api; } /** * Sets the object implementation */ public void setObject(Object object) { _objectImpl = object; } /** * Sets the service class. */ public void setService(Object service) {
41、 setHome(service); } /** * Sets the api-class. */ public void setAPIClass(Class api) { setHomeAPI(api); } /** * Gets the api-class. */ public Class getAPIClass() { return _homeAPI; } /** * Sets the serializer factory. */ p
42、ublic void setSerializerFactory(SerializerFactory factory) { _serializerFactory = factory; } /** * Gets the serializer factory. */ public SerializerFactory getSerializerFactory() { if (_serializerFactory == null) _serializerFactory = new SerializerFactory();
43、 return _serializerFactory; } /** * Sets the serializer send collection java type. */ public void setSendCollectionType(boolean sendType) { getSerializerFactory().setSendCollectionType(sendType); } /** * Initialize the service, including the service obje
44、ct. */ public void init(ServletConfig config) throws ServletException { super.init(config); try { if (_homeImpl != null) { } else if (getInitParameter("home-class") != null) { String className = getInitParameter("home-class"); Class homeClas
45、s = 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();
46、 init(_homeImpl); } else { if (getClass().equals(HessianServlet.class)) throw new ServletException("server must extend HessianServlet"); _homeImpl = this; } if (_homeAPI != null) { } else if (getInitParameter("home-api") != null) { String c
47、lassName = 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 = findRem
48、oteAPI(_homeImpl.getClass()); if (_homeAPI == null) _homeAPI = _homeImpl.getClass(); } if (_objectImpl != null) { } else if (getInitParameter("object-class") != null) { String className = getInitParameter("object-class"); Class objectClass = loadCla
49、ss(className); _objectImpl = objectClass.newInstance(); init(_objectImpl); } if (_objectAPI != null) { } else if (getInitParameter("object-api") != null) { String className = getInitParameter("object-api"); _objectAPI = loadClass(className); }
50、 else if (_objectImpl != null) _objectAPI = _objectImpl.getClass(); _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI); if (_objectAPI != null) _homeSkeleton.setObjectClass(_objectAPI); if (_objectImpl != null) { _objectSkeleton = new HessianSkeleton(_objectImp






