Jsp中几个编码问题的解析

来源:互联网 发布:知乎的收藏夹 编辑:程序博客网 时间:2024/05/23 12:15

 

 

<!-- /* Font Definitions */ @font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;}@font-face{font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;mso-font-charset:1;mso-generic-font-family:roman;mso-font-format:other;mso-font-pitch:variable;mso-font-signature:0 0 0 0 0 0;}@font-face{font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;mso-font-charset:0;mso-generic-font-family:swiss;mso-font-pitch:variable;mso-font-signature:-1610611985 1073750139 0 0 159 0;}@font-face{font-family:"/@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-unhide:no;mso-style-qformat:yes;mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;mso-pagination:none;font-size:10.5pt;mso-bidi-font-size:11.0pt;font-family:"Calibri","sans-serif";mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:"Times New Roman";mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;}p{mso-style-noshow:yes;mso-style-priority:99;mso-margin-top-alt:auto;margin-right:0cm;mso-margin-bottom-alt:auto;margin-left:0cm;mso-pagination:widow-orphan;font-size:12.0pt;font-family:宋体;mso-bidi-font-family:宋体;}.MsoChpDefault{mso-style-type:export-only;mso-default-props:yes;mso-bidi-font-family:"Times New Roman";mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page Section1{size:595.3pt 841.9pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:42.55pt;mso-footer-margin:49.6pt;mso-paper-source:0;layout-grid:15.6pt;}div.Section1{page:Section1;}-->

 

首先,说说JSP/Servlet中的几个编码的作用。

JSP/Servlet中主要有以下几个地方可以设置编 码,pageEncoding="UTF-8"contentType="text/html;charset=UTF-8" request.setCharacterEncoding("UTF-8") response.setCharacterEncoding("UTF-8"),其中前两个只能用于JSP中,而后两个可以用于JSPServlet中。

1pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码。

众所周知,JSP在服务器上是要先被编译成Servlet的。 pageEncoding="UTF-8"的作用就是告诉JSP编译器在将JSP文件编译成Servlet时使用的编码。通常,在JSP内部定义的字符串 (直接在JSP中定义,而不是从浏览器提交的数据)出现乱码时,很多都是由于该参数设置错误引起的。例如,你的JSP文件是以GBK为编码保存的,而在JSP中却指定pageEncoding="UTF-8",就会引起JSP内部定义的字符串为乱码。

另外,该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。

2contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。

在不使用response.setCharacterEncoding方法时,用该参数指定对服务器响应进行重新编码的编码。

3request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。

该方法用来指定对浏览器发送来的数据进行重新编码(或者称为解码)时,使用的编码。

4response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。

服务器在将数据发送到浏览器前,对数据进行重新编码时,使用的就是该编码。

其次,要说一说浏览器是怎么样对接收和发送的数据进行编码的

response.setCharacterEncoding("UTF-8")的 作用是指定对服务器响应进行重新编码的编码。同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。所以在无论你在JSP中设置response.setCharacterEncoding("UTF-8")或者response.setCharacterEncoding("GBK"),浏览器均能正确显示中文(前提是你发送到浏览器的数据编码是正确的,比如正确设置了pageEncoding参数等)。读者可以做个实验,在JSP中设置response.setCharacterEncoding("UTF- 8"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是" UnicodeUTF-8",而在在JSP中设置response.setCharacterEncoding("GBK"),在IE中显示该页面 时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是"简体中文(GB2312"

浏览器在发送数据时,对URL和参数会进行URL编码,对参数中的中文,浏览器也是使response.setCharacterEncoding参数来进行URL编码的。以百度和GOOGLE为例,如果你在百度中搜索"汉字",百度 会将其编码为"%BA%BA%D7%D6"。而在GOOGLE中搜索"汉字"GOOGLE会将其编码为"%E6%B1%89%E5%AD%97",这是因为百度的response.setCharacterEncoding参数为GBK,而GOOGLE的的 response.setCharacterEncoding参数为UTF-8

 

 

 

 

首先URL在地址栏中的解码方式是Unicode

JSP

浏览器接受和回送的编解码方式(相同)是根据服务器response.setCharacterEncoding参数,百度的参数是GBK,而Google的参数是Unicode,所以搜索关键字为汉字时Google时地址栏可以显示搜索的关键字,而Baidu却显示乱码,因为URL在地址栏中的解码方式是Unicode而不是GBK

服务器发送数据的编码方式是按照如下顺序进行response.setCharacterEncoding,contentTypepageEncoding

接受数据分三种情况:URL传值,PostGet方式

无论使用那种方式提交,如果参数中包含中文,浏览器都会使用当前浏览器编码对其进行URL编码。

对于表单中POST方式提交的数据,只要在接收数据的JSP中正确request.setCharacterEncoding参数,即将对客户端请求进行重新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。有写读者可能会问,那如何得到浏览器编码呢?上面我们提过了,在默认请情况下,浏览器编码就是你在响应该请求的JSP页面中 response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在获得数据的JSP页面中 request.setCharacterEncoding要和生成提交该表单的JSP页面的response.setCharacterEncoding设置成相同的值。

对于URL提交的数据表单中GET方式提交的数据,在接收数据的JSP中设置request.setCharacterEncoding参数是不行的,因为在Tomcat5.0中,默认情况下使用ISO-8859-1URL提交的数据和表单中GET方式提交的数据进行重新编码(解码),而不使用该参数对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码)。要解决该问题,应该在Tomcat的配置文件的Connector标签中设置useBodyEncodingForURI或者URIEncoding属性,其中 useBodyEncodingForURI参数表示是否用request.setCharacterEncoding参数对URL提交的数据和表单中 GET方式提交的数据进行重新编码,在默认情况下,该参数为falseTomcat4.0中该参数默认为true);URIEncoding参数指定对所有GET方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编码。URIEncoding useBodyEncodingForURI区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新编码(解码),而 useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新 编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改URIEncoding 参数为浏览器编码或者修改useBodyEncodingForURItrue,并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码

 

下面总结下,以Tomcat5.0WEB服务器时,如何防止中文乱码。

1、对于同一个应用,最好统一编码,推荐为UTF-8,当然GBK也可以。

2、正确设置JSPpageEncoding参数

3、在所有的JSP/Servlet中设置contentType="text/html;charset=UTF-8"response.setCharacterEncoding("UTF-8"),从而间接实现对浏览器编码的设置。

4、对于请求,可以使用过滤器或者在每个JSP/Servlet中设置request.setCharacterEncoding("UTF-8")。同时,要修改Tomcat的默认配置,推荐将useBodyEncodingForURI参数设置为true,也可以将URIEncoding参数设置为UTF-8(有可能影响其他应用,所以不推荐)。

 

1.名词解释及其作用
    1. contentType: <%@ page contentType="text/html;charset=UTF-8"%>
    2. pageEncoding:<%@ pagepageEncoding="UTF-8"%>
    3. html
页面charset:<META http-equiv="Content-Type"content="text/html; charset=UTF-8">
    4.setCharacterEncoding:request.setCharacterEncoding(),response.setCharacterEncoding()
    5. setContentType:response.setContentType()
    6. setHeader: response.setHeader()
    7. jsp
页面编码: jsp文件本身的编码
    8. web
页面显示编码:jsp的输出流在浏览器中显示的编码
    9. web
页面输入编码: 输入框输入的字体编码
    10. web
服务器输入的请求流: web Server相应浏览器的请求数据
    11. web
服务器输出的响应流: web Server相应浏览器的输出数据
2.
他们之间的相互影响和作用域,以及先后作用顺序
    1. pageEncoding:
只是指明了 JSP 页面本身的编码格式,跟页面显示的编码没有关系;
   
容器在读取(文件)或者(数据库)或者(字符串常量)时将起转化为内部使用的 Unicode,而页面显示的时候将
   
内部的Unicode转换为contentType指定的编码后显示页面内容;
   
如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,
   
否则就由contentType属性中的charset决定,如果charset也不存在,JSP页面的字符编码方式就采用
   
默认的ISO-8859-1
    2. contentType:
指定了MIME类型和JSP页面回应时的字符编码方式。MIME类型的默认值是“text/html”;
   
字符编码方式的默认值是“ISO-8859-1”. MIME类型和字符编码方式由分号隔开;
    3. pageEncoding
contentType的关系:
        1. pageEncoding
的内容只是用于jsp输出时的编码,不会作为header发出去的; 是告诉web Server
            jsp
页面按照什么编码输出,web服务器输出的响应流的编码;
       2.
第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译
           
成统一的UTF-8JAVA源码(即.java.
       3.
第二阶段是由JAVACJAVA源码至javabyteCode的编译,不论JSP编写时候用的是什么编码方案,
           
经过这个阶段的结果全部是UTF-8encodingjava源码.JAVACUTF-8encoding读取
            java
源码,编译成UTF-8encoding的二进制码(即.class),这是JVM对常数字串在二进制码
           
javaencoding)内表达的规范.
       4.
第三阶段是Tomcat(或其的applicationcontainer)载入和执行阶段二的来的JAVA二进制码,
           
输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效   
    4.
contentType效果一样的设置方式还有 html页面charset, response.setCharacterEncoding(),
       response.setContentType(),response.setHeader(); response.setContentType(),
        response.setHeader();
优先级最好,其次是response.setCharacterEncoding();再者是
        <%@page contentType="text/html;chareset=gbk"%>,
最后是<meta http-equiv="content-type"
        content="text/html;charset=gb2312" />.
    5. web
页面输入编码: 在设置页面编码<%@page contentType="text/html; chareset=gbk"%>的同时,也       就指定了页面的输入编码;
       
如果页面的显示被设置为UTF-8,那么用户所有的页面输入都会按照 UTF-8 编码; 服务器端程序在读
       
取表单输入之前要设定输入编码;
       
表单被提交后,浏览器会将表单字段值转换为指定字符集对应的字节值,然后根据 HTTP 标准 URL
       
编码方案对结果字节进行编码.但是页面需要告诉服务器当前页面的编码方式;
        request.setCharacterEncoding(),
能修改Serverlet获取请求的编码,response.setCharacterEncoding(),
       
能修改Serverlet返回结果的编码.

原创粉丝点击