在tomcat核心处理中有这么一个需求——“为了提高编码性能,对于socket接收到的字节流不马上进行某种编码的转码,而是应该保留字节流的形式,在需要时、在指定编码时才进行转码工作”。MessageBytes正是为解决这个问题而提出的一个类。

消息字节封装了不同类型方式用于表示信息,它包含了四种类型:T_BYTES、T_CHARS、T_STR、T_NULL,分别表示字节类型、字符类型、字符串类型、空。由于web服务器通信过程使用ASCII码通信,对应的是字节,所以这里选取T_BYTES类型作为案例说明,其他类型与之类似。消息字节的使用方法很简单,假如有一个字节数组byte[] buffer,它坐标的第3到第20之间的字节数组组成的字符表示Request对象中的方法变量的值,那么用以下代码简单表示:

①   public class Request{

MessageBytes methodMB = new MessageBytes();

public MessageBytes method() {

returnmethodMB;

}

}

②   Request request = new Request();

request.method().setBytes(buffer, 3, 18);

执行上面操作后就完成对字节数组的某段进行标记操作,方便以后获取指定的一段字节数组,参照下图,你可以用多个消息字节对buffer标记,例如对请求变量、协议版本等变量进行标记,每个消息字节实例标识了一段字节数组,可以通过如下获取并转为字符串类型:

request.method().toString();

使用起来很简单,接着看下实际实现原理,化繁为简,由于tomcat底层接收的是字节流,于是只考虑T_BYTES的情况。

①   MessageBytes类

public class MessageBytes {

private finalByteChunk byteC = new ByteChunk();

public voidsetBytes(byte[] b, int off, int len) {

byteC.setBytes(b,off, len);

}

public StringtoString() {

returnbyteC.toString();

}

}

②   ByteChunk类

public class ByteChunk {

privatebyte[] buff;

private intstart = 0;

private intend;

public voidsetBytes(byte[] b, int off, int len) {

buff= b;

start= off;

end= start + len;

}

public StringtoString() {

Charsetcharset=Charset.forName("ISO_8859_1");

CharBuffercb = charset.decode(ByteBuffer.wrap(buff, start, end - start));

returnnew String(cb.array(), cb.arrayOffset(), cb.length());

}

}

前面示例中methodMB.setBytes(buffer, 3, 18)其实是调用了ByteChunk的setBytes方法,把字节流及始末坐标设置好,后面methodMB.toString()同样调用了ByteChunk的toString方法,根据指定编码进行转码,这里是ISO_8859_1。这样一来就达到了延迟处理模式的效果,在需要时才根据指定编码转码并获取字符串,不需要的话则无需转,处理性能得到提高。

Tomcat对于socket接收的信息都用消息字节表示,好处是实现一种延迟处理模式,提高性能。而且实际上tomcat还引入了字符串缓存,在转码之前会先从缓存中查找是否有对应的编码的字符串,如果存在则不必再执行转码动作而直接返回对应的字符串,性能进一步得到优化。为了性能我们必须要多做一些额外的工作,这也是tomcat接收到的信息为何不直接用字符串String保存的原因。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:

消息字节——MessageBytes的更多相关文章

  1. NSQ源码剖析——主要结构方法和消息生产消费过程

    目录 1 概述 2 主要结构体及方法 2.1 NSQD 2.2 tcpServer 2.3 protocolV2 2.4 clientV2 2.5 Topic 2.6 channel 3 启动过程 4 ...

  2. WebSocket与消息推送

    B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链 ...

  3. ZeroMQ接口函数之 :zmq_recvmsg – 从一个socket上接收一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-recvmsg zmq_recvmsg(3)         ØMQ Manual - ØMQ/4.1.0 Nam ...

  4. ZeroMQ接口函数之 :zmq_sendmsg – 从一个socket上发送一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-sendmsg zmq_sendmsg(3)        ØMQ Manual - ØMQ/4.1.0 Name ...

  5. HTML5 学习总结(五)——WebSocket与消息推送

    B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链 ...

  6. HTML5 学习笔记(五)——WebSocket与消息推送

    B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链 ...

  7. System V IPC(1)-消息队列

    一.概述                                                    System V三种IPC:消息队列,信号量,共享内存.这三种IPC最先出现在AT&am ...

  8. 消息队列接口API(posix 接口和 system v接口)

    消息队列 posix API 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.信号这种通信方式更像\"即时\"的通信方式,它要求接受信号的进程在某个时间范围内对信 ...

  9. 【原创】Kafka 0.11消息设计

    Kafka 0.11版本增加了很多新功能,包括支持事务.精确一次处理语义和幂等producer等,而实现这些新功能的前提就是要提供支持这些功能的新版本消息格式,同时也要维护与老版本的兼容性.本文将详细 ...

随机推荐

  1. Chrome的First Paint

    前言 First paint 直译过来的意思就是浏览器第一次渲染(paint),在First paint之前是白屏,在这个时间点之后用户就能看到(部分)页面内容. 所以研究这个First Paint的 ...

  2. 【python教程01】 编辑器

    工欲善其事,必先利其器.学习python,首先应该安装好开发中使用的编辑器. 那么在这里说一下我们推荐的两款:sublime text  && pycharm   为什么推荐这两款编辑 ...

  3. MySQL中UTF8编码的数据在cmd下乱码

    MySQL中UTF8编码的数据在cmd下乱,在数据库ide中看到的却是中文. 其实,原因是cmd用gbk的格式来显示数据,那么我们只需要将utf-8存储的数据用gbk的格式输出到cmd即可. 解决方法 ...

  4. SSH构造struts2项目

    第一在pom.xml导入相应的包 (网上有很多导入多个包的教程,我缩减到一个了) <project xmlns="http://maven.apache.org/POM/4.0.0&q ...

  5. angularjs+ionic的app端分页和条件

    做app项目积分商城的商品列表需要分页显示 实现: ionic滚动条:ion-scroll 用于创建一个可滚动的容器. 附:菜鸟教程:http://www.runoob.com/ionic/ionic ...

  6. 关于ES7中的async/await在客户端和服务端上的实践

    一.前言 在项目中经常遇到处理异步请求的情况,面对层层的嵌套,回调显示那么苍白无力: async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案,既然这样就用上吧. 二.配 ...

  7. 628. Maximum Product of Three Numbers

    Given an integer array, find three numbers whose product is maximum and output the maximum product. ...

  8. for循环&len函数和range函数的运用

     函数:len() 作用:返回字符串.列表.字典.元组等长度 语法:len(str) 参数: str:要计算的字符串.列表.字典.元组等 返回值:字符串.列表.字典.元组等元素的长度 实例 1.计算字 ...

  9. Java语言程序设计-Markdown格式作业模板

    Markdown格式作业模板如下,大家可以直接复制粘贴使用. 注意:作业中不能只写答案,题目本身也要出现.. # 1. 本章学习总结 你对于本章知识的学习总结 # 2. 书面作业 **Q1 java ...

  10. 更快实现Android多级树形选择列表

    快速实现Android多级树形列表,这个库是在鸿洋多级树形列表demo中修改而来. 解决的问题: 1. 支持ID为int类型和String类型. 2. 支持多级复选框选中,使用只需一行代码. 3. 支 ...