我们知道Tomcat通信是建立在Socket的基础上,而套接字在服务器端和客户端传递的报文都是未经过编码的字节流,每8位组成1个字节,计算机以二进制为基础,这是由于使用晶体管的开合状态表示1和0,这样8个电晶体管就可以组成一个字节,这正是应用层使用的最小单位——字节。

在通过Socket进行网络通信的程序中,假如我们在接收到报文时不知道通过什么编码才能正确解码,最好的办法就是用Socket最底层的输入装置读取字节流,在确认编码后再对这些字节流进行转码,否则产生解码错误。我们常见的编码有ASCII、GB2312、UNICODE、UTF-8等等,除此之外还有很多其他编码,为什么会有这么多不同的编码?

ASCII编码即个字符已经完全满足使用英语的美国人,英语单词可以通过拆分成字母后用ASCII码表示。

则表示ASCII,如果两个大于127的字节连在一起则表示汉字,而且两个字节的值都在一定的范围内。经过一轮扩展后已经基本解决汉字编码不足问题。

再后来很多国家都按自己规定给自己的文字编码,对其他国家的编码一概不认识,情况一度混乱。接着国际标准化组织推出UNICODE编码,它要把全世界所有文字符号都包括进来,使用两个字节16位对所有字符进行编码,同时为了保证兼容ASCII码,低七位仍用于表示ASCII码原来的字符。通过UNICODE确实是把世界所有字符都统一起来了。

UNICODE编码虽然统一了所有字符,但还存在一个问题,如果是英文字符其实用一个字节已经足够,但使用UNICODE却必须要搭上另外一个毫无意义的字节,在网络传输过程中则意味着要多传输一倍无用的报文。于是引入UTF-8编码,它属于UNICODE的一种实现,它是一种变长的编码方式,在UTF-8规定的实现下可以用一个字节表示ASCII码表示的所有字符,避免了多余的空间浪费。

出了上面几种常见的编码,还有很多其他编码,不同编码指定的规则也不同,但基本都对ASCII做了兼容处理,可以说ASCII是最基础的,这节正是讨论ASCII码解密的常用方法——表驱动模式。

谈到web容器其实就是基于HTTP协议通信建立起两端通信,通过socket实现报文传输,传输过程肯定设计编码的约定,如果没有一个约定将导致消息解码错误。HTTP报文包括三部分:请求行、请求头和请求体(详细可参加前面HTTP协议章节),HTTP协议约定请求行和请求头必须用ASCII编码,这样才能把所有基于HTTP协议通信服务器统一起来,以免造成不同系统默认编码带来混乱。Tomcat接收到ASCII编码的报文,因为ASCII码长度为1字节(8位),java的byte长度也是1字节,两者刚好符合,所以在java中套接字接收到的报文是使用字节类型的数组进行缓冲存储。一般而言,我们比较关心ASCII码向数字、字母及几个特殊符号的解码,通过他们已经足以组成常用的词语语句。如下表,ASCII码中48-57分别表示数字0-9,65-90分别代表A-Z,97-122分别代表a-z。

在解码的过程涉及一些逻辑处理,例如解码后是否为英语字母、是大写还是小写、是否为数字、是否为空白符、转换为其他类型、大小写转换等等。我们惯用的办法是直接用if-else进行判断,如要判断一个ASCII编码是否为英语字母就判断编码是否在65到90、97到122之间,而表驱动思想则不是这样做,它把一张是否为英语字母的结果表放在内存,如下图所示,数组中标为t的表示是英语字母,数组的值即是结果。

类似地,根据其他需求可以在内存中存放更多张表,把判断的逻辑结果事先算好,直接获取数组值便是需要的结果。表驱动模式经常被用于取代很多if-else、switch-case逻辑判断语句中,它的使用有利于提高代码的可读性和维护性。Tomcat使用的ASCII表驱动类为org.apache.tomcat.util.buf.Ascii.java。

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

Tomcat内核之ASCII解码的表驱动模式的更多相关文章

  1. (原创)c++11改进我们的模式之改进表驱动模式

    所谓表驱动法(Table-Driven Approach),简单讲是指用查表的方法获取值.表驱动是将一些通过较为复杂逻辑语句来得到数据信息的方式,通过查询表的方式来实现,将数据信息存放在表里.对于消除 ...

  2. [lua]原来这才是表驱动的正确表达方式

    曾经写了个很煞笔的脚本模拟switch..case语法形式.[lua]尝试一种Case语法糖 而今实际项目应用中突发,原来这才是正确的表驱动方式表达.如下所贴: function event_do( ...

  3. 查询优化--小表驱动大表(In,Exists区别)

    Mysql 系列文章主页 =============== 本文将以真实例子来讲解小表驱动大表(In,Exists区别) 1 准备数据 1.1 创建表.函数.存储过程 参照  这篇(调用函数和存储过程批 ...

  4. 6.2 小表驱动大表(exists的应用)

    1. 优化原则:小表驱动大表,即小数据集驱动大数据集. select * from A where id in (select id from B) 等价于: for select id from B ...

  5. MySQL高级知识(十六)——小表驱动大表

    前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...

  6. 表驱动方法(Table-Driven Methods)

    表驱动方法(Table-Driven Methods) - winner_0715 - 博客园 https://www.cnblogs.com/winner-0715/p/9382048.html W ...

  7. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  8. Table-Driven Design 表驱动设计

    注:本文所有代码来自 http://www.codeproject.com/Articles/42732/Table-driven-Approach 在许多程序中,经常需要处理那些拥有种种色色不同特性 ...

  9. Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 ; $i < ; $i++) { ; $i < ; $j++) { } } ; $i < ; $i++) { ; $i < ; $j++) { } } ...

随机推荐

  1. ●BZOJ 3894 文理分科

    题链: https://vijos.org/d/ljt12138/p/58c696b8d3d8a16c62a248d4 (要权限号啊...用这个交吧) 题解: 题目大意:    N*M的矩阵,每个位置 ...

  2. 2015 多校联赛 ——HDU5416(异或)

    CRB has a tree, whose vertices are labeled by 1, 2, …, N. They are connected by N – 1 edges. Each ed ...

  3. poj 3264 & poj 3468(线段树)

    poj 3264 Sample Input 6 3 1 7 3 4 2 5 1 5 4 6 2 2 Sample Output 6 3 0 求任一区间的最大值和最小值的差 #include<io ...

  4. ●BZOJ 3622 已经没有什么好害怕的了

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3622 题解: 容斥,dp1).可以求出需要多少对"糖果>药片"(K ...

  5. Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)

        简单的小球沿贝塞尔曲线运动,适合场景漫游使用 贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自http://blog.csdn.net/u010019717/article/details/4768 ...

  6. Cisco动态路由配置

    前言: 学完静态路由配置,该学动态路由.所以 学习完后来做终结. 准备: PC:192.168.1.10 R1:fa0/0 192.168.1.1 fa0/1 1.1.12.1 R2: fa0/0 1 ...

  7. Java编写高质量代码改善程序的151个建议

    第一章  Java开发中通用的方法和准则 建议1:不要在常量和变量中出现易混淆的字母: (i.l.1:o.0等). 建议2:莫让常量蜕变成变量: (代码运行工程中不要改变常量值). 建议3:三元操作符 ...

  8. 使用Vitrualbox虚拟Windows Server 2016系统的一些常见问题

    所有的问题都是基于有路由器的网络环境下进行设置的,所有的vitrualbox都是安装在win7或者win2008系统上进行的. 1.无法创建x64系统? 解决方法:1)进入主板bios设置,开启cpu ...

  9. Git 中 SSH key 生成步骤

    由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以必须要让github仓库认证你SSH key,在此之前,必须要生成SSH key. 第1步:创建SSH Key.在windows下 ...

  10. 关于ubuntu14.04LTS 64位 播放优酷视频

    起因:chrome无法播放优酷视频,然后换firefox发现居然没有装flash 插件. 解释:关于chrome在网上看到了不少说法,说chrome新版本的不支持adobe flash之类的,但是这些 ...