get请求中文乱码及get,post编码探究
在我使用get请求进行查询的时候遇到一个问题:
当我的请求参数中有中文时,出现乱码。
可是即使我设置了Spring的characterEncodingFilter,也还是出现乱码。
原因:tomcat默认使用ISO8859-1编码来解析get中的url参数,导致乱码。而characterEncodingFilter或者 request.setCharacterEncoding("UTF-8");都只针对post请求体有效。
下面对Http中get方法编码到tomcat的解码过程进行探究。
解决方法
- 更改tomcat中get方法默认ISO8859-1编码为utf-8编码。
找到conf/server.xml,在<Connector port="8082" protocol="HTTP/1.1"中加入URIEncoding="utf-8"。 - 将参数以iso8859-1编码转化为字节数组,然后再以UTF-8将字节数组转化为字符串。
userName = new String(userName.getBytes("ISO8859-1"), "UTF-8");
URL是怎么编码的?
参考 关于URL编码
一般来说,URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。比如,世界上有英文字母的网址"http://www.abc.com",但是没有希腊字母的网址"http://www.aβγ.com"(读作阿尔法-贝塔-伽玛.com)。这是因为网络标准RFC 1738做了硬性规定。
这意味着,如果URL中有汉字,就必须编码后使用。但是麻烦的是,RFC 1738没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致"URL编码"成为了一个混乱的领域。
不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。经过测试,现在的浏览器大部分都是utf-8编码。但是为了兼容所有的浏览器,可以使用Javascript函数:encodeURI()。
encodeURI()是Javascript中真正用来对URL编码的函数。
它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号"; / ? : @ & = + $ , #",也不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。

它对应的解码函数是decodeURI()。

