首页 > 编程语言 > 详细

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

时间:2014-11-09 02:05:59      阅读:3643      评论:0      收藏:0      [点我收藏+]

之前项目中需要分开部署,使用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);

}

?

?

}

?

?

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

原文:http://xxwang.iteye.com/blog/2153736

(1)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!