目前幾套系統(tǒng)中主要使用的hessian進(jìn)行遠(yuǎn)程調(diào)用webservice服務(wù)的有hessian的HessianProxyFactory(com.caucho.hessian.client.HessianProxyFactory)和spring的HessianProxyFactoryBean(org.springframework.remoting.caucho.HessianProxyFactoryBean).
1.HessianProxyFactory
查看HessianProxyFactory源碼后發(fā)現(xiàn),hessian在創(chuàng)建http請(qǐng)求連接webservice服務(wù)并沒有對(duì)連接超時(shí)進(jìn)行相關(guān)的參數(shù)設(shè)置,所以當(dāng)網(wǎng)絡(luò)出現(xiàn)問題就會(huì)造成整個(gè)hessian處理的阻塞,進(jìn)而阻塞整個(gè)線程后續(xù)的處理
以下是HessianProxyFactory對(duì)連接處理的源碼
protected URLConnection openConnection(URL url)
throws IOException
{
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
if (_readTimeout > 0) {
try {
conn.setReadTimeout((int) _readTimeout);
} catch (Throwable e) {
}
}
conn.setRequestProperty("Content-Type", "x-application/hessian");
if (_basicAuth != null)
conn.setRequestProperty("Authorization", _basicAuth);
else if (_user != null && _password != null) {
_basicAuth = "Basic " + base64(_user + ":" + _password);
conn.setRequestProperty("Authorization", _basicAuth);
}
return conn;
}
所以我們針對(duì)此邏輯繼承并重寫該openConnection方法,在創(chuàng)建http連接的時(shí)候通過設(shè)置連接超時(shí)時(shí)間來解決因網(wǎng)絡(luò)問題阻塞程序繼續(xù)的問題
public class MyHessianProxyFactory extends HessianProxyFactory {
private int connectTimeOut = 10000;
private int readTimeOut = 10000;
public int getConnectTimeOut() {
return connectTimeOut;
}
public void setConnectTimeOut(int connectTimeOut) {
this.connectTimeOut = connectTimeOut;
}
public int getReadTimeOut() {
return readTimeOut;
}
public void setReadTimeOut(int readTimeOut) {
this.readTimeOut = readTimeOut;
}
protected URLConnection openConnection(URL url) throws IOException {
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
if (this.connectTimeOut > 0) {
conn.setConnectTimeout(this.connectTimeOut);
}
if (this.readTimeOut > 0) {
conn.setReadTimeout(this.readTimeOut);
}
conn.setRequestProperty("Content-Type", "x-application/hessian");
if (_basicAuth != null)
conn.setRequestProperty("Authorization", _basicAuth);
else if (_user != null && _password != null) {
_basicAuth = "Basic " + base64(_user + ":" + _password);
conn.setRequestProperty("Authorization", _basicAuth);
}
return conn;
}
}
2.HessianProxyFactoryBean
查看spring的HessianProxyFactoryBean源碼發(fā)現(xiàn),它在封裝hessian是直接創(chuàng)建一個(gè)HessianProxyFactory實(shí)例,然后利用該實(shí)例完成創(chuàng)建遠(yuǎn)程服務(wù)
public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean {
private Object serviceProxy;
public void afterPropertiesSet() {
super.afterPropertiesSet();
this.serviceProxy = ProxyFactory.getProxy(getServiceInterface(), this);
}
public Object getObject() {
return this.serviceProxy;
}
public Class getObjectType() {
return getServiceInterface();
}
public boolean isSingleton() {
return true;
}
}
所以對(duì)此的解決方法與上面差不多,繼承HessianProxyFactoryBean然后加入相應(yīng)的連接超時(shí)和讀取超時(shí)的變量,重寫afterPropertiesSet方法,并且同時(shí)完成上面第一步對(duì)HessianProxyFactory的改造,這樣就能保證連接遠(yuǎn)程webserver服務(wù)器時(shí)不會(huì)因?yàn)榫W(wǎng)絡(luò)原因阻塞程序的執(zhí)行
public class MyHessianProxyFactoryBean extends HessianProxyFactoryBean {
private MyHessianProxyFactory proxyFactory = new MyHessianProxyFactory();
private int readTimeOut = 10000;
private int connectTimeOut = 10000;
public int getReadTimeOut() {
return readTimeOut;
}
public void setReadTimeOut(int readTimeOut) {
this.readTimeOut = readTimeOut;
}
public int getConnectTimeOut() {
return connectTimeOut;
}
public void setConnectTimeOut(int connectTimeOut) {
this.connectTimeOut = connectTimeOut;
}
public void afterPropertiesSet() {
proxyFactory.setReadTimeout(readTimeOut);
proxyFactory.setConnectTimeOut(connectTimeOut);
setProxyFactory(proxyFactory);
super.afterPropertiesSet();
}
}