您的位置:首页 > 运维架构 > Tomcat

Tomcat 中 GET方式 请求 中文乱码 出现的原因

2010-08-27 21:40 453 查看
网上很多关于GET方式请求中文乱码的解决方案,大体类似. 这里主要讲一下Tomcat在处理URL参数过程中, 究竟是为什么会导致了GET方式请求的中文乱码. 一句话概括就是: Tomcat默认将单字节作为一个字符,但是中文是2个字节表示一个字符....

首先来一个Tomcat解析URL中参数的序列图,其中阴影部分就是造成乱码的地方.





测试场景:

对于一个从官方下载的Tomcat6,不去任何配置.(这里强调不去任何配置主要是指不在Tomcat的server.xml文件中作任何修改.)

在Tomcat的 webapps/ROOT目录下新建一个test.jsp:

<html>
<head><title></title></head>
<body>
<%
String name = request.getParameter("name" );
System.out.print(name );
%>
</body>
</html>

然后发起这样一个请求 http://localhost:8080/test.jsp?name=ni%D5%C6%B9%F1

(真实面目是:http://localhost:8080/test.jsp?name=ni掌柜 )

接着我们定位到上面阴影部分的代码:

private String urlDecode(ByteChunk bc, String enc)
throws IOException {
if( urlDec==null ) {
urlDec=new UDecoder();
}
urlDec.convert(bc); //这个方法影响不大,只是对那个java.net.URLEncod...编码的进行处理.
String result = null;
if (enc != null) {
//关键问题:如果这里没有指定URIEncoding的话, 那么enc是null
bc.setEncoding(enc);
result = bc.toString();
}
//这个地方如果没有配置URIEncoding,那么走else的流程,所以就会按照字节来
else {
CharChunk cc = tmpNameC;
int length = bc.getLength();
cc.allocate(length, -1);
// Default encoding: fast conversion
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);
}
cc.setChars(cbuf, 0, length);
result = cc.toString();
cc.recycle();
}
return result;
}

在运行过程中可以看到, 到进入这个方法的时候,还没有乱码 :

然后是到urlDec.convert(bc);

这个方法影响不大,只是对那个java.net.URLEncod...编码的进行处理.

关键是下面部分:看上面代码中,如果 enc == null, 也就是说server.xml中没有设置URIEncoding.

那么进入了else代码段.

这一进入就完了,可以看到他的处理是按单字节作为一个字符, 于是上面的 "ni%D5%C6%B9%F1" 在它眼里就是6个字符了 .(实际上 ni掌柜 是4个字符), 所以显然就是乱码. 如下:





那么在server.xml文件中设置了URIEncoding, 比如: URIEncoding="GBK". 于是在上面代码中,就会进入下面代码段:

if (enc != null) {
//关键问题:如果这里没有指定URIEncoding的话, 那么enc是null
bc.setEncoding(enc);
result = bc.toString();
}

如下:





本文出自 “ni掌柜的IT专栏” 博客,请务必保留此出处http://nileader.blog.51cto.com/1381108/384353
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: