`

解析访问JSP一系列的编码解码过程

阅读更多
乱码是个让人头痛的问题...
页面的乱码,servlet中的乱码,数据库的乱码....
一个烦字了得..

解决的方法也很早就出来...不多讲...
先看看两个网址:
http://www.google.cn/search?client=aff-cs-worldbrowser&forid=1&ie=utf-8&oe=UTF-8&hl=zh-CN&q=开源

http://www.iteye.com/search?type=all&query=分页

点击看看什么效果..选中URL,再回车看看...

--------------------------------------------------------

说说从URL到servlet再到页面的一系列编码解码过程..
首先知道在JAVA中的字符都是使用unicode
其次,我们假定在页面中使用了utf-8编码,当然你还可以使用gb2312之类的...但强烈建议你使用utf-8

1.输入URL...
    此时,servlet引擎就做些事..
    把URL进行编码,按照ISO8859-1字符集编码进行转换成UNICODE,再封装到ServletRequest对象中.
    当我们使用表单的时候,post,get方式,会以页面的字符编码对表单中的内容进行,编码.这个过程有点像URLEncoder.encode()方法的效果...

2.得到URL中的参数..
    这是我们常做的,一个方法而已嘛..request.getParameter("paramName")
   这个方法的背后还有一些解码工作..
   乱码的原因有时就在此..
   getParamter方法,对URL进行解码,在servlet规范中没有明确规定解码所采用的字符集编码,它由各个servlet引擎厂商自行决定...tomcat中默认采用ISO8859-1字符集进行URL解码.
   对于post方式:可以使用request.setCharacterEncoding(),方法指定别的解码方式.
   对于get方式:
   可以使用原始的方法new String(param.getBytes("iso8859-1"),"utf-8")
这条语句在这儿的作用:
   把getParameter方法解码成的错误unicode还原成正确的编码.
怎么讲呢?这儿解释有点麻烦..
在页面中提交表单的时候,表单内容使用页面字符码utf-8编码,而getParameter默认的方法是以iso8859-1解码的,所以如果你不处理下,就会是乱码了...
ISO8859-1与unicode之间的转换是无损的..
  我们使用getBytes("iso8859-1")还原成正确的字符数组,再以utf-8编码,就得到正确的结果了..
   这个过程是这样的:
    (以utf-8编码)           getParameter以(ios8859-1)解码
URL--------------->字符数组------------------------------>UNICODE(错误)
   
   使用getBytes("iso8859-1")还原         new String(bytes,"utf-8")
UNICODE------------------------>字符数组--------------->UNICODE(正确)-            

  也可以修改server.xml
 <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" [color=red]URIEncoding="utf-8[/color]"/>


让url解码时使用utf-8.
   
   记得上面让做实验吗...选中URL,回车.此时,URL中的中文字符是以本地符编码的.就是GB2312编码..
   像javaeye的.URL中的是GB2312,而在后台处理的时候以使用的utf-8,所以就出现了乱码..google的那个, 参数中有个ie,那可能就是浏览器的编码,如果改成gb2312就不会出现乱码...在这个方面.google比baidu做得优秀..页面的编码也会根据这个参数来确定,..而baidu只是对gb2312处理了..所以从这点看,baidu还是没有走向国际化..你可以再做实验验证下..
   直接在输入URL,过程也一样
   先对URL编码,以ISO8859-1编码,getParameter解码..GB2312---->UNICODE
 

3,页面得到字符.
   在servlet中,都是unicode的编码,会以request.setCharacter()编码成字符数组.
在页面中显示时,再以contentType属性解码一下..所有这两处得一致.!

----------------------
以上就是其中的一些过程,还有一些细节...
比如在servlet中没有使用setCharacterEncoding方法,也没有使用相应的filter处理,
那么如果有URL的参数的时候,显示得使用URLEncoder.encode()编码下..在页面上的URL中才会正确显示..

   对于编码和解码,都是对称的...底层都是使用字节数组来传递,我们只要知道了这个字节数组是怎么得到的就知道怎么去处理,也知道乱码原因在哪一步...
    比如输入URL,URL中的是GB2312,先是URL编码,GB2312以ISO8859-1---->字节数组..getParameter又以ISO8859-1对字节数组解码,此时,你写上new String(p.getBytes("iso8859-1"),"utf-8")就是乱码...
写p.getBytes("iso8859-1"),"gb2312"就是正确的..
   在搜索分页的时候,下一页带的中文参数,一般都会在页面上显示得对它进行URLEncoder.encode,如果没有,就得在servlet中进行重新解码..也就是getBytes一下..
        1.在页面中不显示encode,那么在servlet中使用getBytes,重新编码.
  这是因为:URL中的UTF-8字符------(ISO8859-1)-------->字符数组-------getParameter以iso8859-1解码--------->unicode,这里的UNICODE是不正确的,它是UTF-8编码的.
   2.在页面中显示encode下,这个过程也可以在servlet中进行,encode(key,"utf-8"),在servlet中不要进行request.setCharacter(),也就是在servlet中只有iso8859-1与UNICODE间的转换...到页面的时候才涉及到本地符...

-------------------------------------------
关键点:对称的转换...底层字节数组的编码类型..
最好在页面中显示得主动URLEncoder.encode一下,更保险.
中文在ISO8859-1中没有对应的编码..
比如URLEncoder.encode("中","ISO8859-1")就不能得到正确的错误的结果..
因为这个转换是有损的,不可逆的..

-------------------------------------------
我在网站中的一些问题:
   我的网站是使用的utf-8.它是所有字符编码的超集,兼容所有字符..建议使用..
但空间服务商把tomcat/conf/server.xml中配置了URIEncode="GB2312".
  ,建议他改成UTF-8,但他又不改..很是无奈.
我的解决办法,就是在页面的主动编码使用
URLEncoder.encode(keyworks,"gb2312");

这样在URL中的都是通过GB2312编码的字符.这个语句也可以写到servlet中.
后台request.getParameter("query");就不需要处理.. 

3
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics