乱码是一个经常出现的问题
请求中,参数传递的过程中也是经常出现乱码的问题
本文主要整理了请求乱码中的问题以及解决思路
 
先要理解一个概念前提:
编码就是把图形变成数值码所以说:
图形的字符  ---->  字节数组  是编码
字节数组-------->图形的字符 是解码
 

为什么会乱码?

计算机数据只能是二进制的
数值类型的数据转换成二进制很简单,
但字符类型如何转换成二进制呢?这就需要使用字符编码!
在编码表中,每个字符都有对应的编码,编码是整数,最终在计算机中存储的是字符的编码
而不是字符本身(因为计算机数据都是二进制数值,所以字符本身是无法存储的)。
 
假如说两种编码
红框1    橘色框 2 ,不用较真数值是多少,符号是什么,只为表达概念
每种编码方式内部,字符和数值是一 一对应的
但是如果使用A------>65进行编码 
然后使用      65------>$ 另外一种解码方式解读,显然A就变成了$,这不就是乱码了么
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
不同的编码方式不同,同一个字符的二进制也基本是不同的,如果没有正确的进行解读,那么就会出现乱码问题
发起请求时,不管是什么字符,计算机都不认识,必须编码转换为数值.
接收到请求的地方想要使用,就必须在编码成为字符
乱码的根本在于 编码和解码方式的前后不一致
 

 
如何解决乱码问题,也就是正确编码的问题
请求响应的编码问题

1.直接在地址栏中给出中文

请求数据是由客户端浏览器发送服务器的,请求数据的编码是由浏览器决定的。
例如在浏览器地址栏中给出:http://localhost:8080/servlet/AServlet?name=张三,那么其中“张三”是什么编码的呢?
不同浏览器使用不同的编码,所以这是不确定的!
Chrome:使用UTF-8;
IE:使用GB2312;
FireFox:使用GB2312;
 
(这几个说的不一定对,反正重点是要知道,不同的浏览器,直接地址栏输入的参数的字符编码是不固定的,也说不定未来或许会统一)

2. 响应编码

当使用response.getWriter()来向客户端发送字符数据时,如果在之前没有设置编码,那么默认使用iso,因为iso不支持中文,一定乱码
response.getWriter().println("ServletA");

response.getWriter().println("你好");

 

javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
在使用response.getWriter()之前
可以使用response.setCharacterEncoding()来设置字符流的编码为gbk或utf-8
当然我们通常会选择utf-8
response.setCharacterEncoding("utf-8");
这样使用response.getWriter()发送的字符就是使用utf-8编码的。但还是会出现乱码!
因为浏览器并不知道服务器发送过来的是什么编码的数据!这时浏览器一般会使用gbk来解码,所以乱码!
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
所以需要设置响应的编码,以及通知浏览器应该使用何种编码方式去解读
 
在使用response.getWriter()之前
可以使用
response.setHeader("Content-type","text/html;charset=utf-8")
来设置响应头,通知浏览器服务器这边使用的是utf-8编码
而且在调用setHeader()后
还会自动执行setCharacterEncding()方法。
这样浏览器会使用utf-8解码,所以就不会乱码了!
response.setHeader("Content-type","text/html;charset=utf-8");

response.getWriter().println("ServletA");

response.getWriter().println("你好");

 

javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
 
