目前完成的一个项目中,两个应用之间通讯使用了spring的Hessian remote方法,在remote 接口中有一个方法的调用老是抛出异常:
com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d
at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2714)
at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2695)
at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1322)
at com.caucho.hessian.io.Hessian2Input.readMethod(Hessian2Input.java:267)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:138)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:110)
at org.springframework.remoting.caucho.Hessian2SkeletonInvoker.invoke(Hessian2SkeletonInvoker.java:86)
at org.springframework.remoting.caucho.HessianExporter.invoke(HessianExporter.java:142)
at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:70)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:143)
at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
这个方法在本地调用没有问题,远程调用就是老是出现上面的错误。最后发现,Hessian是不支持方法之间的overload的。
比如你希望暴露的远程接口中有这样两个方法:
1、public List<Video> getVideo(int videoBlockId, int page, int size);
2、public List<Video> getVideo(int videoBlockId);
在本地调用完全没有问题,因为jvm可以根据调用参数来区分方法。但是使用Hessian在远程调用第二个方法就会出错,因为据我观察Hessian只识别了第一个方法,而第二个方法不能识别,总是报错,要你传入后面2个参数。所以最终解决办法就是给方法重新命名。