您的位置:首页 > 其它

对使用Hessian协议调用在程序中应用的理解

2010-11-29 21:04 363 查看
Hessian是romote procedure call协议。这个协议是一个二进制协议。在应用过程中的流程是“客户端->序列化写到输出流—>远程方法(服务器端)—>序列化写到输出流 —>客户端读取输入流—>输出结果”。

在我们的项目RingMaster中的应用是这样的。

首先,需要定义一个接口,这个接口是服务器端和客户端公用的。我们的项目中是RemoteInterface。

其次,在客户端需要通过HessianProxyFactory hessianFactory = new HessianProxyFactory();来获取一个hessianFactory的实例。调用factory.create(apiClass, url); 返回一个Proxy对象的实例,这个实例指出了handler是HessianProxy。

那么在我们的项目中,将这些部分结合起来,最终的调用将由HessianProxy来实现调用。在HessianProxy的invoke函数中,进行了最基本的http的链接,发送数据给Hessian的server端。同时,处理server端返回的内容进行反序列化转化成对象返回。

public Object invoke(Object proxy, Method method, Object []args)
throws Throwable
{
String mangleName;

synchronized (_mangleMap) {
mangleName = _mangleMap.get(method);
}

if (mangleName == null) {
String methodName = method.getName();
Class []params = method.getParameterTypes();

// equals and hashCode are special cased
if (methodName.equals("equals")
&& params.length == 1 && params[0].equals(Object.class)) {
Object value = args[0];
if (value == null || ! Proxy.isProxyClass(value.getClass()))
return new Boolean(false);

HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);

return new Boolean(_url.equals(handler.getURL()));
}
else if (methodName.equals("hashCode") && params.length == 0)
return new Integer(_url.hashCode());
else if (methodName.equals("getHessianType"))
return proxy.getClass().getInterfaces()[0].getName();
else if (methodName.equals("getHessianURL"))
return _url.toString();
else if (methodName.equals("toString") && params.length == 0)
return "HessianProxy[" + _url + "]";

if (! _factory.isOverloadEnabled())
mangleName = method.getName();
else
mangleName = mangleName(method);

synchronized (_mangleMap) {
_mangleMap.put(method, mangleName);
}
}

InputStream is = null;
URLConnection conn = null;
HttpURLConnection httpConn = null;

try {
if (log.isLoggable(Level.FINER))
log.finer("Hessian[" + _url + "] calling " + mangleName);

conn = sendRequest(mangleName, args);

if (conn instanceof HttpURLConnection) {
httpConn = (HttpURLConnection) conn;
int code = 500;

try {
code = httpConn.getResponseCode();
} catch (Exception e) {
}

parseResponseHeaders(conn);

if (code != 200) {
StringBuffer sb = new StringBuffer();
int ch;

try {
is = httpConn.getInputStream();

if (is != null) {
while ((ch = is.read()) >= 0)
sb.append((char) ch);

is.close();
}

is = httpConn.getErrorStream();
if (is != null) {
while ((ch = is.read()) >= 0)
sb.append((char) ch);
}
} catch (FileNotFoundException e) {
throw new HessianConnectionException("HessianProxy cannot connect to '" + _url, e);
} catch (IOException e) {
if (is == null)
throw new HessianConnectionException(code + ": " + e, e);
else
throw new HessianConnectionException(code + ": " + sb, e);
}

if (is != null)
is.close();

throw new HessianConnectionException(code + ": " + sb.toString());
}
}

is = conn.getInputStream();

if (log.isLoggable(Level.FINEST)) {
PrintWriter dbg = new PrintWriter(new LogWriter(log));
is = new HessianDebugInputStream(is, dbg);
}

AbstractHessianInput in = _factory.getHessianInput(is);

in.startReply();

Object value = in.readObject(method.getReturnType());

if (value instanceof InputStream) {
value = new ResultInputStream(httpConn, is, in, (InputStream) value);
is = null;
httpConn = null;
}
else
in.completeReply();

return value;
} catch (HessianProtocolException e) {
throw new HessianRuntimeException(e);
} finally {
try {
if (is != null)
is.close();
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
}

try {
if (httpConn != null)
httpConn.disconnect();
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