jsp各部分编码的含义

 

服务器JSP编码

pageEncoding

是jsp文件本身的编码,

       第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,(jsp文件的编码,pageEncoding是否一致),结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定(在JSP标准的语法中,如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的charset决定,如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1。),出来的就是中文乱码。该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。

contentType

contentType的charset是指服务器发送给客户端时的内容编码

 

注:

可见,pageEncoding和contentType都可以设置JSP源文件和响应正文中的字符集编码。但也有区别: 设置JSP源文件字符集时,优先级为pageEncoding>contentType。如果都没有设置,默认ISO-8859-1。 设置响应输出的字符集时,优先级为contentType>pageEncoding。如果都没有设置,默认ISO-8859-1。

客户端浏览器编码

URL编码    

  1. 在IE中输入网址http://www.baidu.com/s?wd=春节

查询字符串的编码:

IE:用的是操作系统的编码。

ChromeUTF-8

FIREFOX:UTF-8

  1. 在页面链接中:<a href=” http://www.baidu.com/s?wd=春节”>点我</a>

由网页编码决定,都是由Content-Type指定

GET请求

由网页编码决定,都是由Content-Type指定

POST请求

由网页编码决定,都是由Content-Type指定

Jquery ajax请求

       在发送请求时,ajax会自动把查询字符串进行UTF-8编码。

$.ajax({

    data:[{key=value}]//这样才会自动编码,如果是key=value&。。。自己拼装的则不会编码

});

注:jquery内部会调用jQuery.param方法对参数encode(执行本应浏览器处理的encode)。 

 

编码处理

GET请求

对于GET方式处理编码有两种方法:(服务器为:Tomcat)

  1. 代码实现,使用硬编码:

new String(request.getParameter(“name”).getBytes(“iso-8859-1”),”客户端编码方式”);

  1. 服务器下的配置(也就是把硬编码的操作交给了Tomcat了)

在server.xml下配置:

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

或者:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI='TRUE'/>

  • URIEncoding是对所有GET方式的请求的数据进行统一的重新编码。
  • useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码,不同的页面可以有不同的重新编码的编码,,在默认情况下,该参数为false。

POST请求

request.setCharacterEncoding(arg0);  只针对POST起作用

Javascript编码函数

1.   escape()

不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如"春节"的返回结果是%u6625%u8282,也就是说在Unicode字符集中,"春"是第6625个(十六进制)字符,"节"是第8282个(十六进制)字符。

它的规则是,escape不编码字符有69个:*+-./@_0-9a-zA-Z,对其他所有字符进行编码。在\u0000到\u00ff之间的符号被转成%xx的形式,其余符号被转成%uxxxx的形式。对应的解码函数是unescape()。

注:首先,无论网页的原始编码是什么,一旦被Javascript编码,就都变为unicode字符。也就是说,Javascipt函数的输入和输出,默认都是Unicode字符。 其次,escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。

 

encodeURI()

encodeURI()是Javascript中真正用来对URL编码的函数。

编码后,它输出符号的utf-8形式,并且在每个字节前加上%。 它对应的解码函数是decodeURI()。  需要注意的是,它不对单引号'编码。

encodeURI不编码字符有82个:!#$&'()*+,-./:;=?@_~0-9a-zA-Z

encodeURIComponent()

与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。 encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z它对应的解码函数是decodeURIComponent()。

有时为什么会使用两次js编码

因为第一次编码,你的参数内容便不带有多字节字符了,成了纯粹的 Ascii 字符串。(这里把编第一次的结果叫成 [STR_ENC1] 好了。[STR_ENC1] 是不带有多字节字符的) 再编一次后,提交,接收时容器自动解一次(容器自动解的这一次,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到 [STR_ENC1] 然后,再在程序中实现一次 decodeURIComponent (Java中通常使用 java.net.URLDecoder(***, "UTF-8")) 就可以得到想提交的参数的原值。

举个栗子:

String str1 = URLEncoder.encode("程序员","utf-8");//假设为浏览器的第一次编码

       String str2 = URLEncoder.encode(str1,"utf-8");  //浏览器第二次编码           

       String deStr1 = URLDecoder.decode(str2,"gbk");

//服务器进行解码,不论是什么编码都能得到正确的浏览器第一次的编码

       String deStr2 = URLDecoder.decode(deStr1,"utf-8");//最后得到正确的字符串

 

http://www.cnblogs.com/xckxue/p/4202278.html

 

1.字节和unicode   Java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式   是使用字节流的。   因此Java要对这些字节流经行转化。char是unicode的,而byte是字节.   Java中byte/char互转的函数在sun.io的包中间有。其中ByteToCharConverter类是中调度,   可以用来告诉你,你用的Convertor。其中两个很常用的静态函数是      public   static   ByteToCharConverter   getDefault()   ;      public   static   ByteToCharConverter   getConverter(String   encoding);   如果你不指定converter,则系统会自动使用当前的Encoding,GB平台上用GBK,EN平台上用   8859_1      我们来就一个简单的例子:       "你 "的gb码是:0xC4E3   ,unicode是0x4F60      你用:      --encoding= "gb2312 ";      --byte   b[]={(byte) '\u00c4 ',(byte) '\u00E3 '};      --convertor=ByteToCharConverter.getConverter(encoding);      --char   []   c=converter.convertAll(b);      --for(int   i=0;i <c.length;c++)      --{      --   System.out.println(Integer.toHexString(c[i]));      --}      --打印出来是0x4F60      --但是如果使用8859_1的编码,打印出来是      --0x00C4,0x00E3      ----例1        反过来:        --encoding= "gb2312 ";           char   c[]={ '\u4F60 '};           convertor=ByteToCharConverter.getConverter(encoding);      --byte   []   b=converter.convertAll(c);      --for(int   i=0;i <b.length;c++)      --{      --   System.out.println(Integer.toHexString(b[i]));      --}       --打印出来是:0xC4,0xE3       ----例2       --如果用8859_1就是0x3F,?号,表示无法转化      --         很多中文问题就是从这两个最简单的类派生出来的。而却有很多类     不直接支持把Encoding输入,这给我们带来诸多不便。很多程序难得用encoding   了,直接用default的encoding,这就给我们移植带来了很多困难   --   2.UTF-8   --UTF-8是和Unicode一一对应的,其实现很简单   --      --   7位的Unicode:   0   _   _   _   _   _   _   _   --11位的Unicode:   1   1   0   _   _   _   _   _   1   0   _   _   _   _   _   _   --16位的Unicode:   1   1   1   0   _   _   _   _   1   0   _   _   _   _   _   _   1   0   _   _   _   _   _   _   --21位的Unicode:   1   1   1   1   0   _   _   _   1   0   _   _   _   _   _   _   1   0   _   _   _   _   _   _   1   0   _   _   _   _   _   _   --大多数情况是只使用到16位以下的Unicode:   -- "你 "的gb码是:0xC4E3   ,unicode是0x4F60   --我们还是用上面的例子   --  --例1:0xC4E3的二进制:   --  --      1   1   0   0   0   1   0   0   1   1   1   0   0   0   1   1   --  --      由于只有两位我们按照两位的编码来排,但是我们发现这行不通,   --  --      因为第7位不是0因此,返回 "? "   --  --        --  --例2:0x4F60的二进制:   --  --      0   1   0   0   1   1   1   1   0   1   1   0   0   0   0   0     --  --      我们用UTF-8补齐,变成:   --  --      11100100   10111101   10100000   --  --      E4--BD--   A0   --  --      于是返回0xE4,0xBD,0xA0   --  --   3.String和byte[]   --String其实核心是char[],然而要把byte转化成String,必须经过编码。   --String.length()其实就是char数组的长度,如果使用不同的编码,很可   --能会错分,造成散字和乱码。   --例:   ----byte   []   b={(byte) '\u00c4 ',(byte) '\u00e3 '};   ----String   str=new   String(b,encoding);  ----   ----如果encoding=8859_1,会有两个字,但是encoding=gb2312只有一个字  ----   --这个问题在处理分页是经常发生   4.Reader,Writer/InputStream,OutputStream   --Reader和Writer核心是char,InputStream和OutputStream核心是byte。   --但是Reader和Writer的主要目的是要把Char读/写InputStream/OutputStream --一个reader的例子: --文件test.txt只有一个 "你 "字,0xC4,0xE3-- --String   encoding=; --InputStreamReader   reader=new   InputStreamReader( ----new   FileInputStream( "text.txt "),encoding); --char   []c=new   char[10]; --int   length=reader.read(c); --for(int   i=0;i <c.length;i++) ----System.out.println(c[i]);   --如果encoding是gb2312,则只有一个字符,如果encoding=8859_1,则有两个字符   -------- -- --         ----  2.我们要对Java的编译器有所了解:  --javac   -encoding     我们常常没有用到ENCODING这个参数。其实Encoding这个参数对于跨平台的操作是很重要的。     如果没有指定Encoding,则按照系统的默认Encoding,gb平台上是gb2312,英文平台上是ISO8859_1。     --Java的编译器实际上是调用sun.tools.javac.Main的类,对文件进行编译,这个类 --  有compile函数中间有一个encoding的变量,-encoding的参数其实直接传给encoding变量。  编译器就是根据这个变量来读取java文件的,然后把用UTF-8形式编译成class文件。  一个例子:  --public   void   test()  --{  ----String   str= "你 ";  ----FileWriter   write=new   FileWriter( "test.txt ");  ----write.write(str);  ----write.close();  --}  ----例3 --如果用gb2312编译,你会找到E4   BD   A0的字段 -- --如果用8859_1编译, --00C4   00E3的二进制: --00000000   11000100   00000000   11100011-- --因为每个字符都大于7位,因此用11位编码: --11000001   10000100   11000011   10100011   --C1--   84-- C3--    A3 --你会找到C1   84   C3   A3   --        但是我们往往忽略掉这个参数,因此这样往往会有跨平台的问题:   --  例3在中文平台上编译,生成ZhClass   --  例3在英文平台上编译,输出EnClass   --1.    ZhClass在中文平台上执行OK,但是在英文平台上不行   --2.    EnClass在英文平台上执行OK,但是在中文平台上不行   原因:  --1.在中文平台上编译后,其实str在运行态的char[]是0x4F60, ----  --在中文平台上运行,FileWriter的缺省编码是gb2312,因此  --CharToByteConverter会自动用调用gb2312的converter,把str转化  --成byte输入到FileOutputStream中,于是0xC4,0xE3放进了文件。  --但是如果是在英文平台下,CharToByteConverter的缺省值是8859_1,  --FileWriter会自动调用8859_1去转化str,但是他无法解释,因此他会  --输出 "? " ----  --2. 在英文平台上编译后,其实str在运行态的char[]是0x00C4   0x00E3, ----  --在中文平台上运行,中文无法识别,因此会出现??  --  在英文平台上,0x00C4--> 0xC4,0x00E3-> 0xE3,因此0xC4,0xE3被放进了  --文件 ---- 1.对于JSP正文的解释: --Tomcat首先看一下你的叶面中有没有 " <%@page   include的符号。有,则在相同 --地方设定response.setContentType(..);按照encoding的来读,没有他按照8859_1 --读取文件,然后用UTF-8写成.java文件,然后用sun.tools.Main去读取这个文件, --(当然它使用UTF-8去读),然后编译成class文件 --setContentType改变的是out的属性,out变量缺省的encoding是8859_1

2.对Parameter的解释 --很不幸Parameter只有ISO8859_1的解释,这个质料可以在servlet的实现代码中找到。

3.对include的解释 格式的,但是很不幸,由于那个写 "org.apache.jasper.compiler.Parser "的人 在数组JspUtil.ValidAttribute[]忘记加了一个参数:encoding,因此导致不支 持这种方式。你完全可以编译源代码,加上对encoding的支持

总结:

如果你在NT底下,最简单的方法就是欺骗java,不加任何Encoding变量: <html> 你好 <%=request.getParameter( "value ")%> </html>

http://localhost/test/test.jsp?value=你

结果:你好你

但这种方法局限性较大,比如对上传的文章分段,这样的做法是死定的,最好的 解决方案是用这种方案: <%@   page   contentType= "text/html;charset=gb2312 "   %> <html> 你好 <%=new   String(request.getParameter( "value ").getBytes( "8859_1 "), "gb2312 ")%> </html>

 

Eclipse中如.js,或.properties文件中有中文不能保存的问题的解决方法

Window-》Ppreference-》General -》Content Types -》Text -》JavaScript或Java Properties File,选中它并在Default encoding:把iso8859-1改为utf-8,或gbk,或gb2312,再点击“Update”就可以了。 
这里还可以改变其他一些文件的默认编码:如JSP,Java Source File ...... 

 

总结jsp提交中文乱码

http://www.blogjava.net/luedipiaofeng/articles/307666.html

1: 最基本的乱码问题。
这个乱码问题是最简单的乱码问题。一般新会出现。就是页面编码不一致导致的乱码。
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=iso8859-1"%>
<html>
<head>
<title>中文问题</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
</head>
<body>
   我是个好人
</body>

三个地方的编码。

第一个地方的编码格式为jsp文件的存储格式。Eclipse会根据这个编码格式保存文件。并编译jsp文件,包括里面的汉字。

第 二处编码为解码格式。因为存为UTF-8的文件被解码为iso8859-1,这样 如有中文肯定出乱码。也就是必须一致。而第二处所在的这一行,可以没有。缺省也是使用iso8859-1的编码格式。所以如果没有这一行的话,“我是个好人”也会出现乱码。必须一致才可以。

第三处编码为控制浏览器的解码方式。如果前面的解码都一致并且无误的话,这个编码格式没有关系。有的网页出现乱码,就是因为浏览器不能确定使用哪种编码格式。因为页面有时候会嵌入页面,导致浏览器混淆了编码格式。出现了乱码。


2:表单使用Post方式提交后接收到的乱码问题
这个问题也是一个常见的问题。这个乱码也是tomcat的内部编码格式iso8859-1在捣乱,也就是说post提交时,如果没有设置提交的编码格式,则会以iso8859-1方式进行提交,(tomcat默认编码:ISO8859-1)接受的jsp却以utf-8的方式接受。导致乱码。既然这样的原因,下面有几种解决方式,并比较。
A :接受参数时进行编码转换
String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;

这样的话,每一个参数都必须这样进行转码。很麻烦。但确实可以拿到汉字。

B :在请求页面上开始处,执行请求的编码代码, request.setCharacterEncoding("UTF-8"),把提交内容的字符集设为UTF8。这样的话,接受此参数的页面就不必在 转码了。直接使用String str request.getParamet("something");即可得到汉字参数。但每页都需要执行这句话。这个方法也就对post提交的有效果,对于get提交和上传文件时的enctype="multipart/form-data"是无效的。稍后下面单独对这个两个的乱码情况再进行说明。

C :为了避免每页都要写request.setCharacterEncoding("UTF-8"),建议使用过滤器对所有jsp进行编码处理。

3 :表单get提交方式的乱码处理方式

如果使用get方式提交中文,接受参数的页面也会出现乱码,这个乱码的原因也是tomcat的内部编码格式iso8859-1导致。Tomcat会以get的缺省编码方式iso8859-1对汉字进行编码,编码后追加到url,导致接受页面得到的参数为乱码。

解决办法:

A 使用上例中的第一种方式,对接受到的字符进行解码,再转码。

B Get走的是url提交,而在进入url之前已经进行了iso8859-1的编码处理。要想影响这个编码则需要在
server.xml 的Connector节点增加useBodyEncodingForURI="true" 属性配置,即可控制tomcat对get方式的汉字编码方式,上面这个属性控制get提交也是用 request.setCharacterEncoding("UTF-8")所设置的编码格式进行编码。所以自动编码为utf-8,接受页面正常接受就 可以了。但我认为真正的编码过程是,tomcat又要根据
<Connector port="8080" 
maxThreads="150" minSpareThreads="25" maxSpareThreads="75" 
enableLookups="false" redirectPort="8443" acceptCount="100" 
debug="0" connectionTimeout="20000" useBodyEncodingForURI="true" 
disableUploadTimeout="true" 
URIEncoding=”UTF-8”/>里面所设置的URIEncoding=”UTF-8”再进行一次编码,
但是由于已经编码为utf-8,再编码也不会有变化了。
如果是从url获取编码,接受页面则是根据URIEncoding=”UTF-8”来进行解码的。

 

 

 

1. (客户端乱码)IE中显示乱码

1).<%@page pageEncoding="utf-8"%>----------------->指定javac.exe用什么方式去读jsp文件

2).注意:jsp文件另存为的时候,要选择utf-8格式保存.===>和第一步一致
3).<%@page contentType="text/html;charset=utf-8"%>------>指定reponse返回流用什么编码

4).注意: IE中-->查看-->编码--->会自动选择utf-8===>和第三步一致

 

注意:html的meta中的<meta http-equiv="content-Type" content="text/html; charset=utf-8">是不起任何作用的。它只在IE直接打开本地的html文件时有用,在这种情况下,由它来告诉IE,到底使用哪种编码方式去读本地的html文件。

(可能不对,因为IE还没有读html怎么知道该文件中含有这个信息呢,如果已经读了,那还要该信息干什么。)

 

2.(服务器端乱码)在*.java中request.getParameter("username");是乱码

html中的form含有中文时,form提交到服务器端的流的编码方式----与“IE中-->查看-->编码--->会自动选择utf-8”是一致的。所以,在java中,在取参数之前,用:request.setCharacterEncoding("UTF-8");

 

上一篇:Linux应用程序调用其他程序执行


下一篇:QDEZ集训笔记【更新中】