摘要:

  本文首先从四个方面给出了在使用JSP过程中可能出现中文乱码的情形,具体包括JSP页面中文乱码、JSP源文件中文乱码、GET 请求的请求参数为中文乱码 和 POST 请求的请求参数为中文乱码四种情形,并针对每种情形给出了相应的终极解决方案。


一. JSP页面与JSP源文件乱码

  在介绍JSP页面与JSP源文件的乱码问题前,首先我们必须对JSP页面中文乱码问题与JSP源文件中文乱码问题有一个清晰的概念,即:

  • JSP页面中文乱码问题是指用户在浏览器看到的服务器所返回的jsp页面中,中文字符不能正常显示;
  • JSP源文件中文乱码问题是指在编辑器保存JSP源文件后,中文字符不能正常显示。

    因此,这是两个不同层面的问题。接下来,我们分别解决这两个问题。


1、JSP页面乱码

  我们先在记事本中编写一个JSP程序,如下:

<!-- 示例1 -->
<%@ page language="java" import="java.util.*"%>
<html><head><title>JSP页面中文乱码</title></head><body>中国<br><%="中国" %></body>
</html>

  上面这个JSP程序是在页面显示几句中文而且标题也是中文,运行后在浏览器中显示如图所示:

              

  原因在于没有在JSP中指定 页面显示的编码,消除乱码的解决方案就是将上面代码中的page命令修改成如下所示即可:

<!-- 示例2 -->
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html><head><title>JSP页面中文乱码</title></head><body>中国<br><%="中国" %></body>
</html>

  再次运行中文正常显示,原理就是 向页面指定编码为utf-8,那么页面就会按照此编码来显示,于是乱码消失。


2、JSP源文件乱码

1). JSP源文件乱码 与 Eclipse/MyEclipse 对JSP的默认编码设置

  如果我们在Eclipse/MyEclipse中打开上面示例1的jsp源文件,由于Eclipse/MyEclipse中默认的JSP编码格式为ISO-8859-1,所以当打开由其他编辑器编辑的JSP文件时会出现乱码,如图所示:

             

  对于这个问题,我们只需要更改一下 Eclipse/MyEclipse 中对JSP的默认编码并update就可以了,修改的地方(我的MyEclipse版本为 10)如图所示:

            

  修改后,对于在Eclipse/MyEclipse所创建的任何一个JSP源文件,其默认编码方式均为 UTF-8,例如:

            


  如果不做上述修改,如果我们在Eclipse/MyEclipse中编辑的JSP中存在中文字符,那么当我们保存该页面时,会弹出以下对话框:

             

  但是,我们如果我们提前按如上步骤设置后,JSP源文件就能正常保存、编译。


2). Eclipse/MyEclipse 创建 JSP时 pageEncoding 的默认值设置

  我们在编辑的JSP文件时,尤其在包含中文字符时,一定要在page编译指令中恰当地指明 pageEncoding 的值,否则在浏览器访问该JSP页面时,其中的中文就会显示为乱码。因为一旦缺省 pageEncoding 时,其值就会被默认指定为 “iso-8859-1”,该字符集不支持中文。此外,使用 Eclipse/MyEclipse 进行开发的伙伴们都知道,这两个IDE生成的JSP模板的pageEncoding的默认值是“iso-8859-1”。为方便开发,我们可以更改Eclipse/MyEclipse生成JSP模板时pageEncoding的默认值,修改的地方(我的MyEclipse版本为10)如图所示:

            

  这样,通过以上两步的设置,当我们在 Eclipse/MyEclipse 中创建一个新的JSP文件时,该源文件在Eclipse/MyEclipse中的默认编码方式为utf-8,因此就不会导致 JSP源文件乱码;并且其 pageEncoding 的值会被自动设为“utf-8”,这就不会导致JSP页面乱码。


二. GET 请求的请求参数为中文情形

1、URL传递参数中文乱码

