Hessian源码剖析(三)
来源:互联网 发布:黑暗之光坐骑升阶数据 编辑:程序博客网 时间:2024/04/27 16:38
上篇博文我们分析了一个远程调用的过程,但是没有分析具体的细节,这篇文章我们来分析一下远程调用请求的过程
protected HessianConnection sendRequest(String methodName, Object []args) throws IOException { HessianConnection conn = null; conn = _factory.getConnectionFactory().open(_url);//代码1 boolean isValid = false; try { addRequestHeaders(conn);//代码2 OutputStream os = null; try { os = conn.getOutputStream();//代码3 } catch (Exception e) { throw new HessianRuntimeException(e); } if (log.isLoggable(Level.FINEST)) {//代码4 PrintWriter dbg = new PrintWriter(new LogWriter(log)); HessianDebugOutputStream dOs = new HessianDebugOutputStream(os, dbg); dOs.startTop2(); os = dOs; } AbstractHessianOutput out = _factory.getHessianOutput(os);//代码5 out.call(methodName, args);//代码6 out.flush();//代码7 conn.sendRequest();//代码8 isValid = true; return conn; } finally { if (! isValid && conn != null) conn.destroy(); } }
1、_factory是在创建HessianProxy代理对象时,通过构造器组合进来的HessianProxyFactory对象,HessianProxyFactory组合了两个工厂,一个是HessianConnectionFactory工厂,它负责创建到Server端的HTTP连接,代码1就是通过该工厂打开了到server端的连接,另一个是SerializerFactory工厂,该工厂负责将client端的信息进行序列化然后传输到server端,具体代码如下
public HessianConnection open(URL url) throws IOException { if (log.isLoggable(Level.FINER)) log.finer(this + " open(" + url + ")"); URLConnection conn = url.openConnection(); long connectTimeout = _proxyFactory.getConnectTimeout(); if (connectTimeout >= 0) conn.setConnectTimeout((int) connectTimeout); conn.setDoOutput(true); long readTimeout = _proxyFactory.getReadTimeout(); if (readTimeout > 0) { try { conn.setReadTimeout((int) readTimeout); } catch (Throwable e) { } } return new HessianURLConnection(url, conn); }2、打开了到server端的连接之后就可以通过连接拿到输出流,并向输出流里面写入信息了,但是因为这是一个HTTP请求,所以我们在请求之前要设置对应的请求头,如代码2所示,具体代码如下
protected void addRequestHeaders(HessianConnection conn) { conn.addHeader("Content-Type", "x-application/hessian"); conn.addHeader("Accept-Encoding", "deflate"); String basicAuth = _factory.getBasicAuth(); if (basicAuth != null) conn.addHeader("Authorization", basicAuth); }3、通过连接Connection拿到输出流
4、因为默认的日志级别是Info,所以不会走到代码4的判断条件里
5、通过HessianProxyFactory获取经过Hession包装过的输出流AbstractHessianOutput,AbstractHessianOutput只是一个抽象类,真正的包装类是HessianOutput,创建完HessianOutput对象后需要给该对象组合一个SerializerFactory工厂用于client端参数的序列化,代码如下
public AbstractHessianOutput getHessianOutput(OutputStream os) { AbstractHessianOutput out; if (_isHessian2Request)//默认为false,不会走到这里 out = new Hessian2Output(os); else { HessianOutput out1 = new HessianOutput(os); out = out1; if (_isHessian2Reply) out1.setVersion(2); } out.setSerializerFactory(getSerializerFactory()); return out; }6、调用HessianOutput对象的call()方法如代码6所示,call()方法的具体实现如下,在call方法中最复杂的当属writeObject()方法了,因为参数的类型是千变万化的,即可能有java的基本类型,又可能有自定义的类型,还可以是list,Map等嵌套的类型,如何将这些信息按一定的规则写出到输出流是Hessian的核心与难点,下篇文章我们来具体分析
public void call(String method, Object []args) throws IOException { int length = args != null ? args.length : 0; startCall(method, length);//首先将方法名称写到输出流 for (int i = 0; i < length; i++) writeObject(args[i]);//将参数写出到输出流 completeCall();//将结束符写出到输出流 }7、代码7将输出缓冲区中的字节流写到网络中
8、将字节流写入到server端后等待server端返回状态码,如果是异常的(非200的状态码)状态码则进行相应的处理
到此为止字节流就已经写到了server端
阅读全文
0 0
- Hessian源码剖析(三)
- Hessian源码剖析(一)
- Hessian源码剖析(二)
- Hessian源码剖析(七)
- Hessian源码分析(三)------ HessianSkeleton
- Hessian源码分析(三)------ HessianSkeleton
- Azureus源码剖析(三)
- chromium源码剖析(三)
- chromium源码剖析(三)
- Atlas源码剖析(三)
- hessian原理服务端源码分析(三)
- Hessian源码学习(2)
- Hessian源码解析(四)
- Mina2.0框架源码剖析(三)
- Mina2.0框架源码剖析(三)
- Mina2.0框架源码剖析(三)
- Java基础(三)HashMap源码剖析
- STL源码剖析(三)---迭代器
- C/C++内存管理
- Netty事件循环--无锁化
- Error:NDK not configured. Download it with SDK manager
- 【EXTJS入门】创建并编译一个APP
- 二叉树的层序遍历
- Hessian源码剖析(三)
- codeforces-727A
- Code Forces 587A
- Linux下的mkdir&&rmdir指令
- 三、Eureka 的常用配
- 日常问题总结 二
- Python实现各种内排序算法
- PTA- 链式表的按序号查找
- 文章标题