tomcat 乱码问题

 

测试环境:apache-tomcat-6.0.48

操作系统:win7 中文 默认GBK编码

一、浏览器采用的字符集

测试jsp:

 

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"> <!--html5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--html4写法-->
  <title></title>
</head>
<body >
  <%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  <form action="charset.jsp">
    userName:<input type="text" name="userName" value="中国">
     <button type="submit" > 提交 </button>
  </form>
</body>

</html>
 

  页面显示正常。

   



 
 

    

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
修改为===》
<%@ page contentType="text/html;charset=GBK" language="java" %>

   页面:http://127.0.0.1:8080/charset.jsp,显示乱码:

   

 查看一下IE显示页面时使用的中文编码:

是GB2312,那么IE如何确认页面采用哪一种编码格式显示页面呢?
 我们来查看一下请求响应:

 

     原来:服务器返回 Content-type:text/html;charset=GBK,

     来源于:<%@ page contentType="text/html;charset=GBK" language="java" %>,

     IE使用该字符集显示页面,charset.jsp 文件是UTF-8字符集保存的,字符集不符,所以乱码,更改

     charset.jsp 文件的字符集为GBK,再次请求,显示正常:

     


 jsp 编码取决于:<%@ page contentType="text/html;charset=GBK" language="java" %>,

那么HTML是什么情况呢? 

再测试一下:

 新建 charset.html:

 

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"> <!--html5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--html4写法-->
  <title></title>
</head>
<body >
  <%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  <form action="charset.jsp">
    userName:<input type="text" name="userName" value="中国">
     <button type="submit" > 提交</button>
  </form>
</body>
<!--file utf-8 charset-->
</html>
 
   打开页面:http://127.0.0.1:8080/charset.html

 

   页面显示正常:

   

 查看一下服务器response header:



 Content-Type未指定字符集,那么以页面中html 标签定义的字符集为准。

  

<meta charset="utf-8"> <!--html5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--html4写法-->
 
返过来,再想一下,如果jsp 头中未指定字符集

 

<%@ page contentType="text/html;charset=GBK" language="java" %> 

charset=GBK ------这个不写

浏览器以哪个字符集为准呢? 再测试一下:

 jsp 未指定字符集:

  

<%@ page contentType="text/html" language="java" %>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"> 
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title></title>
</head>
<body >
  <%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  <form action="charset.jsp">
    userName:<input type="text" name="userName" value="中国">
     <button type="submit" > 提交</button>
  </form>
</body>

</html>
 

 页面展现:

   

 页面展示正常,且浏览器认为是UTF8编码。

再看一下服务器 response header:

  

 服务器响应header 中未指定字符集, 浏览器采用html指定的字符集:

 

 <meta charset="utf-8"> 
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

 


 结论:如果服务器response header 中指定了字符集:

 Content-type="text/html;charset=字符集"

           

 
则使用该字符集,如果没有指定则使用html标签中的字符集:

<meta charset="utf-8"> <!--html5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--html4写法-->

 
 

 

 
 

 



 

二 get 请求 

 浏览器向web服务器提交请求时,如果参数中有中文,浏览器会进行转换:

    中文转换为%加上汉字字符集的编码,

如“中国”两个字:

      如果浏览器认为页面是UTF-8编码:  

                        utf-8编码占用6个字节:e4 b8 ad e5 9b bd  ,浏览器会转换为:%E4%B8%AD%E5%9B%BD

     如果浏览器认为页面是GBK编码:  

         GBK编码占4个字节:D6 D0 B9 FA,浏览器会转换为:%D6%D0%B9%FA

   

 测试jsp:

  

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"> <!--html5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--html4写法-->
  <title></title>
</head>
<body >
  <%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  <form action="charset.jsp">
    userName:<input type="text" name="userName" value="中国">
     <button type="submit" > 提交 </button>
  </form>
</body>

</html>

  提交方式为get( form 元素中未加入 method="post"),

   

   请求url:http://127.0.0.1:8080/charset.jsp?userName=%E4%B8%AD%E5%9B%BD

   userName 值为中文“中国”,浏览器确认页面字符集编码为UTF-8(由response header 中Content-type:"text/html;charset:UTF-8"),自动为按UTF-8转码:%E4%B8%AD%E5%9B%BD,传给后台服务。

  

   提交结果后,显面显示乱码:

  

<%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  输出:userName:ä¸­å½ 

   原因:tomcat 默认以iso_8859_1 编码处理get请求参数。

 

   修改方式:tomcat ->conf/server.xml:

       增加:URIEncoding="UTF-8"

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443"   URIEncoding="UTF-8"/>

   修改后,页面显示正常:

 

     

    <%
     String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
    输出:userName:中国

   

   问题:如果页面编码格式为GBK,那么会不会乱码呢?

   修改:

   

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
修改为===》
<%@ page contentType="text/html;charset=GBK" language="java" %>

 

 那么提交一下,显示乱码:

  

 原因: 页面字符集为GBK,向后台提交请求时采用GBK编码,向后台传送%D6%D0%B9%FA,后台tomcat配置为URIEncoding="UTF-8",以UTF-8编码接收请求的GBK编码的数据,所以乱码。 

 

 

总结:对于get请求时参数中有中文,后台需要配置:

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443"   URIEncoding="字符集"/>

 字符集取决为:

   jsp:

<%@ page contentType="text/html;charset=这个字符集" language="java" %>

 

    html: 

   <meta charset="这个字符集"> 

<meta http-equiv="Content-Type" content="text/html; charset=这个字符集" />     

   

 

三、post请求

 

   与get请求一样,浏览器对当前页面的采用的字符编码进行汉字编码,发送给后台。

   区别在于:汉字编码是在 body中发送出的,而不是在请求的queryString中发出去的。

   所以对post请求,server.xml中配置URIEncoding="字符集"不启做用,需要程序中调用:

            request.setCharacterEncoding("字符集")。

 

   该字符集与浏览器发送的编码一至即可。

   request.setCharacterEncoding:spring 提供了一个通用的filter可以设置:

    

 
<filter>  
	 <filter-name>EncodingFilter</filter-name>  
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter  
	 </filter-class>  
	 <init-param>  
		<param-name>encoding</param-name>  
	 <param-value>UTF-8</param-value>  
	 </init-param>  
	 <init-param>  
	 <param-name>forceEncoding</param-name>  
		<param-value>true</param-value>  
	 </init-param>  
 </filter>  
<filter-mapping>  
     <filter-name>EncodingFilter</filter-name>  
     <url-pattern>/*</url-pattern>  
</filter-mapping>  
</web-app>

 需要注意:EncodingFilter 应该是第一个被调用的filter,原因:如果其它Filter 从request获取了数据,如request.getParameter 之后,EncodingFilter再设置:request.setCharacterEncoding 不生效。

  因此EncodingFilter 应该在web.xml 中最靠前的位置。

 

 

    测试jsp:

    

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"> <!--HTML5写法-->
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <!--HTML4写法-->
  <title></title>
</head>
<body >
  <%
    String userName = request.getParameter("userName");
    out.println("userName:"+userName);
  %>
  <form action="charset1.jsp" method="post">
    userName:<input type="text" name="userName" value="中国">
     <button type="submit" > 提交</button>
  </form>
</body>
<!--file charset:UTF-8 -->
</html>

  由jsp可见,浏览器会使用utf-8编码汉字,因此tomcat web.xml :filter 字符集设为UTF-8

  

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  6.    
  7. <filter>  
  8. <filter-name>EncodingFilter</filter-name>  
  9. <filter-class>org.springframework.web.filter.CharacterEncodingFilter  
  10. </filter-class>  
  11. <init-param>  
  12. <param-name>encoding</param-name>  
  13. <param-value>UTF-8</param-value>  
  14. </init-param>  
  15. <init-param>  
  16. <param-name>forceEncoding</param-name>  
  17. <param-value>true</param-value>  
  18. </init-param>  
  19.  </filter>  
  20. <filter-mapping>  
  21.      <filter-name>EncodingFilter</filter-name>  
  22.      <url-pattern>/*</url-pattern>  
  23. </filter-mapping>  
  24. </web-app>
  25. </web-app>  

 

打开页面,显示正常,提交中文正常:



 

 

   

 




 
 

   

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值