欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

jsp 编码问题

程序员文章站 2023-11-10 14:16:28
使用Tomcat进行JSP开发最头疼的莫过于中文乱码问题了,总结Tomcat乱码问题出现的原因必须明白以下几点:   1.Tomcat一般总是默认使用ISO-8859...

使用Tomcat进行JSP开发最头疼的莫过于中文乱码问题了,总结Tomcat乱码问题出现的原因必须明白以下几点:

 

1.Tomcat一般总是默认使用ISO-8859-1作为字符编码方式的。所以,除非你在Servlet中使用了request.setCharacterEncoding("编码方式");指定了特殊的编码方式,否则Tomcat默认使用ISO-8859-1的编码方式。

 

2.在JSP页面中pageEncoding和charset和含义是不同的。pageEncoding是指页面的编码格式(请记住!,十分重要~,与显示无关),也就是说无论你JSP里的pageEncoding采用什么方式,如果出现中文乱码,原因不在于pageEncoding的所指定的编码方式不对,而在于charset的属性不对。charset是负责JSP页面中的字符按什么编码方式显示。pageEncoding只负责页面的编码格式,而后JAVA虚拟机负责按照pageEncoding指定的编码转换成Unicode编码的字节码文件。(也就是说,无论你pageEncoding指定什么方式,最终都是转换成了Unicode编码。)另外请大家注意,如果从客户端提交的用户请求里的中文也是使用pageEncoding方式编码的。也就是说,在Servlet中request.getParameter("参数");Tomcat默认是使用ISO-8859-1方式去读取的,但实际里面的字符编码方式应该是JSP页面pageEncoding所指定的方式。除非用户自己加上request.setCharacterEncoding("编码方式");

 

3.明白pageEncoding和charset之间的关系。一般而言,如果页面里指定了pageEncoding的方式也就是说,比如:<%@page language="java" import="java.util.*" pageEncoding="GBK"%>这句话,而没有指定charset的话,那么页面默认是按照charset=ISO-8859-1编码方式显示字符,按照pageEncoding="GBK"方式进行页面的编码。如果你的JSP页面里面没有指定pageEncoding方式,而只是说明了charset的话,比如:

<%@ pagecontentType="text/html;charset=utf-8"%>这句话,那么JSP默认是按照pageEncoding="utf-8"进行页面编码的,字符集按照charset=utf-8"显示。

 

4.使用request.setCharacterEncoding("编码方式");注意:request.setCharacterEncoding()仅仅对POST提交方式起作用,对于GET方式提交还是会出现乱码问题。要解决GET提交中文的乱码问题,可以在Server.xml的<Connector port="8888" protocol="HTTP/1.1"
 
             connectionTimeout="20000"
              redirectPort="8443" />

加入:URIEncoding="utf-8" useBodyEncodingForURI="true"

另外,request.setCharacterEncoding()这句话一定要放在要读取的第一参数之前调用。否则也不起作用了!!

 

下来我们看一个小例子:

  在index.jsp页面中,指定pageEncoding方式:

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

<%@ page language="java" import="java.util.*"pageEncoding="GBK" %>

<html>
  <head>
   <basehref="<%=basePath%>">
 
   <title>My JSP 'index.jsp' startingpage</title>
 
<meta http-equiv="pragma"content="no-cache">
<meta http-equiv="cache-control"content="no-cache">
<meta http-equiv="expires"content="0"> 
<meta http-equiv="keywords"content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is mypage">
<!--
<link rel="stylesheet" type="text/css"href="styles.css">
-->

  </head>

  <body>
    <form action=servlet/Loginmethod=post>
      用户名:<input type=text name="username"size=20><br>
      密码:<input type="password" name="password"size=20><br>
      <input type=submitname="submit">
  </form>
  </body>
</html>
-------------------------------------------------------------

在Login.java Servlet源文件中:

public void doPost(HttpServletRequest request, HttpServletResponseresponse)
   throws ServletException,IOException {

 
  PrintWriter out = response.getWriter();
 out.print("<H>welcome you comehere!</H>");
 out.print("<br>");
 out.println(request.getParameter("username"));
 out.print("<br>");
 out.println(request.getParameter("password"));
 out.print("<br>");
  out.flush();
 System.out.println(response.getCharacterEncoding());
  out.close();
}

当输入中文的用户名,调用Login Servlet后,结果能正常显示中文,读者看到这里似乎感到很奇怪。

因为,在LoginServlet中并没有使用request.setCharacterEncoding("编码方式");指定特点的编码方式,也就是说Tomcat默认是使用ISO-8859-1的方式,怎么能正常显示中文了呢?问题出在IE浏览器上,请大家注意!因为,大家默认使用的都是中文IE浏览器,所以中文IE浏览器默认使用的字符集是charset=GBK,再请大家注意了,在上面这段LoginServlet代码中并没有指定response.setContentType("text/html;charset=GBK");这样的语句,也就是说IE浏览器认为,既然用户自己没有指定字符集,那么就使用默认的字符集,也就是默认使用了charset=GBK,

所以你所看到的中文显示,是IE浏览器默默帮你转换了,从ISO-8859-1到GBK的转换,也就是说IE浏览器帮你做了这么一句话:

out.println(newString(request.getParameter("username").getBytes("ISO-8859-1"),"gbk"));

再请大家注意,如果你在Login Servlet原码中加入了response.setContentType("text/html;charset=GBK");那么你就画蛇添足了,反而起到不好的效果,因为IE浏览器认为用户自己已经指定了特定的字符集方式,而且就是charset=GBK方式,所以就不需要从ISO-8859-1到GBK的转换,因为IE浏览认为你页面里的字符就应该是GBK编码方式的,但是其实不然,是ISO-8859-1方式的,所以反而显示的中文乱码了。

 

下来,我们把上面的小例子改一下:index.jsp页面中只指定charset方式:

<%@ pagecontentType="text/html;charset=utf-8"%>

<html>
  <head>
   <basehref="<%=basePath%>">
 
   <title>My JSP 'index.jsp' startingpage</title>
 
<meta http-equiv="pragma"content="no-cache">
<meta http-equiv="cache-control"content="no-cache">
<meta http-equiv="expires"content="0"> 
<meta http-equiv="keywords"content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is mypage">
<!--
<link rel="stylesheet" type="text/css"href="styles.css">
-->

  </head>

  <body>
    <form action=servlet/Loginmethod=post>
      用户名:<input type=text name="username"size=20><br>
      密码:<input type="password" name="password"size=20><br>
      <input type=submitname="submit">
  </form>
  </body>
</html>
-------------------------------------------------------

在Login.java Servlet源文件中:

public void doPost(HttpServletRequest request, HttpServletResponseresponse)
   throws ServletException,IOException {

 response.setContentType("text/html;charset=utf-8");

 //response.setContentType("text/html;charset=GBK");//也可以正常显示中文

  request.setCharacterEncoding("utf-8");
  PrintWriter out = response.getWriter();
 out.print("<H>welcome you comehere!</H>");
 out.print("<br>");
 out.println(request.getParameter("username"));
 out.print("<br>");
 out.println(request.getParameter("password"));
 out.print("<br>");
  out.flush();
 System.out.println(response.getCharacterEncoding());
  out.close();
}

 

因为在index.jsp中

<%@ pagecontentType="text/html;charset=utf-8"%>有这句话,所以JSP默认使用的pageEncoding=utf-8

所以在Login Servlet你必须加上:

response.setContentType("text/html;charset=utf-8");

request.setCharacterEncoding("utf-8");
这两句话,才能正常显示中文!
作者:mark_qi