您的位置:首页 > 其它

hessian源码分析-服务器端

2015-04-02 10:34 411 查看
服务器端逻辑很简单,核心类是HessianSkeleton,客户端的请求最终会调用到HessianSkeleton.invoke方法,此方法其实没有什么特别,反序列化,调用相应的方法,再把返回值序列化,放响应里,HessianSkeleton继承AbstractSkeleton,在实例化时,AbstractSkeleton的构造函数会把相关类的方法名和方法实例都取出来,缓存到_methodMap里,方便使用:

/**
* Create a new hessian skeleton.
*
* @param apiClass the API interface
*/
protected AbstractSkeleton(Class apiClass)
{
_apiClass = apiClass;

Method []methodList = apiClass.getMethods();

for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];

if (_methodMap.get(method.getName()) == null)
_methodMap.put(method.getName(), methodList[i]);

Class []param = method.getParameterTypes();
String mangledName = method.getName() + "__" + param.length;
_methodMap.put(mangledName, methodList[i]);

_methodMap.put(mangleName(method, false), methodList[i]);
}
}
下面来看看HessianSkeleton的invoke方法,反序列化,调用,序列化:

/**
* Invoke the object with the request from the input stream.
*
* @param in the Hessian input stream
* @param out the Hessian output stream
*/
public void invoke(Object service,
AbstractHessianInput in,
AbstractHessianOutput out)
throws Exception
{
ServiceContext context = ServiceContext.getContext();

// backward compatibility for some frameworks that don't read
// the call type first
in.skipOptionalCall();

// Hessian 1.0 backward compatibility
String header;
while ((header = in.readHeader()) != null) {
Object value = in.readObject();

context.addHeader(header, value);
}

// 根据方法名取方法实例
String methodName = in.readMethod();
int argLength = in.readMethodArgLength();

Method method;

method = getMethod(methodName + "__" + argLength);

if (method == null)
method = getMethod(methodName);

if (method != null) {
}
else if ("_hessian_getAttribute".equals(methodName)) {
String attrName = in.readString();
in.completeCall();

String value = null;

if ("java.api.class".equals(attrName))
value = getAPIClassName();
else if ("java.home.class".equals(attrName))
value = getHomeClassName();
else if ("java.object.class".equals(attrName))
value = getObjectClassName();

out.writeReply(value);
out.close();
return;
}
else if (method == null) {
out.writeFault("NoSuchMethodException",
"The service has no method named: " + in.getMethod(),
null);
out.close();
return;
}

Class<?> []args = method.getParameterTypes();

if (argLength != args.length && argLength >= 0) {
out.writeFault("NoSuchMethod",
"method " + method + " argument length mismatch, received length=" + argLength,
null);
out.close();
return;
}

Object []values = new Object[args.length];
// 为每个参数反序列化,反序列化操作过程和客户端类似
for (int i = 0; i < args.length; i++) {
// XXX: needs Marshal object
values[i] = in.readObject(args[i]);
}

Object result = null;

try {
// 方法调用
result = method.invoke(service, values);
} catch (Exception e) {
Throwable e1 = e;
if (e1 instanceof InvocationTargetException)
e1 = ((InvocationTargetException) e).getTargetException();

log.log(Level.FINE, this + " " + e1.toString(), e1);

out.writeFault("ServiceException", e1.getMessage(), e1);
out.close();
return;
}

// The complete call needs to be after the invoke to handle a
// trailing InputStream
in.completeCall();

// 序列化写入响应,里面很常规的逻辑,和client端类似,取相应的序列化实例,然后操作
out.writeReply(result);

out.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: