Spring和Hessian整合使用中的小修改

之前项目中需要分开部署,使用hessian(4.0.7)交互,而项目本身就是用Spring(3.2.5),已提供相关组件,因此使用起来很容易。如果是作为服务端,暴露服务,使用的是org.springframework.remoting.caucho.HessianServiceExporter,已提供有debug属性,方便开发时调试。但提供给客户端用于代理指定接口的org.springframework.remoting.caucho.HessianProxyFactoryBean并没有提供debug属性。HessianProxyFactoryBean继承自org.springframework.remoting.caucho.HessianClientInterceptor,所有对HessianClientInterceptor的调用均委托给HessianProxyFactory处理,HessianProxyFactory本身有debug属性,只需要重写HessianClientInterceptor,暴露出来即可。完整代码如下(只是新增了方法setConnectTimeout),

 

 

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.UndeclaredThrowableException;

import java.net.ConnectException;

import java.net.MalformedURLException;

 

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import org.springframework.remoting.RemoteAccessException;

import org.springframework.remoting.RemoteConnectFailureException;

import org.springframework.remoting.RemoteLookupFailureException;

import org.springframework.remoting.RemoteProxyFailureException;

import org.springframework.remoting.support.UrlBasedRemoteAccessor;

import org.springframework.util.Assert;

 

import com.caucho.hessian.HessianException;

import com.caucho.hessian.client.HessianConnectionException;

import com.caucho.hessian.client.HessianProxyFactory;

import com.caucho.hessian.client.HessianRuntimeException;

import com.caucho.hessian.io.SerializerFactory;

 

 

public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor {

 

private HessianProxyFactory proxyFactory = new HessianProxyFactory();

 

private Object hessianProxy;

 

/**

* Set the HessianProxyFactory instance to use. If not specified, a

* default HessianProxyFactory will be created.

* <p>

* Allows to use an externally configured factory instance, in particular

* a custom HessianProxyFactory subclass.

*/

public void setProxyFactory(HessianProxyFactory proxyFactory) {

this.proxyFactory = (proxyFactory != null ? proxyFactory : new HessianProxyFactory());

}

 

/**

* Specify the Hessian SerializerFactory to use.

* <p>

* This will typically be passed in as an inner bean definition of type

* {@code com.caucho.hessian.io.SerializerFactory}, with custom bean

* property values applied.

*/

public void setSerializerFactory(SerializerFactory serializerFactory) {

this.proxyFactory.setSerializerFactory(serializerFactory);

}

 

/**

* Set whether to send the Java collection type for each serialized

* collection. Default is "true".

*/

public void setSendCollectionType(boolean sendCollectionType) {

this.proxyFactory.getSerializerFactory().setSendCollectionType(sendCollectionType);

}

 

/**

* Set whether overloaded methods should be enabled for remote

* invocations. Default is "false".

* @see com.caucho.hessian.client.HessianProxyFactory#setOverloadEnabled

*/

public void setOverloadEnabled(boolean overloadEnabled) {

this.proxyFactory.setOverloadEnabled(overloadEnabled);

}

 

/**

* Set the username that this factory should use to access the remote

* service. Default is none.

* <p>

* The username will be sent by Hessian via HTTP Basic Authentication.

* @see com.caucho.hessian.client.HessianProxyFactory#setUser

*/

public void setUsername(String username) {

this.proxyFactory.setUser(username);

}

 

/**

* Set the password that this factory should use to access the remote

* service. Default is none.

* <p>

* The password will be sent by Hessian via HTTP Basic Authentication.

* @see com.caucho.hessian.client.HessianProxyFactory#setPassword

*/

public void setPassword(String password) {

this.proxyFactory.setPassword(password);

}

 

/**

* Set whether Hessian's debug mode should be enabled. Default is "false".

* @see com.caucho.hessian.client.HessianProxyFactory#setDebug

*/

public void setDebug(boolean debug) {

this.proxyFactory.setDebug(debug);

}

 

/**

* Set whether to use a chunked post for sending a Hessian request.

* @see com.caucho.hessian.client.HessianProxyFactory#setChunkedPost

*/

public void setChunkedPost(boolean chunkedPost) {

this.proxyFactory.setChunkedPost(chunkedPost);

}

 

/**

* Set the timeout to use when waiting for a reply from the Hessian

* service.

* @see com.caucho.hessian.client.HessianProxyFactory#setReadTimeout

*/

public void setReadTimeout(long timeout) {

this.proxyFactory.setReadTimeout(timeout);

}

 

/**

* Set whether version 2 of the Hessian protocol should be used for

* parsing requests and replies. Default is "false".

* @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request

*/

public void setHessian2(boolean hessian2) {

this.proxyFactory.setHessian2Request(hessian2);

this.proxyFactory.setHessian2Reply(hessian2);

}

 

/**

* Set whether version 2 of the Hessian protocol should be used for

* parsing requests. Default is "false".

* @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request

*/

public void setHessian2Request(boolean hessian2) {

this.proxyFactory.setHessian2Request(hessian2);

}

 

/**

* Set whether version 2 of the Hessian protocol should be used for

* parsing replies. Default is "false".

* @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Reply

*/

public void setHessian2Reply(boolean hessian2) {

this.proxyFactory.setHessian2Reply(hessian2);

}

 

@Override

public void afterPropertiesSet() {

super.afterPropertiesSet();

prepare();

}

 

/**

* Initialize the Hessian proxy for this interceptor.

* @throws RemoteLookupFailureException

*               if the service URL is invalid

*/

public void prepare() throws RemoteLookupFailureException {

try {

this.hessianProxy = createHessianProxy(this.proxyFactory);

}

catch (MalformedURLException ex) {

throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex);

}

}

 

/**

* Create the Hessian proxy that is wrapped by this interceptor.

* @param proxyFactory

*              the proxy factory to use

* @return the Hessian proxy

* @throws MalformedURLException

*               if thrown by the proxy factory

* @see com.caucho.hessian.client.HessianProxyFactory#create

*/

protected Object createHessianProxy(HessianProxyFactory proxyFactory) throws MalformedURLException {

Assert.notNull(getServiceInterface(), "'serviceInterface' is required");

return proxyFactory.create(getServiceInterface(), getServiceUrl());

}

 

@Override

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 {

return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments());

}

catch (InvocationTargetException ex) {

Throwable targetEx = ex.getTargetException();

// Hessian 4.0 check: another layer of

// InvocationTargetException.

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);

}

}

 

/**

* Convert the given Hessian access exception to an appropriate Spring

* RemoteAccessException.

* @param ex

*              the exception to convert

* @return the RemoteAccessException to throw

*/

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);

}

}

 

/**

* 连接超时配置

* @param timeout

*/

public void setConnectTimeout(long timeout) {

this.proxyFactory.setConnectTimeout(timeout);

}

 

 

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值