关于get传递参数乱码及长度为奇数时最后一个字符乱码的问题

JSP中文传参数乱码问题。

如果是post加过滤器或者加入

request.setCharacterEncode("gbk")(管输入)
response.setCharacterEncode("gbk")(管输出)

 

如果是url的get提交参数带中文的
可以改下面这个文件,加入一个URIEncoding="GBK"
X:\Tomcat \conf\Server.xml 
 

Xml代码
  1. <Connector    
  2.         port="8080"    
  3.         redirectPort="8443"    
  4.         minSpareThreads="25"    
  5.         connectionTimeout="30"    
  6.         maxThreads="150"    
  7.         maxSpareThreads="75"    
  8. URIEncoding="GBK">   

一、概况:ie7正常,ie6参数就会出现中文接受信息错误,表现为长度是奇数时最后一个字符出现乱码。

二、具体表现:

1、全是汉字时,无论奇数还是偶数,都无乱码。

2、如果是英文中文混合,并且英文字符数是奇数时,就会出现最后有一个“?”号。

3、如果是英文中文混合,并且英文字符数是偶数时,无乱码。

三、原因:ie7支持UTF8编码,但是ie6支持不好。

环境: jdk1.5,tomcat5.5,ie6.0 ,所有jsp页面,xml配置文件URIEncoding 都设置成utf-8,也保存成utf-8格式。

当用ie提交时,单个汉字会出现这个问题。(如果所有的都设置成gbk,则不会出现此问题)

开始以为是tomcat源码问题,通过跟踪tomcat,调试 tomcat org.apache.coyote.http11.Http11BaseProtocol.java可知:

如果输入单汉字“你”->tomcat的侦听的byte流应该时:%E4%BD%A0,而实际收到的是 %E4%BD,第3个byte没有收到。

而同样的配置,如果用firefox1.5测试,则完全正常。!!!!!

所以,这个是ie发送信息时转码错误!!



四、解决方法:

1、用post发送,这个方法当然不出错了,但是,有时候必须用get传递参数的方法,那就没辙了,只能用第二个方法。

2、习惯把中文字符串显示长度设置为偶数。

现在的处理逻辑是:在业务方法里进行判断,如果输入的字符个数为奇数,则给其拼接上一个全角的空格,如果是半角的空格,也还是会有乱码问题。
当你要传值时,故意在汉字结尾处加一个半角字符,比如:

index.jsp?name=我爱你_

我要传的是“我爱你”,但是我故意加一个“_”在后面。

然后在servlet里接收时,用substring()去掉这个“_”:

String name = request.getParameter("name");
name = name.substring(0, name.length()-1);

 

 

 

在网页中的超链接,例如 click me,如果超链接里的地址有中文就如上面的'name=世界'一样,即使在web.xml中设置转换字符集的filter,在servlet中得到的值还是乱码。下面是我的几个实验,

(1) 首先,在web.xml中没有字符集转换的filter下,在表单中提交中文的情况,HTML片段如下

Html代码 复制代码  收藏代码
  1. <form action="./servlet/MyServlet" method="get">  
  2.         <input type="text" name="name">  
  3.         <input type="submit">  
  4. form>  

在文本框中输入'世界', 毫无疑问这个时候在servlet中得到的name的值是乱码 例如:name = ????

(2)现在再把form中的method方法换成post并且仍然是在web.xml中没有字符集转换的filter下,看在表单中提交中文会不会有乱码,HTML片段如下

Html代码 复制代码  收藏代码
  1. <form action="./servlet/MyServlet" method="post">  
  2.         <input type="text" name="name">  
  3.         <input type="submit">  
  4. form>  

 在文本框中输入'世界', 这个时候在servlet中得到的name的值仍然是乱码 例如:name = ????

(3)现在在web.xml中加入字符集转换的filter,代码如下

Xml代码 复制代码  收藏代码
  1. <filter>  
  2.         <filter-name>Set Character Encodingfilter-name>  
  3.         <filter-class>filters.SetCharacterEncodingFilterfilter-class>  
  4.         <init-param>  
  5.             <param-name>encodingparam-name>  
  6.             <param-value>GBKparam-value>  
  7.         init-param>  
  8.     filter>  
  9.        
  10.     <filter-mapping>  
  11.         <filter-name>Set Character Encodingfilter-name>  
  12.         <url-pattern>/*url-pattern>  
  13.     filter-mapping>  

        Set Character Encoding
        filters.SetCharacterEncodingFilter
        
            encoding
            GBK
        
    
    
    
        Set Character Encoding
        /*
    

(4)现在咱们还是现在form的method属性是get时候进行测试,在文本框中输入世界,然后在servlet中得到的name值仍然是乱码,name = ????

(5)然后再在form的method属性是post时候进行测试,在文本框中输入世界,然后在servlet中得到的name值就是正常的值的没有乱码。

我现在用的浏览器是IE,就是表单提交中文时候,如果正确的设置了字符集转换的filter,那么在form中的post方法中提交时,在servlet中得到的正常的值,如果在form中的get方法中提交时候,得到的中文数据居然是乱码,这个有点不可思议。

(6)然后在同样的环境下,在超链接的href属性中提交中文参数值,例如

Html代码 复制代码  收藏代码
  1. <a href='./servlet/MyServlet?name=世界>click mea> <br>  
 />    
     
  • c:url>  
  •        
  • <a href="${url}">Helloa> <br>  
  • 
        	
    
        
    Hello 

     然后在servlet中得到的仍然是乱码,仍然需要(6)中介绍的方法进行转换,才能得到正确的值。

    (8)通过post方法提交的表单中的中文值是不需要通过(6)中的进行转码的,如果进行转码的话,反而会造成乱码。那么,在serlvet中,如果让这两种提交方式(超链接提交和表单post方法)都通用的话,如果超链接的值没有中文的话是可以实现通用的,如果超链接提交的参数有中文的话,就会出现问题,那么就必须在超链接提交的URL中另加一个额外的参数来标识是从哪里提交的,以此来决定是否需要对特定的值进行转化。有没有更好的办法在超链接里提交中文时候在servlet中不进行转码呢。答案就是(5)。如果把超链接提交转化为表单的post提交,中文就不会出现乱码,见(9)

    (9)

    Js代码 复制代码  收藏代码
    1. function linkClick(linkObject) {   
    2.                
    3.     var formObject = document.createElement('form');   
    4.     document.body.appendChild(formObject);   
    5.      formObject.setAttribute('method''post');   
    6.      var url = linkObject.href;   
    7.      var uri = '';   
    8.      var i = url.indexOf('?');   
    9.                
    10.      if(i == -1) {   
    11.         formObject.action = url;   
    12.      } else {   
    13.         formObject.action = url.substring(0, i);   
    14.      }   
    15.                
    16.      if( i >= 0 && url.length >= i + 1) {   
    17.         uri = url.substring(i + 1, url.length);   
    18.      }   
    19.   
    20.      var sa = uri.split('&');   
    21.                
    22.      for(var i = 0; i < sa.length; i++) {   
    23.        var isa = sa[i].split('=');         
    24.        var inputObject = document.createElement('input');   
    25.        inputObject.setAttribute('type''hidden');   
    26.        inputObject.setAttribute('name', isa[0]);   
    27.        inputObject.setAttribute('value', isa[1]);   
    28.        formObject.appendChild(inputObject);   
    29.      }   
    30.                
    31.      formObject.submit();   
    32.                
    33.      return false;   
    34. }  
    function linkClick(linkObject) {
    			
        var formObject = document.createElement('form');
        document.body.appendChild(formObject);
         formObject.setAttribute('method', 'post');
         var url = linkObject.href;
         var uri = '';
         var i = url.indexOf('?');
    			
         if(i == -1) {
            formObject.action = url;
         } else {
            formObject.action = url.substring(0, i);
         }
    			
         if( i >= 0 && url.length >= i + 1) {
            uri = url.substring(i + 1, url.length);
         }
    
         var sa = uri.split('&');
    			
         for(var i = 0; i < sa.length; i++) {
           var isa = sa[i].split('=');		
           var inputObject = document.createElement('input');
           inputObject.setAttribute('type', 'hidden');
           inputObject.setAttribute('name', isa[0]);
           inputObject.setAttribute('value', isa[1]);
           formObject.appendChild(inputObject);
         }
    			
         formObject.submit();
    			
         return false;
    }

     下面是html代码

     

    Html代码 复制代码  收藏代码
    1. <a href='./servlet/MyServlet?name=世界&id=1' onclick="return linkClick(this)">click mea> <br>  
    click me 

     这样就OK了,在linkClick方法里面会自己创建一个表单,然后会去解析你的参数并自动转化成hidden,并给hidden域赋值,这样,再也不怕提交中文参数,并且也不需要在servlet中进行麻烦的转码,真是一劳永逸啊,但是需要在JSP的超链接中加上上面的方法。上面的程序用的是IE6和tomcat5。

     

     

    1.统一用UTF-8编码,即Tomcat的server.xml、页面、过滤器都用UTF-8
    2.
    请求参数,需要编码

    "
    target="frameset">Xls表数据管理


    假如是java代码的话直接写java.net.URLEncoder.encode("测试吗","UTF-8");

    下面引用Qieqie的一段代码:

    	public static void main(String[] args) throws UnsupportedEncodingException {
    		//给定某3个汉字
    		String src = "你好啊";
    		//String src = "一二三";
    		
    		//浏览器进行utf-8编码,并传送到服务器
    		byte[] bytes1 = src.getBytes("utf-8");
    		System.out.println(bytes1.length);//9
    		
    		//tomcat以gbk方式解码(这个片段的说明仅针对gbk处理汉字的情况)
    		//如果一对汉字字节不符合gbk编码规范,则每个字节使用'?'(ascii 63)代替
    		//万幸的话,只是最后一个(第9个)字节因不能成对,变成问号(比如当src="你好啊"时)
    		//不幸的话,中间某些字节就通不过gbk编码规范出现'?'了(比如当src="一二三"时)
    		//总之temp的最后一位必定是问号'?'
    		String temp = new String(bytes1, "gbk"); 
    		
    		//你的action中的代码
    		//由于以上的tomcat以gbk解释utf-8不能成功
    		//所以此时bytes2和bytes1不一样
    		byte[] bytes2 = temp.getBytes("gbk");
    		System.out.println(bytes2.length);
    		for (int i = 0; i < bytes1.length; i++) {
    			System.out.print(bytes1[i] & 0xff);
    			System.out.print("\t");
    		}
    		System.out.println();
    		for (int i = 0; i < bytes2.length; i++) {
    			System.out.print(bytes2[i] & 0xff);
    			System.out.print("\t");
    		}
    		System.out.println();
    
    		//构建出来的dest自然不是原先的src
    		String dest = new String(bytes2, "utf-8");
    		System.out.println(dest);
    		
    	}
    

     

    你可能感兴趣的:(jsp)