<!-- 请求URL示例:http://localhost:8080/Demo/request/request2.jsp?name=大将&gender=男 --><%@ page contentType="text/html; charset=utf-8" language="java"pageEncoding="utf-8" errorPage="" import="java.net.*"%>
<head>
<title>URL传递参数中文乱码</title>
</head>
<body><%! private String rawQueryString = null;  %><%// 获取name请求参数的值String name = request.getParameter("name");// 获取gender请求参数的值String gender = request.getParameter("gender");out.print("---------------------原生查询字符串-----------------------</br>");rawQueryString = request.getQueryString();out.print(rawQueryString + "</br>");%><%out.print("</br>---------------------方式一:直接打印请求参数-----------------------</br>");out.print( "名字 : " + name +"</br>");out.print( "性别 : " + gender + "</br>");%><%out.print("</br>---------------------方式二:利用String进行转码-----------------------</br>");out.print( "名字 : " + new String(name.getBytes("iso-8859-1"),"utf-8") +"</br>");out.print( "性别 : " + new String(gender.getBytes("iso-8859-1"),"utf-8") +"</br>");%><%out.print("</br>---------------------方式三:利用URLDecoder进行解码-----------------------</br>");String queryString = URLDecoder.decode(rawQueryString, "utf-8");String[] queryParams = queryString.split("&");out.print( "名字 : " + queryParams[0].split("=")[1] + "</br>");out.print( "性别 : " + queryParams[1].split("=")[1] +"</br>");%>
</body>
</html>

运行结果如下图所示:

              


2、表单提交中文乱码

  该示例由 “收集参数的表单页” 和 “表单提交参数显示页”两部分构成。

收集参数的表单页:

<%@ page contentType="text/html; charset=utf-8" language="java"pageEncoding="utf-8" errorPage=""%>
<head>
<title>收集参数的表单页</title>
</head>
<body><form id="form" action="request1.jsp" method="get">用户名:<br /> <input type="text" name="name"><hr /> 性别:<br /> 男:<input
            type="radio" name="gender" value="男"> 女:<input type="radio"name="gender" value="女"><hr /> 喜欢的颜色:<br /> 红:<input
                    type="checkbox" name="color" value="红"> 绿:<input
                        type="checkbox" name="color" value="绿"> 蓝:<input
                            type="checkbox" name="color" value="蓝"><hr /> 来自的国家:<br /><select name="country"><option value="中国">中国</option><option value="美国">美国</option><option value="俄罗斯">俄罗斯</option></select><hr /><input type="submit" value="提交"><input type="reset" value="重置"></form>
</body>
</html>

表单提交参数显示页:

<%@ page language="java" import="java.util.*,java.net.*"contentType="text/html; charset=utf-8" pageEncoding="utf-8"errorPage=""%>
<html>
<head>
<title>表单提交中文乱码</title>
</head>
<body><%! private String rawQueryString = null;  %><%/* 对于get请求,该语句对避免中文参数乱码不起任何作用 */request.setCharacterEncoding("utf-8");String name = request.getParameter("name");String gender = request.getParameter("gender");String[] color = request.getParameterValues("color");String country = request.getParameter("country");out.print("---------------------原生查询字符串-----------------------</br>");rawQueryString = request.getQueryString();if (rawQueryString != null)out.print(rawQueryString + "</br>");%><%out.print("</br>---------------------方式一:直接打印请求参数-----------------------</br>");out.print("name: " + name + "</br>");out.print("gender: " + gender + "</br>");out.print("color: ");for (String s : color) {out.println(s);}out.print("</br>");out.print("country: " + country + "</br>");%><%out.print("</br>---------------------方式二:利用String进行转码-----------------------</br>");out.print("name: " + new String(name.getBytes("ISO-8859-1"), "utf-8") + "</br>");out.print("gender: " + new String(gender.getBytes("ISO-8859-1"), "utf-8") + "</br>");out.print("color: ");for (String s : color) {out.println(new String(s.getBytes("ISO-8859-1"), "utf-8"));}out.print("</br>");out.print("country: " + new String(country.getBytes("ISO-8859-1"), "utf-8") + "</br>");%><%out.print("</br>---------------------方式三:利用URLDecoder进行解码-----------------------</br>");if (rawQueryString != null) {String queryString = URLDecoder.decode(rawQueryString, "utf-8");out.print("解码后的字符串 : " + queryString);String[] queryParams = queryString.split("&");out.print("name: " + queryParams[0].split("=")[1] + "</br>");out.print("gender: " + queryParams[1].split("=")[1] + "</br>");out.print("color: ");for (String s : queryParams) {if(s.split("=")[0].equals("color"))out.println(s.split("=")[1]);}out.print("</br>");out.print("country: " + queryParams[queryParams.length-1].split("=")[1] + "</br>");} %>
</body>
</html>

运行结果如下图所示:

            


3、GET 请求的请求参数为中文情形小结

  只要我们以GET形式提交请求,无论是以表单形式提交还是以URL形式提交,如果参数中存在中文字符,那么我们必须进行相应的转码(借助String类)或者解码(借助URLDecoder类),关于 URLDecoder 的详细介绍见我的博文《使用 URLDecoder 和 URLEncoder 对中文进行编码和解码》。特别地,有五点需要注意:

  • request.getQueryString() 所返回的原生查询字符串只适用于 GET请求 ,若对 POST请求 使用,则返回 null;

  • 利用 URLDecoder 进行解码时,必须先对原生查询字符串解码,而后获取各请求参数。如果先获取各个请求参数,再依次解码,则仍是乱码;

  • 使用String进行 转码时,往往都是先从 ISO-8859-1 格式的字符串中取出字节内容,然后再用页面相应的编码格式重新构造一个新的字符串,像本示例(new String(country.getBytes(“ISO-8859-1”), “utf-8”))中的 一样。这样就可以支持中文字符的正常取值和显示;

  • 利用 URLDecoder 进行解码时,所采用的解码字符集取决于浏览器(本文所有实验都是基于 Google Chrome 的)。对于中文环境而言,一般要么是 UTF-8,要么是 GBK ;

  • 对于 GET请求,语句 request.setCharacterEncoding(“utf-8”); 对避免中文参数乱码起不到任何作用。

      
     经过上面的处理,GET请求的中文参数乱码问题已经得到解决。但是如果上面的表单中的输入项不止几项,那么每个输入项都需要进行编码转换,那样就很麻烦了。这时,我们就用到了大名鼎鼎的过滤器 filter 了。


三. POST 请求的请求参数为中文情形

  一般地,我们以POST形式提交请求,都是以表单形式进行并且 form 的 method 属性为 post。下面的示例对上面的示例做了一些修改,也由 “收集参数的表单页” 和 “表单提交参数显示页” 两部分构成:

收集参数的表单页:

<%@ page contentType="text/html; charset=utf-8" language="java"pageEncoding="utf-8" errorPage=""%>
<head>
<title>收集参数的表单页</title>
</head>
<body><form id="form" action="request1.jsp" method="post">用户名:<br /> <input type="text" name="name"><hr /> 性别:<br /> 男:<input
            type="radio" name="gender" value="男"> 女:<input type="radio"name="gender" value="女"><hr /> 喜欢的颜色:<br /> 红:<input
                    type="checkbox" name="color" value="红"> 绿:<input
                        type="checkbox" name="color" value="绿"> 蓝:<input
                            type="checkbox" name="color" value="蓝"><hr /> 来自的国家:<br /><select name="country"><option value="中国">中国</option><option value="美国">美国</option><option value="俄罗斯">俄罗斯</option></select><hr /><input type="submit" value="提交"><input type="reset" value="重置"></form>
</body>
</html>

表单提交参数显示页:

