tomcat源码分析之getParameter(String)与getQueryString()

本文详细分析了Tomcat中getParameter和getQueryString的实现差异,揭示了为何在不同场景下可能出现乱码问题。通过源码跟踪,发现getParameter会根据服务器配置的URIEncoding解码,而getQueryString返回的是原始URL编码。问题源于客户端URL编码与服务器默认编码不一致,解决方案是正确配置服务器的URIEncoding。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文有些地方的描述对某些人来说可能比较罗嗦,但确实是自己一步步分析解决问题的思路,虽然有些地方的思考还不是很深入,主要是由于时间不是很充裕(虽然花了三天时间,但感觉还是不够),但我会在后续的博文中,结合自己遇到的实际问题或在论坛中看到的别人提出的问题,一步步的带着问题深入分析tomcat源码,这种带着问题进行源码分析的方式,比较有针对性,不至于让自己迷失在源码的汪洋之中。如果大家对博客格式或其他方面有比较好的建议,欢迎指出,非常感谢。

本次源码分析的目标是:

弄清楚org.apache.catalina.conector.RequestFacade::getQueryString()以及getParameter(String)不同及其具体实现,达到此目标即可。

引言

问题的引出是由于前些天在oschina上看到的一篇帖子http://www.oschina.net/question/820641_104356

问题分析

起初的分析思路也是受帖子作者的影响,心想出现这种情况是否是因为hashmap destroy encoding导致的,所以就google了一下hashmap encoding,得到一个比较相关的答案

http://stackoverflow.com/questions/8427488/hashmap-destroys-encoding,这篇帖子中出现的情况也比较奇怪。

程序功能描述如下:
从文件A中读取一组以空格为分隔符的的字符串,然后将这些字符串一行一行的写入到另外一个文件B中。
如文件A的格式为:
Aaa  bbbbb cdefggg …..
文件B的格式为:
Aaa
Bbbbb
Cdefgggg
….

程序代码:

01 final StringBuffer fileData = new StringBuffer(1000);
02  
03     final BufferedReader reader = new BufferedReader(
04  
05             new FileReader("fileIn.txt"));
06  
07     char[] buf = new char[1024];
08  
09     int numRead = 0;
10  
11     while ((numRead = reader.read(buf)) != -1)
12  
13     {
14  
15         final String readData = String.valueOf(buf, 0, numRead);
16  
17         fileData.append(readData);
18  
19         buf = new char[1024];
20  
21     }
22  
23     reader.close();
24  
25     String mergedContent = fileData.toString();
26  
27     mergedContent = mergedContent.replaceAll("\\<.*?>"" ");
28  
29     mergedContent = mergedContent.replaceAll("\\r\\n|\\r|\\n"" ");
30  
31     final BufferedWriter out = new BufferedWriter(
32  
33             new OutputStreamWriter(
34  
35                     new FileOutputStream("fileOut.txt")));
36  
37     final HashMap<String, String> wordsMap = new HashMap<String, String>();
38  
39     final String test[] = mergedContent.split(" ");
40  
41     for (final String string : test)
42  
43     {
44         wordsMap.put(string, string);
45  
46     }
47     for (final String string : wordsMap.values())
48  
49     {
50         out.write(string + "\n");
51  
52     }
53     out.close();

这种情况下,发现文件B中的内容为乱码,而如果将上述程序中的部分代码改为下面这样,则会得到期望的结果。

01 ...
02  
03         for (final String string : test)
04         {
05                         out.write(string + "\n");
06             //wordsMap.put(string, string);
07  
08         }
09  
10         //for (final String string : wordsMap.values())
11  
12         //{
13  
14         //  out.write(string + "\n");
15  
16         //}
17         out.close();

出现这种情况的原因,我也不是很理解,原文中关于该贴的回答,我觉得和问题没有任何关系,大多数人都在讲如何解决这个问题,而没有提到出现上述情况的原因。

经过该贴和其他一些相关帖的了解,我发现引言中提出的问题貌似和hashmapencoding没有任何关系,可能存在别的原因,于是自己写了一个简单的servlet来实践一下。

实践

首先是问题重现,我写了一个简单的servlet如下所示:

//请求的url为:http://localhost:8080/demo/1.do?addr=上海

01 @Override
02     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值