tomcat是怎么解码的?
get请求是使用url编码方式,而post请求基于请求体自身的编码。
推荐
- get请求含有url参数时,使用js自带的编码函数进行编码。
- post请求在content-type中设置charset=utf-8,否则使用页面默认编码。
get方法的编码
查看tomcat源码中,org.apache.catalina.connector.CoyoteAdapter的方法:
使用在conf/server.xml中 <Connector port="8082" protocol="HTTP/1.1">配置的URIEncoding作为将前端传过来的参数转化为字符数组的编码,缺省为ISO8859-1。
protected void convertURI(MessageBytes uri, Request request)
throws Exception {
ByteChunk bc = uri.getByteChunk();
int length = bc.getLength();
CharChunk cc = uri.getCharChunk();
cc.allocate(length, -1);
// 使用默认编码 ISO8859-1 将字节数组编程字符
String enc = connector.getURIEncoding();
if (enc != null) {
B2CConverter conv = request.getURIConverter();
try {
if (conv == null) {
conv = new B2CConverter(enc, true);
request.setURIConverter(conv);
} else {
conv.recycle();
}
} catch (IOException e) {
log.error("Invalid URI encoding; using HTTP default");
connector.setURIEncoding(null);
}
if (conv != null) {
try {
conv.convert(bc, cc, true);
uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength());
return;
} catch (IOException ioe) {
// Should never happen as B2CConverter should replace
// problematic characters
request.getResponse().sendError(
HttpServletResponse.SC_BAD_REQUEST);
}
}
}
// Default encoding: fast conversion for ISO-8859-1
byte[] bbuf = bc.getBuffer();
char[] cbuf = cc.getBuffer();
int start = bc.getStart();
for (int i = 0; i < length; i++) {
cbuf[i] = (char) (bbuf[i + start] & 0xff);
}
uri.setChars(cbuf, 0, length);
}
post方法的字符编码
如果在servlet的doPost方法中或者filter中设置了request的字符编码,那么就以设置的为准。
- request设置编码
public void doPost(HttpServletRequestrequest,HttpServletResponse response)
throws IOException,ServletException{
//必须在getParameter,getParameterNames,
//getParameterValues方法调用之前进行设置
request.setContentType("UTF-8");
}
- web.xml中配置filter
<filter>
<filter-name>SetCharacterEncoding</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
如果没有进行上面的配置,那么从http header中取出content-type,然后从content-type的值中取出charset的值,charset的值作为post的字符编码。
如content-type=application/x-www-form-urlencoded;charset=utf-8
那么,post的字符编码就是utf-8。
如果从http header中没有取到content-type中的charset,那么,就使用缺省的ISO-8859-1。
参考文档
get请求中文乱码及get,post编码探究的更多相关文章
- Spring-解决请求中文乱码问题
解决spring请求中文乱码问题 1.web.xml添加编码拦截器 <filter> <filter-name>CharacterEncoding</filter-nam ...
- 使用httpclient post请求中文乱码解决办法
使用httpclient post请求中文乱码解决办法 在使用httpclient发送post请求的时候,接收端中文乱码问题解决. 正文: 我们都知道,一般情况下使用post请求是不会出现中文乱码 ...
- get请求与post请求中文乱码问题的解决办法
首先出现中文乱码的原因是tomcat默认的编码方式是"ISO-8859-1",这种编码方式以单个字节作为一个字符,而汉字是以两个字节表示一个字符的. 一,get请求参数中文乱码的解 ...
- 尚硅谷面试第一季-09SpringMVC中如何解决POST请求中文乱码问题GET的又如何处理呢
目录结构: 关键代码: web.xml <filter> <filter-name>CharacterEncodingFilter</filter-name> &l ...
- 解决Post请求中文乱码问题
解决Post请求中文乱码问题 req.setChracterEncoding()要在获取请求参数前调用才有效,不然还是乱码
- 5 Http请求中文乱码处理
java 乱码分很多种,这里主要研究解决http请求中出现乱码的情况. http请求出现中文乱码的主要原因:发送方与接收方编码不一致,服务器默认支持的编码与web应用不一致,如:tomcat 是国外程 ...
- SpringMVC如何解决POST请求中文乱码问题,GET的又如何处理呢?
在web.xml中 <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-c ...
- Java中关于Servlet中请求中文乱码及文件下载
1,Servlet请求响应中文乱码问题 package com.demo.servlet; import java.io.PrintWriter; import java.io.IOException ...
- java web中get请求中文乱码在filter中解决
之前已经讲过get或者post方法的中文乱码问题,之前都是在每个方法中编写设置编码.如果程序变大,就会很繁琐,使用filter可以避免这种繁琐. 1)写一个encodingFilter进行编码设置 p ...
随机推荐
- JAVA基础-IO流(一)
一.IO流 IO流是Java为方便我们对文件的读写进行操作而提供的一种技术.按照读取写入文件的方式不同可以分为字符流和字节流,而每个流派按照功能又分为读和写.字符流读写操作的根类为Reader和Wri ...
- 一个标准的WebView示例
xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
- RNN的简单的推导演算公式(BPTT)
附上y=2x-b拟合的简单的代码. import numpy as np x = np.asarray([2,1,3,5,6]); y = np.zeros((1,5)); learning_rate ...
- Java中import及package的用法
有些人写了一阵子 Java,可是对於 Java 的 package 跟 import 还是不 太了解很多人以為原始码 .java 档案中的 import 会让编译器把所 import 的程式通通写到编 ...
- 2017广东工业大学程序设竞赛E题(倒水)
Description 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把一个 ...
- [国嵌笔记][027][ARM协处理器访问指令]
协处理器作用 协处理器用于执行特定的处理任务,如数学协处理器可以执行控制数字处理,以减轻处理器的负担.ARM处理器最多可以支持16个协处理器,其中CP15是最重要的一个协处理器 CP15的作用 CP1 ...
- Web应用的目录结构
Web应用的目录结构 |- WebRoot : web应用的根目录 |- 静态资源(html+css+js+image+vedio)|- WEB-INF :固定写法. |-classes: (可选 ...
- java常量池詳解
一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池在Clas ...
- SSH会话连接超时问题
目前大多数ssh服务是运行在Linux系统上的sshd服务.当访问终端在windows上时,各终端软件,如,putty,SecureCRT等,大多支持设置向服务器端自动发送消息,来防止终端定期超时.其 ...
- [知了堂学习笔记]_牵线Eclipse和Tomcat第二篇 —— 安装Tomcat&&添加Tomcat到Eclipse
来了来了~~~~~我们的"织女"--Tomcat来了,牛郎们等急了吧!哈哈! 一.安装Tomcat 下载地址:http://tomcat.apache.org/download-7 ...