ption { Assert.notNull(getServiceInterface(), "'serviceInterface' is required"); //使用Hessian代理工厂创建Hessian代理 return proxyFactory.create(getServiceInterface(), getServiceUrl()); } //拦截器客户端请求的方法 public Object invoke(MethodInvocation invocation) throws Throwable { if (this.hessianProxy == null) { throw new IllegalStateException("HessianClientInterceptor is not properly initialized - " + "invoke 'prepare' before attempting any operations"); } //获取当前环境中线程类加载器 ClassLoader originalClassLoader = overrideThreadContextClassLoader(); try { //调用Hessian代理的方法,是Hessian远程调用的入口方法,使用JDK反射机制 return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments()); } //处理Hessian远程调用中的异常 catch (InvocationTargetException ex) { Throwable targetEx = ex.getTargetException(); if (targetEx instanceof InvocationTargetException) { targetEx = ((InvocationTargetException) targetEx).getTargetException(); } if (targetEx instanceof HessianConnectionException) { throw convertHessianAccessException(targetEx); } else if (targetEx instanceof HessianException || targetEx instanceof HessianRuntimeException) { Throwable cause = targetEx.getCause(); throw convertHessianAccessException(cause != null cause : targetEx); } else if (targetEx instanceof UndeclaredThrowableException) { UndeclaredThrowableException utex = (UndeclaredThrowableException) targetEx; throw convertHessianAccessException(utex.getUndeclaredThrowable()); } else { throw targetEx; } } catch (Throwable ex) { throw new RemoteProxyFailureException( "Failed to invoke Hessian proxy for remote service [" + getServiceUrl() + "]", ex); } //重置类加载器 finally { resetThreadContextClassLoader(originalClassLoader); } } //将Hessian异常转换为Spring远程调用异常 protected RemoteAccessException convertHessianAccessException(Throwable ex) { if (ex instanceof HessianConnectionException || ex instanceof ConnectException) { return new RemoteConnectFailureException( "Cannot connect to Hessian remote service at [" + getServiceUrl() + "]", ex); } else { return new RemoteAccessException( "Cannot access Hessian remote service at [" + getServiceUrl() + "]", ex); } }}
通过上面对HessianClientInterceptor的源码分析,我们可以看到Hessian客户端拦截器提供的最重要的方法是对远程调用拦截的方法invoke,在该方法中使用JDK的反射机制调用Hessian代理对象的指定方法。而Hessian代理是由Hessain代理器工厂HessianProxyFactory产生的,这个Hessian代理器工厂是有Hessian提供的。
5.Hessian服务器端配置:
在Hessian的服务端需要进行类似如下的配置:
[xhtml] view plaincopyprint
[
]
远程服务接口
Spring的HessianServiceExporter把远程调用服务整合到Spring MVC框架中,通过DispatcherServlet将客户端请求转发到服务器端相应的请求url远程对象上。
注意:serviceUrl要和客户端serviceUrl中配置的相同,service即是服务端提供服务的远程对象。
6.HessianServiceExporter处理Hessian远程调用请求:
HessianServiceExporter接收客户端的远程调用请求,并调用HessianExporter具体处理远程调用,并且远程调用结果封装到HTTP响应中返回,源码如下:
[java] view plaincopyprint public class HessianServiceExporter extends HessianExporter implements HttpRequestHandler { //处理Hessian请求,并将处理结果封装为Hessian响应返回 public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Hessian只支持HTTP的POST方法 if (!"POST".equals(request.getMethod())) { throw new HttpRequestMethodNotSupportedException(request.getMethod(), new St