<%@ page language="java" import="java.util.*,java.net.*"contentType="text/html; charset=utf-8" pageEncoding="utf-8"errorPage=""%>
<html>
<head>
<title>表单提交中文乱码</title>
</head>
<body><%! private String rawQueryString = null;  %><%/* 对于post请求,该语句为避免中文参数乱码起到关键作用 */request.setCharacterEncoding("utf-8");String name = request.getParameter("name");String gender = request.getParameter("gender");String[] color = request.getParameterValues("color");String country = request.getParameter("country");out.print("---------------------原生查询字符串-----------------------</br>");rawQueryString = request.getQueryString();out.print(rawQueryString + "</br>");%><%out.print("</br>---------------------方式一:直接打印请求参数-----------------------</br>");out.print("name: " + name + "</br>");out.print("gender: " + gender + "</br>");out.print("color: ");for (String s : color) {out.println(s);}out.print("</br>");out.print("country: " + country + "</br>");%><%out.print("</br>---------------------方式二:利用String进行转码-----------------------</br>");out.print("name: " + new String(name.getBytes("ISO-8859-1"), "utf-8") + "</br>");out.print("gender: " + new String(gender.getBytes("ISO-8859-1"), "utf-8") + "</br>");out.print("color: ");for (String s : color) {out.println(new String(s.getBytes("ISO-8859-1"), "utf-8"));}out.print("</br>");out.print("country: " + new String(country.getBytes("ISO-8859-1"), "utf-8") + "</br>");%><%out.print("</br>---------------------方式三:利用URLDecoder进行解码-----------------------</br>");if (rawQueryString != null) {String queryString = URLDecoder.decode(rawQueryString, "utf-8");out.print("解码后的字符串 : " + queryString);String[] queryParams = queryString.split("&");out.print("name: " + queryParams[0].split("=")[1] + "</br>");out.print("gender: " + queryParams[1].split("=")[1] + "</br>");out.print("color: ");for (String s : queryParams) {if(s.split("=")[0].equals("color"))out.println(s.split("=")[1]);}out.print("</br>");out.print("country: " + queryParams[queryParams.length-1].split("=")[1] + "</br>");} %>
</body>
</html>

运行结果如下图所示:

            


  根据上面运行结果,我们知道: 对于POST请求,若其请求参数包含中文字符,那么我们只需在解析请求参数前加一句如下的代码即可。需要注意的是,这种方式对 Get请求起不到任何作用。此外,由于我们对请求已经重新编码,所以已经不需要使用 String类 再进行转码,否则画蛇添足。最后,对于 POST请求,request.getQueryString(); 返回的查询字符串为 null。

request.setCharacterEncoding("utf-8");

四. 总结

  本文首先从四个方面给出了在使用JSP过程中可能出现中文乱码的情形,具体包括JSP页面中文乱码、JSP源文件中文乱码、GET 请求的请求参数为中文乱码 和POST 请求的请求参数为中文乱码四种情形,并针对每种情形给出了相应的终极解决方案。

  更多关于 JSP技术的细节见我的其他两篇博客: 《Java Web基础 — Jsp 综述(上)》 和 《Java Web基础 — Jsp 综述(下)》。

  更多关于 JSP中文乱码问题的解决方案见我的另一篇博客:《 JSP中文乱码问题终极解决方案(上)》。


引用

JSP中文乱码问题终极解决方案

