关于字符编码与解码的几个问题,希望大家一起讨论

提几个问题:

1.从JSP页面按get或post方式传递参数,到返回结果这个过程中,中文参数会被经过几次字符编码,具体经过哪些编码过程?

2.JSP页面设置的字符编码会对传递的参数进行编码吗?如JSP页面设置为:
HTML code
      
      
<!----> <% @ page language = " java " contentType = " text/html; charset=GBK " pageEncoding = " GBK " %>

  那么在传递参数之前,会将参数先进行编码成GBK吗?

3.在参数传递到服务器这个过程中(tomcat),会进行几次URLEncoder.encode()编码和几次URLDecoder.decode()解码,并且 编码和解码的时候都采用什么字符编码格式?在传递的过程中是否也会使用new String(s.getBytes("GBK"), "UTF-8")这种方式进行转码或者其他方式进行转码?

4.如果在tomcat的server.xml文件的 <Connector>中设置URIEncoding属性,是否会将所有请求进行一次编码,这样的话又是在什么地方进行解码的呢?URLEncoding这个属性设置与不设置的区别如何?

5.如下面代码中,如何再将乱码转换回汉字?
Java code
      
      
<!----> String s = " 中文 " ; try { s = new String(s.getBytes( " GBK " ), " UTF-8 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s);

  此时,s已经被转换为乱码,如何再将它转换回正常的汉字呢?

以上几个问题,我已经迷惑了好久,始终没有一个清晰的概念,希望大家一起讨论!希望了解的高人们能够给出一个清晰的回答,在参数传递这整个流程中,都经过了哪些关键的编码或转码?
如果有好的资料,也希望不吝分享!
 
 
问题点数:200 回复次数:79 显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • yinyuan1987
  • 等级:
  • 可用分等级:富农
  • 总技术分:13039
  • 总技术分排名:1460
发表于:2008-12-12 10:04:111楼 得分:0
这是我以前在别的帖子上发的希望对大家有帮助

关于中文乱码问题的几点总结: 
  1、unicode,utf-8,gbk,gb2312等都是字符编码,是指怎么用字节来表示字符。       
  2、java使用的是unicode,此话的意思是指运行时java的char类型是一个unicode编码字符,占两个字节。 
  3、java原文件一般都是以本地字符编码存储在本地文件系统中的。 
  4、java类文件是以unicode编码存储在本地文件系统中的。 
  5、当从一个字节序列转化为一个字符串的时候,需要字符编码。 
   
  乱码问题一般就是发生在第5步,比如一个4字节iso8859-1编码的字节(如:a,b,c,d),如果使用正确的字符编码转化它将被转化为4个字符(a,b,c,d)占8个字节,如果使用gbk编码转化它将被转为2个字符,同时着两个字符肯定也不是合法的gbk字符(??),乱码也就产生了。 
   
  jsp中的乱码问题 
  1、首先说读取数据,web服务器接收请求时,接受到的是字节序列,转化为字符时就需要知道此字符序列的编码,才能正确转化。对于tomcat来讲,如果未指定则默认使用iso8859-1,而通常中文平台的编码是gb2312,所以就会产生乱玛。 
  2、 <%@  page  contentType="text/html;  charset=GBK"  %> 
  着句的意思是设置http响应头,提示浏览器使用的字符编码,同时设置http响应(response)的字符编码。 
  3、对于tomcat的get请求,编码的处理是在server.xml的connctor的URIEncoding中指定的。 

这是对乱码的总结。


支持楼主上面的这样的讨论帖子
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • lihan6415151528
  • 等级:
  • 可用分等级:小财主
  • 总技术分:19483
  • 总技术分排名:739
  • 3

发表于:2008-12-12 10:06:052楼 得分:0
Java code
          
          
<!----> String s = " 中文 " ; try { s = new String(s.getBytes( " GBK " ), " UTF-8 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s);

改成
Java code
          
          
<!----> String s = " 中文 " ; String s1 = "" ; try { s = new String(s.getBytes( " GBK " ), " UTF-8 " ); s1 = new String(s.getBytes( " iso=8859-1 " ), " gb2312 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s1);
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • crjjason
  • 等级:
  • 可用分等级:中农
  • 总技术分:1421
  • 总技术分排名:21661
发表于:2008-12-12 10:06:293楼 得分:0
有人说,乱码问题一直跟中国的程序员特别有缘,真是再同意不过了,不管是Struts,JSF,JSP,还是MySQL,Tomcat,全都或多或少有乱码的问题。
一般的做法有用Filter:
< filter >
    < filter-name > Set Character Encoding </ filter-name >
    < filter-class > org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
    < init-param >
      < param-name > encoding </ param-name >
      < param-value > GBK </ param-value >
    </ init-param >
    < init-param >
      < param-name > ignore </ param-name >
      < param-value > true </ param-value >
    </ init-param >
  </ filter >
  < filter-mapping >
    < filter-name > Set Character Encoding </ filter-name >
    < url-pattern > *.do </ url-pattern >
  </ filter-mapping >
  < filter-mapping >
    < filter-name > Set Character Encoding </ filter-name >
    < url-pattern > *.jsp </ url-pattern >
  </ filter-mapping >
  < filter-mapping >
    < filter-name > Set Character Encoding </ filter-name >
    < url-pattern > *.html </ url-pattern >
  </ filter-mapping >
  < filter-mapping >
    < filter-name > Set Character Encoding </ filter-name >
    < url-pattern > *.htm </ url-pattern >
  </ filter-mapping >
的,有用
<% request.setCharacterEncoding( " GBK " ); %>
的,还有用
<% @ page contentType = " text/html; charset=GBK "  pageEncoding = " GBK " %>
的,还可以用
<%  String name  =  new  String(request.getParameter( " name " ).getBytes( " 8859_1 " ),  " GB2312 " );  %>
在做项目的过程中,发现用URL传request参数的时候,在第二个页面上得到乱码的问题。把上面几种方法都试了一下还是不行。仔细追踪了一下,发现在页面的源代码上中文是正常的,一直到URL还是中文正常,可是在后台的Action里面log出来就成了乱码了,于是猜想是在request封装的过程中把中文变成乱码了,以致于后台直接就是取到的乱码。在后台Action中Set入中文,页面上正常显示,说明Struts的中文已经不存在问题。剩下的,应该就只有doGet和doPost方法的问题了。找了一下tomcat的配置文件,发现只要在server.xml中:
<!--  Define a non-SSL HTTP/1.1 Connector on port 8080  -->
    < Connector  port ="8080"  maxHttpHeaderSize ="8192"
              maxThreads ="150"  minSpareThreads ="25"  maxSpareThreads ="75"
              enableLookups ="false"  redirectPort ="8443"  acceptCount ="100"
              connectionTimeout ="20000"  disableUploadTimeout ="true" />
    <!--  Note : To disable connection timeouts, set connectionTimeout value
    to 0  -->
改为
<!--  Define a non-SSL HTTP/1.1 Connector on port 8080  -->
    < Connector  port ="8080"  maxHttpHeaderSize ="8192"
              maxThreads ="150"  minSpareThreads ="25"  maxSpareThreads ="75"
              enableLookups ="false"  redirectPort ="8443"  acceptCount ="100"
              connectionTimeout ="20000"  disableUploadTimeout ="true"  URIEncoding ="GBK" />
    <!--  Note : To disable connection timeouts, set connectionTimeout value
    to 0  -->
就是加上URIEncoding="GBK"就万事大吉了。
至此,应该再困难的乱码问题都解决了吧。就是要在页面上、数据库中、request里、doGet、doPost方法里面都是中文!
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • zou_wei_forever
  • 等级:
  • 可用分等级:中农
  • 总技术分:4315
  • 总技术分排名:5844
发表于:2008-12-12 10:07:424楼 得分:0
sf?
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • ganglong99
  • 等级:
  • 可用分等级:贫农
  • 总技术分:1262
  • 总技术分排名:19367
发表于:2008-12-12 10:19:195楼 得分:0
谢谢yinyuan1987.

1.既然web服务器接收到的是字节序列,那么这个字节序列应该是通过字符串的getBytes()方法转化的吧,那么在这里转化的时候采用的是什么编码呢?系统默认的还是?

2. <%@  page  contentType="text/html;  charset=GBK"  %> 
  着句的意思是设置http响应头,提示浏览器使用的字符编码,同时设置http响应(response)的字符编码。
没错,这是提示浏览器使用的什么字符编码,那么提交的参数会产生这种编码吗?如果直接在地址栏输入中文的参数,它会进行编码吗?

3.对于tomcat的get请求,编码的处理是在server.xml的connctor的URIEncoding中指定的。
那么如果不指定这个属性值,默认会采用什么编码格式呢?
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • ganglong99
  • 等级:
  • 可用分等级:贫农
  • 总技术分:1262
  • 总技术分排名:19367
发表于:2008-12-12 10:25:026楼 得分:0
2楼李晗的方法我试了一下,结果仍然是乱码啊!
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • lihan6415151528
  • 等级:
  • 可用分等级:小财主
  • 总技术分:19483
  • 总技术分排名:739
  • 3

发表于:2008-12-12 10:28:057楼 得分:0
乱码问题我一般都是这样用得

Java code
          
          
<!----> String s = " 中文 " ; try { s = new String(s.getBytes( " iso=8859-1 " ), " gb2312 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s);


或者用过滤器

不好用你打我
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • herowach
  • 等级:
  • 可用分等级:中农
  • 总技术分:1246
  • 总技术分排名:18803
发表于:2008-12-12 10:33:198楼 得分:0
问几个问题:
一、.java文件的字符集编码会对文件中的字符串产生影响吗?
二、String s = "abc"; 这里的abc的字符集是跟操作系统的字符集编码一致还是JVM的?
三、如何将servlet的response.getWriter().print(xml);输入的到界面的字符集改成UTF-8,以前遇到过的,怎么转换最后还是ANSI的(就是在页面点查看源代码,然后另存为可以看见当前的字符集编码格式)
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • ganglong99
  • 等级:
  • 可用分等级:贫农
  • 总技术分:1262
  • 总技术分排名:19367
发表于:2008-12-12 10:35:069楼 得分:0
Java code
          
          
<!----> String s = " 中文 " ; try { s = new String(s.getBytes( " iso-8859-1 " ), " gb2312 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s);

呵呵,你这个仍然是乱码!

其实我想问的是,如果我把中文用下面的方式转化了后,再怎么转换回正常的汉字来。
Java code
          
          
<!----> String s = " 中文 " ; try { s = new String(s.getBytes( " GBK " ), " UTF-8 " ); } catch (UnsupportedEncodingException e3) { e3.printStackTrace(); } System.out.println(s);

现在是用GBK来把s字符串先解成字节数组,然后用UTF-8把字节数组解成字符串,此时的字符串是乱码,怎么变回正常的汉字来?
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • realcbb
  • 等级:
  • 可用分等级:富农
  • 总技术分:781
  • 总技术分排名:27498
发表于:2008-12-12 10:35:1110楼 得分:0
的确比较全面的编解码问题,我的理解:

1.无论是post还是get都是按页面的编码进行提交,即pageEncoding。如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的charset决定;如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1。后台处理完成后以charset设定的编码方式返回给JSP页面。
未设定时,pageEncoding和charset默认都是ISO-8859-1。

2.第一个问题中已经说清楚了,在程序里获取的参数就是以pageEncoding方式编码的内容。

3.除非你手动调用,否则不会进行URLEncoder.encode()或URLDecoder.decode(),具体过程还是见第一个问题。

4.如果设置了过滤器,只能对post方式提交的数据自动转码;如果在server.xml中设置了URIEncoding,只能对get方式提交数据自动转码。如果这两项都没有设置,需要时可以手动进行转码。

5.s = new String(s.getBytes("UTF-8"), "GBK");即可。
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • herowach
  • 等级:
  • 可用分等级:中农
  • 总技术分:1246
  • 总技术分排名:18803
发表于:2008-12-12 10:38:2011楼 得分:0
引用 5 楼 ganglong99 的回复:
谢谢yinyuan1987.

1.既然web服务器接收到的是字节序列,那么这个字节序列应该是通过字符串的getBytes()方法转化的吧,那么在这里转化的时候采用的是什么编码呢?系统默认的还是?

2. <%@  page  contentType="text/html;  charset=GBK"  %> 
  着句的意思是设置http响应头,提示浏览器使用的字符编码,同时设置http响应(response)的字符编码。
没错,这是提示浏览器使用的什么字符编码,那么提交的参数会产生这种编码…

默认应该是ISO-8859-1吧,
直接在地址栏输应该不会编码,(至少我这边GET提交中文要先URLEncoder.encode一下),
第三个不清楚,反正不是UTF-8
 
<!---->修改 删除 举报 引用 回复

进入用户个人空间
加为好友
发送私信
在线聊天
  • ganglong99
  • 等级:
  • 可用分等级:贫农
  • 总技术分:1262
  • 总技术分排名:19367
发表于:2008-12-12 10:44:3212楼 得分:0
8楼herowach的问题我也想问:

一、.java文件的字符集编码会对文件中的字符串产生影响吗?
个人认为是会产生影响的,如果你的系统编码不是支持中文的,比如是ISO-8859-1,那么含有中文的java文件可能就编译不通过吧,个人想法!

二、String s = "abc"; 这里的abc的字符集是跟操作系统的字符集编码一致还是JVM的?
是跟操作系统一致吧。

三、如何将servlet的response.getWriter().print(xml);输入的到界面的字符集改成UTF-8,以前遇到过的,怎么转换最后还是ANSI的(就是在页面点查看源代码,然后另存为可以看见当前的字符集编码格式)
可以用response.setCharacterEncoding("UTF-8")
 
<!---->

你可能感兴趣的:(tomcat,jsp,xml,struts,浏览器)