摘要:
本文首先从四个方面给出了在使用 JSP 过程中可能出现中文乱码的情形,具体包括 JSP 页面中文乱码、JSP 源文件中文乱码、GET 请求的请求参数为中文乱码 和 POST 请求的请求参数为中文乱码四种情形,并针对每种情形给出了相应的终极解决方案。
在介绍 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 页面乱码。
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=""%>
- <%! 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>");
- }
- %>
运行结果如下图所示:
3、GET 请求的请求参数为中文情形小结
只要我们以 GET 形式提交请求,无论是以表单形式提交还是以 URL 形式提交,如果参数中存在中文字符,那么我们必须进行相应的转码(借助 String 类)或者解码(借助 URLDecoder 类),关于 URLDecoder 的详细介绍见我的博文。特别地,有五点需要注意:
一般地,我们以 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=""%>
- <%! 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>");
- }
- %>
运行结果如下图所示:
根据上面运行结果,我们知道: 对于 POST 请求,若其请求参数包含中文字符,那么我们只需在解析请求参数前加一句如下的代码即可。需要注意的是,这种方式对 Get 请求起不到任何作用。此外,由于我们对请求已经重新编码,所以已经不需要使用 String 类 再进行转码,否则画蛇添足。最后,对于 POST 请求,request.getQueryString(); 返回的查询字符串为 null。
- request.setCharacterEncoding("utf-8");
本文首先从四个方面给出了在使用 JSP 过程中可能出现中文乱码的情形,具体包括 JSP 页面中文乱码、JSP 源文件中文乱码、GET 请求的请求参数为中文乱码 和 POST 请求的请求参数为中文乱码四种情形,并针对每种情形给出了相应的终极解决方案。
更多关于 JSP 技术的细节见我的其他两篇博客: 和 。
更多关于 JSP 中文乱码问题的解决方案见我的另一篇博客:。
来源: http://www.bubuko.com/infodetail-1964059.html