JSP中文乱码问题终极解决方案(下)相关推荐

  1. JSP中文乱码问题终极解决方案(上)

    摘要: 本文首先介绍了一个JSP的源文件执行过程,即需要经过三个阶段,两次编码,才能完成一次完整的输出.特别需要注意的是,在这个过程中,编码问题贯穿始终.我们知道在JSP/Servlet中,主要有以下 ...

  2. JSP中文乱码问题终极解决方案(转)

    JSP中文乱码问题终极解决方案 http://www.cnblogs.com/beijiguangyong/archive/2012/03/31/2437124.html 在介绍方法之前我们首先应该清 ...

  3. JSP中文乱码问题终极解决方案

    在介绍方法之前我们首先应该清楚具体的问题有哪些,笔者在本博客当中论述的JSP中文乱码问题有如下几个方面:页面乱码.参数乱码.表单乱码.源文件乱码.下面来逐一解决其中的乱码问题. 一.JSP页面中文乱码 ...

  4. vim、gvim在windows下中文乱码的终极解决方案

    From: http://www.liuhuadong.com/archives/68/index.html vim.gvim在windows下中文乱码的终极解决方案 在windows下vim的中文字 ...

  5. Java中文jsp页面被转码了_JSP中文乱码问题终极解决方案

    转载自: http://www.cnblogs.com/beijiguangyong/ http://www.cnblogs.com/beijiguangyong/archive/2012/03/31 ...

  6. Tomcat 中 jsp 中文乱码显示处理解决方案

    JSP 中文乱码处理解决方案 初学JSP,尤其是Tomcat环境,经常会因为中文汉字字符集设置问题导致中文乱码,本文就这一问题提出解决方案,解决中文乱码问题,供各位参考,我采用的方案是统一字符集至UT ...

  7. gvim在windows下中文乱码的终极解决方案

    打开vim的配置文件,位置在/etc/vim/vimrc 在其中加入 set encoding=utf-8 set fileencodings=utf-8,gb2312,gbk,gb18030 set ...

  8. python graphviz中文乱码_graphviz画决策树图中文乱码问题终极解决方案

    大家在画决策树的过程中,一定非常希望能画出带有中文特征名称或类别名称的决策树.但我们直接用graphviz画图时,中文却会出现乱码.如下图所示,相信大家都遇见过:在红酒数据集中,将feature_na ...

  9. JSP中文乱码解决方案了解和TOMCAT中文乱码解决

    java 中文乱码终极解决方案 首先,确保你的数据库是支持中文的.把数据库的编码方式设置能支持中文的,如GB2132,utf-8等,而且经过测试后确实能写入中文且正常显示.这样就就保证了数据库确实是支 ...

  10. jsp mysql中文乱码,jsp中文乱码 jsp mysql 乱码的解决方法

    jsp中文乱码 jsp mysql 乱码的解决方法 jsp中文乱码 jsp mysql 乱码要servlet里面支持中文的方法: 在dopost或者doget的第一句加上: request.setCh ...

最新文章

  1. cadence原理图封装pin名称重复_硬件工程师必备技巧--如何快速制作PCB封装
  2. 用YII实现多重查询(基于tag)
  3. android复杂列表滑动卡顿,Android 列表滑动性能优化总结
  4. ES6——class和继承,保护对象
  5. 算法——X^3+Y^3+Z^3=XYZ(水仙花数)
  6. 如何进入mysql命令界面
  7. 零和博弈 (社会学概念)
  8. 使用construct3制作Mario游戏
  9. 2020算法提前批_2020年网页设计的极大沉默,算法可理解性的ni灭
  10. pdf怎么删除其中一页与添加新页面
  11. cc2530 按键中断实验——按键控制LED灯的亮灭
  12. HTTP请求服务器 statuscode的状态码说明 (statuscode==500)
  13. 华为BGP协议基础配置
  14. 第4章 JavaScript表达式与运算符
  15. 数字签名,盲签名,环签名,群签名
  16. bigquery_Google的BigQuery提供免费访问GDELT的权限
  17. 视频教程-Access2013数据库入门教程-Office/WPS
  18. 周杰伦2014魔天伦世界巡回演唱会北京站
  19. 如何查看计算机系统管理日志,怎么查看电脑系统日志
  20. python发红包小程序_小程序红包雨

热门文章

  1. 找电影最强攻略,最全资源站
  2. 上百套HTML5登录页面模板
  3. 判断浏览器内核是否是IE8及其以下
  4. python三维建模可以加 贴图_三维模型都有哪些绘制贴图的软件??
  5. bat批处理注册dll
  6. linux下用套接字抓arp包,TCP抓包-linux
  7. JS实现随机切换姓名与头像
  8. 机械臂视觉抓取仿真,vrep与matlab联合仿真示例
  9. c语言课程设计 工资管理系统
  10. 用VBA制作Excel单选框和多选框