zoukankan      html  css  js  c++  java
  • 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");

  • 相关阅读:
    svn command line tag
    MDbg.exe(.NET Framework 命令行调试程序)
    Microsoft Web Deployment Tool
    sql server CI
    VS 2010 One Click Deployment Issue “Application Validation did not succeed. Unable to continue”
    mshtml
    大厂程序员站错队被架空,只拿着五折工资!苟活和离职,如何选择?
    揭秘!Windows 为什么会蓝屏?微软程序员竟说是这个原因...
    喂!千万别忘了这个C语言知识!(~0 == -1 问题)
    Linux 比 Windows 更好,谁反对?我有13个赞成理由
  • 原文地址:https://www.cnblogs.com/softidea/p/4202359.html
Copyright © 2011-2022 走看看