怎么调用hessian接口 spring

 我来答
就烦条0o
2016-07-22 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
1.Spring中除了提供HTTP调用器方式的远程调用,还对第三方的远程调用实现提供了支持,其中提供了对Hessian的支持。

Hessian是由Caocho公司发布的一个轻量级的二进制协议远程调用实现方案,Hessian也是基于HTTP协议的,其工作原理如下:

(1).客户端:

a.发送远程调用请求:

客户端程序—>发送远程调用请求—>Hessian客户端拦截器—>封装远程调用请求—>Hessian代理—>通过HTTP协议发送远程请求代理到服务端。

b.接收远程调用响应:

远程调用结果—>HTTP响应—>客户端。

(1).服务端:

a.接收远程调用请求:

远程调用HTTP请求—>HessianServiceExporter接收请求—>HessianExporter将远程调用对象封装为HessianSkeleton框架—> HessianSkeleton处理远程调用请求。

b.返回远程调用响应:

HessianSkeleton封装远程调用处理结果—>HTTP响应—>客户端。

本文章通过分析Spring对Hessian支持的相关源码,了解Spring对Hessian支持的具体实现。

2.Hessian的客户端配置:

Hessian的客户端需要做类似如下的配置:

[xhtml] view plaincopy

<bean id=”hessianProxy” class=”org.springframework.remoting.caucho.HessianProxyFactoryBean”>
<property name=”serviceUrl”>
<value>http://hostAddress:8080/serviceUrl</value>
</property>
<property name=”serviceInterface”>
<value>远程调用服务接口</value>
]</property>
</bean>

和HTTP调用器的配置类似,都需要配置远程调用请求的url,这个url要和服务端的url一致,Spring通过DispatcherServlet找到服务端对于的请求url。

HessianProxyFactoryBean是Spring中管理Hessian客户端的IoC容器,主要负责产生服务端远程调用代理和对客户端远程调用的拦截器设置。

3.HessianProxyFactoryBean:

HessianProxyFactoryBean生成远程调用代理和客户端远程调用拦截器设置,其源码如下:

[java] view plaincopy

public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean<Object> {
//远程调用代理对象
private Object serviceProxy;
//Spring IoC容器依赖注入完成后的回调方法
public void afterPropertiesSet() {
//首先调用父类HessianClientInterceptor的回调方法
super.afterPropertiesSet();
//创建远程调用代理对象并设置拦截器,注意这个this参数,因为//HessianProxyFactoryBean继承HessianClientInterceptor,因此其本身也
//是Hassien客户端拦截器
this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
}
//Spring IoC容器的接口FactoryBean产生对象的方法,客户端通过该方法获取被管
//理的远程调用代理
public Object getObject() {
return this.serviceProxy;
}
//获取对象的类型
public Class<?> getObjectType() {
return getServiceInterface();
}
//对象是否是单态类型,Spring默认管理的对象都是单态模式
public boolean isSingleton() {
return true;
}
}

HessianProxyFactoryBean最核心的功能就是在IoC容器回调方法中产生远程调用代理对象,在产生远程调用代理对象时,将代理对象的拦截器设置为其父类HessianClientInterceptor。

4.HessianClientInterceptor拦截客户端的远程调用请求:

HessianClientInterceptor对客户端的远程调用进行拦截,为客户端的远程调用创建Hessian代理,通过Hessian代理调用服务端远程调用对象,其源码如下:

[java] view plaincopy

public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor {
//创建Hessiann代理工厂
private HessianProxyFactory proxyFactory = new HessianProxyFactory();
//Hessian代理
private Object hessianProxy;
//设置Hessian代理工厂
public void setProxyFactory(HessianProxyFactory proxyFactory) {
this.proxyFactory = (proxyFactory != null ? proxyFactory : new HessianProxyFactory());
}
//设置Hessian序列化工厂
public void setSerializerFactory(SerializerFactory serializerFactory) {
this.proxyFactory.setSerializerFactory(serializerFactory);
}
//设置Hessian是否发送java集合类型对象
public void setSendCollectionType(boolean sendCollectionType) {
this.proxyFactory.getSerializerFactory().setSendCollectionType(sendCollectionType);
}
//设置远程调用时是否重载方法
public void setOverloadEnabled(boolean overloadEnabled) {
this.proxyFactory.setOverloadEnabled(overloadEnabled);
}
//设置远程调用用户名
public void setUsername(String username) {
this.proxyFactory.setUser(username);
}
//设置远程调用密码
public void setPassword(String password) {
this.proxyFactory.setPassword(password);
}
//设置是否使用Hessian的Debug调试模式
public void setDebug(boolean debug) {
this.proxyFactory.setDebug(debug);
}
//设置是否使用chunked端口发送Hessian请求
public void setChunkedPost(boolean chunkedPost) {
this.proxyFactory.setChunkedPost(chunkedPost);
}
//设置Hessian等待响应的超时时长
public void setReadTimeout(long timeout) {
this.proxyFactory.setReadTimeout(timeout);
}
//设置是否使用Hessain版本2协议解析请求和响应
public void setHessian2(boolean hessian2) {
this.proxyFactory.setHessian2Request(hessian2);
this.proxyFactory.setHessian2Reply(hessian2);
}
//设置是否使用Hessian版本2协议解析请求
public void setHessian2Request(boolean hessian2) {
this.proxyFactory.setHessian2Request(hessian2);
}
//设置是否使用Hessian版本2协议解析响应
public void setHessian2Reply(boolean hessian2) {
this.proxyFactory.setHessian2Reply(hessian2);
}
//子类HessianProxyFactoryBean的回调方法调用此回调方法
public void afterPropertiesSet() {
//调用其父类UrlBasedRemoteAccessor的回调方法获取客户端配置的请求url
super.afterPropertiesSet();
//初始化Hessian代理
prepare();
}
//初始化Hessian代理
public void prepare() throws RemoteLookupFailureException {
try {
//创建Hessian代理
this.hessianProxy = createHessianProxy(this.proxyFactory);
}
catch (MalformedURLException ex) {
throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex);
}
}
//创建Hessian代理
protected Object createHessianProxy(HessianProxyFactory proxyFactory) throws MalformedURLException {
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提供的。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式