尽管字节流也能有办法决绝乱码问题,但是还是比较麻烦,于是java就有了字符流,字符为单位
读写数据,字符流专门用于处理文本
文件。如果处理纯文本的数据优先考虑字符流,其他情况就只能用字节流了(图片、视频、等等只文本
例外)。
从另一角度来说:字符流 = 字节流 + 编码表
来自:https://blog.csdn.net/qq_44543508/article/details/102831084
encoding:编码
decoding:解码
http请求包括:url header bod三个部分
get的请求参数在QueryString中,对于get请求,我们需要关注url是如何encoding的
post的请求参数在body中,对于post请求,需要关注body是如何encoding的
设置get请求Query String 的charset:-->queryStringEncoding
tomcat通过url的chaset来设置QueryString的chaset:可在tomcat根目录下的conf/server.xml中配置,URIEncoding
userBodyEncodingForURL 如果该属性为true,则toncat将使用body的charset作为url的charset
如果tomcat没有设置body的chaset,则使用HTTP请求的Content-type Header中的chaset;如果HTTP请求没设置Content-Type Header,则使用ISO-8859-1作为默认的charset
设置post请求的body的charset
request.setCharacterEncoding("UTF-8")-->该方法在读取请求参数之前调用有效。 post专用,get用不了。
问题起源:
计算机只认识0和1-->提出Unicode编码(对仅有的26个符号采用双字节编码)
乱码原因:
JVM对应的操作系统/浏览器进行编码格式转换时出现错误。
常见字符编码:
1.ascll编码
ascll码使用指定7位或8位二进制数字组合表示128或256种可能的字符。7位二进制数表示所有的大小写字母和数字和标点符号以及一些特殊的控制字符。
2.gbk编码
GB2312
用于汉字处理,通行于中国大陆。编码规则:小于127的字符意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字。前面的一个字节称为高字节,后面一个字节称为低字节。这样大约组合出7000多个字。但是不常见的汉字不能处理,于是就出现了GBK、GB18030
3.Unicode编码
世界存在那么多国家,gbk等编码出现在网络上,由于互不兼容,访问出现乱码。Unicode编码的作用能够实现计算机夸平台、跨语言。包含世界上所有的符号,并且是独一无二的。同时Unicode是字符集,它存在几种实现方式如:UTF-8 UTF-16
UTF-8
UTF-8最大的一个特点是:它是一种变长的编码方式。它使用1~4个字节表示一个符号。对于英文字母,UTF-8编码和ASCLL码是相同的。
基础知识:
编码:信息从一种形式和格式转换为另外一种形式的过程:通俗讲就是讲我们看到的文字图片等信息安装某种规则存储在计算机。
解码:是编码的逆过程。将存储在计算机的二进制转换为可以看见的文字图片等
字符:计算机中使用的字母、数字、字、符号。
字符集:各种文字和符号的总称。常见字符集名称:ASCLL字符集、GB2312字符集、Unicode字符集等。
javaWeb编码和解码:
用户向服务器发送一个HTTP请求,需要编码的地方有url、cookie、parameter,经过编码后服务器接受HTTP请求,解析HTTP请求,然后对url、cookie、parameter进行解码。在服务器进行业务逻辑处理过程中可能需要读取数据库、本地文件或者网络中的其他文件等等。这些过程都需要进行编码和解码。当处理完成后,服务器将数据进行编码后发送给客户端,浏览器经过解码后显示给用户。在整个过程中,涉及编码和解码的地方很多。其中最容易出现乱码的位置在于服务器与客户端进行交互的过程。
请求:
客户端向服务器发送请求无法就通过4种情况:
-
url方式直接访问
-
页面链接
-
表单get提交
-
表单post提交
url方式:
这个url浏览器会对path和parameter进行编码,uri 、 queryString
表单get: 一般通过new String(request.getParameter(“name”).getBytes(“iso-8859-1″),”utf-8″) 的形式来获取正确数据
表单post: 采用的编码也是由页面来决定的,即contenttype。 request.setCharacterEncoding(charset) 。
流的关闭顺序(先开后关原则,一定要按顺序关闭,不然会存在流未关闭完的问题)
- 一般情况下是:先打开的后关闭,后打开的先关闭
- 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
- 可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。
注意:
- 如果将节点流关闭以后再关闭处理流,会抛出IO异常。
- 如果关闭了处理流,在关闭与之相关的节点流,也可能出现IO异常。