转自:http://janwer.iteye.com/blog/150226

  首先,说说 JSP/Servlet 中的几个编码的作用
  在 JSP/Servlet 中主要有以下几种设置编码的方式:

    1. pageEncoding ="UTF-8"(JSP)
    2. contentType = "text/html;charset=UTF-8"(JSP)
    3. request.setCharacterEncoding("UTF-8")(JSP,Servlet)
    4. response.setCharacterEncoding("UTF-8")(JSP,Servlet)

  其中前两个只能用于JSP 中,而后两个可以用于 JSP 和 Servlet 中。
  1、pageEncoding="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 方法时,指定对服务器响应进行重新编码的编码。
  2、contentType="text/html;charset=UTF-8" 的作用是指定对服务器响应进行重新编码的编码
  在不使用 response.setCharacterEncoding 方法时,用该参数指定对服务器响应进行重新编码的编码。

  3、 request.setCharacterEncoding("UTF-8") 的作用是设置对“客户端请求”进行重新编码的编码。
  该方法用来指定对浏览器发送来的数据进行重新编码(或者称为解码)时,使用的编码。
  4、 response.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)" 中可以查看到是 " Unicode(UTF-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 。
  浏览器在接收服务器数据和发送数据到服务器时所使用的编码是相同的,默认情况下均为 JSP 页面的 response.setCharacterEncoding 参数(或者 contentType 和 pageEncoding 参数),我们称其为浏览器编码。当然,在IE中可以修改浏览器编码(在IE的菜单中选择" 查看(V)--> 编码(D)" 中修改),但通常情况下,修改该参数会使原本正确的页面中出现乱码。一个有趣的例子是,在 IE 中浏览 GOOGLE 的主页时,将浏览器编码修改为"简体中文(GB2312)" ,此时,页面上的中文会变成乱码,不理它,在文本框中输入"汉字",提交,GOOGLE 会将其编码为"%BA%BA%D7%D6" ,可见,浏览器在对中文进行URL 编码时,使用的就是浏览器编码。

  弄清了浏览器是在接收和发送数据时,是如何对数据进行编码的了,再来看看服务器是在接收和发送数据时,是如何对数据进行编码的。
  对于发送数据,服务器按照response.setCharacterEncoding—>contentType—>pageEncoding 的优先顺序,对要发送的数据进行编码。
  对于接收数据,要分三种情况。一种是浏览器直接用URL提交的数据,另外两种是用表单的GET 和 POST 方式提交的数据。
  因为各种 WEB 服务器对这三种方式的处理也不相同,所以我们以 Tomcat5.0 为例。
  无论使用那种方式提交,如果参数中包含中文,浏览器都会使用当前浏览器编码对其进行 URL 编码。
  对于表单中 POST 方式提交的数据,只要在接收数据的 JSP 中正确request.setCharacterEncoding 参数,即将对客户端请求进行重新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。有人可能会问,那如何得到浏览器编码呢?上面提过了,在默认请情况下,浏览器编码就是你在响应该请求的 JSP 页面中response.setCharacterEncoding 设置的值。所以对于 POST 表单提交的数据,在获得数据的 JSP 页面中 request.setCharacterEncoding 要和生成提交该表单的JSP页面的 response.setCharacterEncoding 设置成相同的值。
  对于 URL 提交的数据和表单中 GET 方式提交的数据,在接收数据的 JSP 中设置 request.setCharacterEncoding 参数是不行的,因为在 Tomcat5.0 中,默认情况下使用ISO-8859-1 对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码(解码),而不使用该参数对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码(解码)。要解决该问题,应该在 Tomcat 的配置文件的 Connector 标签中设置useBodyEncodingForURI 或者 URIEncoding 属性,其中 useBodyEncodingForURI 参数表示是否用 request.setCharacterEncoding 参数对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码,在默认情况下,该参数为 false (Tomcat4.0 中该参数默认为true );URIEncoding 参数指定对所有 GET 方式请求(包括 URL 提交的数据和表单中 GET 方式提交的数据)进行统一的重新编码(解码)的编码。URIEncoding 和 useBodyEncodingForURI 区别是,URIEncoding 是对所有 GET 方式的请求的数据进行统一的重新编码(解码),而 useBodyEncodingForURI 则是根据响应该请求的页面的request.setCharacterEncoding 参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于 URL 提交的数据和表单中 GET 方式提交的数据,可以修改 URIEncoding 参数为浏览器编码或者修改 useBodyEncodingForURI 为true ,并且在获得数据的 JSP 页面中 request.setCharacterEncoding 参数设置成浏览器编码。

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

  1. 对于同一个应用,最好统一编码,推荐为 UTF-8 ,当然 GBK 也可以。
  2. 正确设置 JSP 的 pageEncoding 参数
  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 (有可能影响其他应用,所以不推荐.)。

JSP/Servlet的编码原理的更多相关文章

  1. servlet的编码原理

    编码问题: 在介绍编码问题前,先介绍一下java平台(JVM)上的编码转化情况.首先要说明的一点,在JVM中,即java平台上,运行的程序一定都是Unicode编码方式的.对于代码中的字符串常量,根据 ...

  2. jsp/servlet编码原理

    转自:http://janwer.iteye.com/blog/150226 首先,说说 JSP/Servlet 中的几个编码的作用 在 JSP/Servlet 中主要有以下几种设置编码的方式: pa ...

  3. jsp/servlet中的编码问题

    首先声明以下只是我个人的看法,有部分观点与网上人云亦云的观点不一样,不过凡事必恭亲,我还是相信自己测试的结果 推荐一个很好地URL编码详解http://www.ruanyifeng.com/blog/ ...

  4. JSP/Servlet基础语法

    相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp ...

  5. JSP/Servlet 中的汉字编码问题

    JSP/Servlet 中的汉字编码问题 1.问题的起源 每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的 ASCII,中国的 GB2312 -80,日本的 JIS 等,作为该国家/区 ...

  6. 第二章.JSP/Servlet及相关技术详解

    JSP的4种基本语法: 1.JSP注释: <%-- JSP注释部分 --%> 2.JSP声明: <%! //声明一个整型变量 public int count; //声明一个方法 p ...

  7. JSP/Servlet Web 学习笔记 DayFour

    Servlet概述 Servelt是使用Java Servlet应用程序接口及相关类和方法的Java程序. Servlet是用Java编写的Server端程序,它与协议和平台无关.Servlet运行于 ...

  8. jsp+servlet和ajex中遇到的问题

    软件杯的时候,我们的项目需要在手机端运行,由于本身的这个项目我们使用jsp+servlet做的一个项目,所以我们利用ajex,把eclipse作为后台运行tomcat8,,在hbuilder用weba ...

  9. JS.中文乱码,Jsp\Servlet端的解决办法

    JS.中文乱码,Jsp\Servlet端的解决办法 2010-03-08 15:18:21|  分类: Extjs |  标签:encodeuricomponent  乱码  urldecoder   ...

随机推荐

  1. SQL Server 流程控制

    流程控制语句: BEGIN ... END WAITFOR GOTO WHILE IF ... ELSE BREAK RETURN CONTINURE   1.BEGIN ... END BEGIN ...

  2. poj 2403

    http://poj.org/problem?id=2403 题意:就是给你m个单词,以及n段对话.每一个单词都有所对应的价值.求对话中的价值总和 题解:很简单,就是用单词和价值对应起来,然后再寻找就 ...

  3. 【转】你可能不知道的Shell

    本文转自http://coolshell.cn/articles/8619.html,只摘取了其中的一部分. 再分享一些可能你不知道的shell用法和脚本,简单&强大! 在阅读以下部分前,强烈 ...

  4. 使用Java中File类批量创建文件和批量修改文件名

    批量创建文件 int cont = 1; String s = "E:\\学习资料\\Java笔记-"; while(cont<100){ File f = new File ...

  5. JS 异步加载的方法

    (1) defer,只支持IE : <script type="text/javascript" defer="defer"> </scrip ...

  6. 用户登录流程详解 +volley(StringRequest)

    在实习期间由于要求使用volley,所以第一次开始接触volley,从一开始的迷茫陌生,到疯狂的查找各种资料,通过在项目中用到的实际问题,我想做一些总结,所以写了这篇文章.下面我将介绍我理解的用户登录 ...

  7. 在CMD窗口中使用javac和java命令进行编译和执行带有包名的具有继承关系的类

    一.背景 最近在使用记事本编写带有包名并且有继承关系的java代码并运行时发现出现了很多错误,经过努力一一被解决,今天我们来看一下会遇见哪些问题,并给出解决办法. 二.测试过程 1.父类代码 pack ...

  8. [Android Pro] Android 性能分析工具dumpsys的使用

    reference to : http://www.open-open.com/lib/view/open1405061994872.html Android提供的dumpsys工具可以用于查看感兴趣 ...

  9. 【Mongodb】3.X 配置身份验证

    配置身份验证详解: 开启认证: 启动MongoDB./mongodb --syslog --fork --port 20000  --auth 1.如果不添加参数:auth,表明用默认的root的权限 ...

  10. c语言字符集

    一.字符常量 'A', 'B','\n','\'','1' 二.字符类型变量的赋值 char c1='A'; char c2='b'; char c3=65; c2='\''; c2='\n'; 三. ...