setHeader("Content-Type", "text/html;charset=utf-8")的快捷方法是:
response.setContentType("text/html;charset=utf-8);
总结:输出响应,想要不乱码
只需要在使用getWriter()方法前:
response.setContentType("text/html;charset=utf-8);

 
如果是静态页面中,使用<meta>来设置content-type响应头,例如:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

 


补充说明: 
UTF-8 中  三个字节表示一个中文
E4BDA0=你  E5A5BD=好  
发送的时候是UTF-8 也就是发送的  E4BDA0E5A5BD
GBK中两个字节表示一个中文
也就是
E4BD   A0E5    A5BD
查表可得:
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码

 
 

3.在页面中发出请求

通常向服务器发送请求数据都需要先请求一个页面,然后用户在页面中输入数据。
页面中有超链接和表单,通过超链接和表单就可以向服务器发送数据了。
用户在页面中输入的数据是由页面本身的编码决定的
又因为页面是服务器发送到客户端浏览器的,所以这个页面本身的编码又由服务器响应决定

 

 

 

javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
 
服务器返回当前页面的响应时,设置响应头content-type,指定当前页面的编码为utf-8
如果设置了那么可以通过浏览器查看响应信息看到
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
如果是
Content-Type:text/html;  而没有后面的charset=utf-8
可以看下输出的响应页面上是否有这一句,也是一样的
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
归根结底是看响应中是否有 Content-type utf-8 的相关信息   有了charset的信息,就按照他来

4.GET请求解读编码

 

当客户端通过GET请求发送数据给服务器时
使用request.getParameter()获取的数据是被服务器误认为ISO-8859-1编码的
也就是说客户端发送过来的数据无论是UTF-8还是GBK,服务器都认为是ISO-8859-1  
tomcat8以后默认编码格式是utf-8;7之前的都是iso8859-1
 

是否需要在使用request.getParameter()获取数据后,再转发成正确的编码
要看你实际使用的tomcat 版本
例如客户端以UTF-8发送的数据,使用tomcat7 以及之前的版本
需要使用如下转码方式:

String name = request.getParameter(“name”);

name = new String(name.getBytes(“iso-8859-1”), “utf-8”);
重点是要理解逻辑:
 tomcat 默认的使用某种编码对传递过来的数据进行了解码
 如果说正好是我们传递过来的,那么不需要做处理
 如果不是,就需要按照他解码的方式,重新编码成字符数组,在使用字节数组 按照编码规则重新解码为字符串
 (字符到字节数组是编码   字节数组到字符是解码)
 
示例:
在utf8页面上 get请求  http://127.0.0.1:8080/servlet/ServletA?name=张三
Servlet中
String name = request.getParameter("name");
System.out.println("request.getParameter(\"name\"): "+name);

name = new String(name.getBytes("iso-8859-1"), "utf-8");
System.out.println("new String(name.getBytes(\"iso-8859-1\"), \"utf-8\"): "+name);
页面是utf8 自然请求是utf8编码规则
tomcat8  默认utf8  解码
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
 
tomcat7 默认iso
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
当然也是可以修改Server.xml中设置URIEncoding的值为UTF-8
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
但是不建议这么做,代码不能依赖tomcat的设置,严重破坏可移植性
 
 

5.POST请求解读编码

当客户端通过POST请求发送数据给服务器时,可以在使用request.getParameter()获取请求参数之前
先通过request.setCharacterEncoding()来指定编码,然后再使用reuqest.getParameter()方法来获取请求参数
那么就是用指定的编码来读取了。
也就是说,如果是POST请求,服务器可以指定编码!
但如果没有指定编码,那么仍旧也还是使用默认的来解读
request.setCharacterEncoding(“utf-8”);
String name = request.getParameter(“name”);

6. URL编码

POST表单提交的类型:
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
Content-Type: application/x-www-form-urlencoded
  • 首先,Content-Type 被指定为 application/x-www-form-urlencoded;
  • 其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
  • 大部分服务端语言都对这种方式有很好的支持。
其实就是把中文转换成%后面跟随两位的16进制。
在客户端和服务器之间传递中文时需要把它转换成网络适合的方式
不是字符编码,客户端与服务器之间传递参数用的一种方式
URL编码需要先指定一种字符编码,把字符串解码后,得到byte[],然后把小于0的字节+256,再转换成16进制。前面再添加一个%。
* POST请求默认就使用URL编码!tomcat会自动使用URL解码!
* URL编码:String username = URLEncoder.encode(username, "utf-8");
* URL解码:String username = URLDecoder.decode(username, "utf-8");
 
这种场景下,编码和解码都是自动的,不需要手动干预
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
浏览器中显示的"张三"
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
新建一个测试类 main方法中执行打印结果一样
public static void main(String[] args) throws UnsupportedEncodingException {
String s= "张三";
System.out.println(URLEncoder.encode(s,"UTF-8"));
}
javaweb请求编码 url编码 响应编码 乱码问题 post编码 get请求编码 中文乱码问题 GET POST参数乱码问题 url乱码问题 get post请求乱码 字符编码
 
 
 
 

相关文章: