问题发生于,我想用tcpmon拦截页面提交数据。
由于post的数据都是经过urlencoded编码的,所以看到的数据如果是日文的话都是类似于“%8Ex%95%A5%8B%E0%8Az%8D%87%8Cv”这个样子的。
我想把它解码成原始数据,以便于调查。
于是使用了URLDecoder.decode方法进行解码,发现解码回来的数据有误
System.out.println(URLDecoder.decode("%8Ex%95%A5%8B%E0%8Az%8D%87%8Cv","windows-31j"));
输出结果为
支?金?合?
正确结果应该为
支払金額合計
于是使用
System.out.println(URLEncoder.encode("支払金額合計","windows-31j"));
把这几个字符编码了一下,得到的结果是
%8E%78%95%A5%8B%E0%8A%7A%8D%87%8C%76
和上面的比较了一下确实有些不一样
下面几个编码好像变成了字幕
%78 ->x
%7A ->z
%76 ->z
用下面代码解码一下也确实如此
System.out.println(URLDecoder.decode("%78","windows-31j"));
System.out.println(URLDecoder.decode("%7A","windows-31j"));
System.out.println(URLDecoder.decode("%76","windows-31j"));
但是问题是,为什么浏览器编码时和URLEncoder.encode编码是不一样的呢?为什么Tomcat可以正确的解码呢?
调查了一下才发现Tomcat根本不是用的URLDecoder.decode来解码的,而是用的org.apache.catalina.util.RequestUtil类。
这样解码一下发现都能得到正确的结果
System.out.println(RequestUtil.URLDecode("%8Ex%95%A5%8B%E0%8Az%8D%87%8Cv","windows-31j"));
System.out.println(RequestUtil.URLDecode("%8E%78%95%A5%8B%E0%8A%7A%8D%87%8C%76","windows-31j"));
至于为什么,查看一下两个类的源代码就一清二楚了。
至于为什么要这样做,我想是出于减少浏览器和服务器之间的传输数据量的考虑。