hessian原理解析二(服务端分析)
hessian 服務(wù)端源碼分析
我們?cè)诨仡^看看 web.xml 中 servlet 配置
<servlet>
<servlet-name>HelloHessian</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>service-class</param-name>
<param-value>com.hessian.server.HelloHessianImpl</param-value>
</init-param>
</servlet>
服務(wù)端HessianServlet 處理hessian 請(qǐng)求 ,HessianServlet 繼承HttpServlet, 每個(gè)servlet有兩個(gè)重要的方法 init 和 service
1、void init(ServletConfig config) 初始化遠(yuǎn)程服務(wù)實(shí)現(xiàn)類、遠(yuǎn)程服務(wù)接口類以及HessianSkeleton
a、初始化遠(yuǎn)程服務(wù)實(shí)現(xiàn)類, home-class 、service-class
?if (getInitParameter("home-class") != null) {
String className = getInitParameter("home-class");
Class<?> homeClass = loadClass(className);
_homeImpl = homeClass.newInstance();
init(_homeImpl);
} else if (getInitParameter("service-class") != null) {
String className = getInitParameter("service-class");
Class<?> homeClass = loadClass(className);
_homeImpl = homeClass.newInstance(); init(_homeImpl);
}
?
b 、初始化遠(yuǎn)程服務(wù)接口
if (getInitParameter("home-api") != null) {
String className = getInitParameter("home-api");
_homeAPI = loadClass(className);
} else if (getInitParameter("api-class") != null) {
String className = getInitParameter("api-class");
_homeAPI = loadClass(className);
} else if (_homeImpl != null) {
_homeAPI = _homeImpl.getClass();
}
?
c 、初始化 HessianSkeleton
_homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);
// 取服務(wù)類的方法
Method []methodList = apiClass.getMethods()
// 遍歷 服務(wù)類的方法,放入_methodMap
for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
Class []param = method.getParameterTypes();
String mangledName = method.getName() + "__" + param.length;
_methodMap.put(method.getName(), methodList[i]);
_methodMap.put(mangledName, methodList[i]);
_methodMap.put(mangleName(method, false), methodList[i]);
}
hessian 支持重載處理,關(guān)鍵點(diǎn): 比如對(duì)于一個(gè)方法 public void sayHello(User user), 那么在_methodMap中會(huì)存放三個(gè)key sayHello sayHello_1, sayHello_User
?
?
2、service(ServletRequest request, ServletResponse response) 重寫父類的service 方法
2.1、 檢查請(qǐng)求方式是否為POST
if (! req.getMethod().equals("POST")) {
res.setStatus(500); // ?"Hessian Requires POST"
?return;
}
2.2、獲取輸入輸出流、對(duì)象的序列化工廠 執(zhí)行目標(biāo)目標(biāo)服務(wù)方法
ServletInputStream e = request.getInputStream();
ServletOutputStream os = response.getOutputStream();
SerializerFactory serializerFactory = this.getSerializerFactory();
hessianSkeleton.invoke(is, os, serializerFactory)
?
hessianServlet 處理請(qǐng)求時(shí)序圖
?
?
HessianSkeleton invoke 方法解析:
public void invoke(Object service,AbstractHessianInput in,AbstractHessianOutput out){
//讀取方法調(diào)用名
String methodName = in.readMethod();
int argLength = in.readMethodArgLength();
Method method = this.getMethod(methodName + "_" + argLength);
//讀取調(diào)用方法參數(shù)
Class[] args = method.getParameterTypes();
Object[] values = new Object[args.length];
? ? ? for(int i= 0; i < args.length; ++i) {
values[i] = in.readObject(args[i]);
}
//執(zhí)行目標(biāo)方法調(diào)用
? ? ?result = method.invoke(service, values)
? ? ?//結(jié)果輸出
? ? out.writeReply(result);
? ? out.close();
?
? ? ? 輸出格式:
? ??
? ? ??此處為16進(jìn)制數(shù)表示
? ? ? 72 01 00 53 00 05 74 69 67 65 72 7A
? ? ? ?r ? ? ? ? ? ?s ? ? ? ? ? ? ?t ? i ? g ? ?e ? r ? z?
?
轉(zhuǎn)載于:https://www.cnblogs.com/wwg168/p/6337067.html
總結(jié)
以上是生活随笔為你收集整理的hessian原理解析二(服务端分析)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis (一)Redis简介、安装
- 下一篇: 程序员整理的各种不错的工具