Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 384|回复: 0

[servlet学习]WEB应用中的编码问题

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-10 00:56:53 | 显示全部楼层 |阅读模式
    java是为做国际化应用设计的,Servlet应根据浏览器语言设置自动切换字符集配置。
          首先一个概念:即使是基于Java的WEB应用,在服务器和客户端之间传递的仍然是字节流,比如我从一个中文客户端的浏览器表单中提交“世界你好”这4个中文字到服务器时:首先浏览器按照GBK方式编码成字节流CA C0 BD E7 C4 E3 BA C3,然后8个字节按照URLEncoding的规范转成:%CA%C0%BD%E7%C4%E3%BA%C3,服务器端的Servlet接收到请求后应该按什么解码处理,输出时又应该按什么方式编码字节流呢?  

      

      
          在目前的Servlet的规范中,如果不指定的话通过WEB提交时的输入ServletRequest和输出时的ServletResponse缺省都是ISO-8859-1方式编码/解码的(注意,这里的编码/解码方式是和操作系统环境中的语言环境是无关的)。因此,即使服务器操作系统的语言环境是中文,上面输入的请求仍然按英文解码成8个UNICODE字符,输出时仍按照英文再编码成8个字节,虽然这样在浏览器端如果设置是中文能够正确显示,但实际上读写的是“字节”,正确的方式是应该根据客户端浏览器设置ServletRequest和ServletResponse,用相应语言的编码方式进行输入解码/输出编码,HelloUnicodeServlet.java就是这样一个监测客户端浏览器语言设置的例子:

       package examples;
    /*
      *  Che, Dong Email:
      *chedongATbigfoot.com/chedongATchedong.com
      * $Id: HelloUnicodeServlet.java,v 1.4
      */
      
      
       
       
       

       
      
      
    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
      * 一个简单的Servlet试验:用于说明如何自动根据HTTP头中的"Accept-Language"
      * 检测客户端的语言字符集设置,正确的将请求中的内容解码,并将内容用正确的
      * 编码方式编码反馈给客户端。
      *
      * @author Che, Dong
      */

    public class HelloUnicodeServlet extends HttpServlet {
         /**
          * Brower language detection demo
          * @param req HTTP Servlet Request
          * @param res HTTP Servlet Response
          * @throws ServletException servlet error
          * @throws IOException  io error
          */
         public void doGet(HttpServletRequest req, HttpServletResponse res)
             throws ServletException, IOException {
             String clientLanguage = req.getHeader("Accept-Language");

             /*
              * comment following code to disable brower language detection
              */
             if (clientLanguage.startsWith("zh-cn")) {//
                 //for Simplied Chinese         
                 req.setCharacterEncoding("GBK");
                 res.setContentType("text/HTML; charset=GBK");
             } else if (clientLanguage.startsWith("zh-tw")) {
                 //for Traditional Chinese
                 req.setCharacterEncoding("BIG5");
                 res.setContentType("text/html; charset=BIG5");
             } else {
                 //default encoding
                 req.setCharacterEncoding("ISO-8859-1");
                 res.setContentType("text/html; charset=ISO-8859-1");
             }

             //defualt hello string
             String hello = "hello world";

             if (req.getParameter("hello") != null) {
                 hello = req.getParameter("hello").trim();
             }

             PrintWriter pw = res.getWriter();
             pw.println(
                 "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
             pw.println("<html>");
             pw.println("<head>");
             pw.println("<title>" + hello + "</title>");
             pw.println("</head>");
             pw.println();
             pw.println("<body>");
             pw.println();
             pw.println("<h2>" +"clientLanguage="+ clientLanguage+"</h2><p />");
             pw.println("<h1>"" + hello + "" length=" + hello.length()+ "</h1><p />");

             //print current request and response charset encoding
             pw.println("ServletRequest"s Charset Encoding = "
                 + req.getCharacterEncoding());
             pw.println("<br />");
             pw.println("ServletResponse"s Charset Encoding = "
                 + res.getCharacterEncoding());
             pw.println("<br />");

             //print char array
             pw.println(getCharArray(hello));

             //show input form
             pw.println("<form action="" method="GET">");
             pw.println("<input name="hello" value="");
             pw.print(hello);
             pw.print("">");
             pw.println(" <input type="submit">");
             pw.print("</form>");

             //print system properties
             pw.println("<pre>");
             System.getProperties().list(pw);
             pw.println("</pre>");

             pw.println("</body></html>");
             pw.close();
         }

         /**
          * print char array
          * @param inStr  input String
          * @return String output String
          */
         private static String getCharArray(String inStr) {
             char[] myBuffer = inStr.toCharArray();
             StringBuffer sb = new StringBuffer();

             //list each Charactor in byte value, short value, and UnicodeBlock Mapping
             for (int i = 0; i < inStr.length(); i++) {
                 byte b = (byte) myBuffer;
                 short s = (short) myBuffer;
                 String hexB = Integer.toHexString(b).toUpperCase();
                 String hexS = Integer.toHexString(s).toUpperCase();

                 //print char
                 sb.append("char[");
                 sb.append(i);
                 sb.append("]="");
                 sb.append(myBuffer);
                 sb.append(""        ");

                 //byte value
                 sb.append("byte=");
                 sb.append(b);
                 sb.append(" \u");
                 sb.append(hexB);
                 sb.append("        ");

                 //short value
                 sb.append("short=");
                 sb.append(s);
                 sb.append(" \u");
                 sb.append(hexS);
                 sb.append("        ");

                 //Unicode Block
                 sb.append(Character.UnicodeBlock.of(myBuffer));
                 sb.append("<br />");
             }

             return sb.toString();
         }
    }
    当浏览器的首选语言设置为中文(中国)[zh-ch]时,输出如下:

    clientLanguage=zh-cn,zh-tw;q=0.8,zh;q=0.7,en-us;q=0.5,en;q=0.3,tr;q=0.2

    "hello 世界你好" length=10
    ServletRequest"s Charset Encoding = GBK  
    ServletResponse"s Charset Encoding = GBK  
    char[0]="h" byte=104 u68 short=104 u68 BASIC_LATIN
    char[1]="e" byte=101 u65 short=101 u65 BASIC_LATIN
    char[2]="l" byte=108 u6C short=108 u6C BASIC_LATIN
    char[3]="l" byte=108 u6C short=108 u6C BASIC_LATIN
    char[4]="o" byte=111 u6F short=111 u6F BASIC_LATIN
    char[5]=" " byte=32 u20 short=32 u20 BASIC_LATIN
    char[6]="世" byte=22 u16 short=19990 u4E16 CJK_UNIFIED_IDEOGRAPHS
    char[7]="界" byte=76 u4C short=30028 u754C CJK_UNIFIED_IDEOGRAPHS
    char[8]="你" byte=96 u60 short=20320 u4F60 CJK_UNIFIED_IDEOGRAPHS
    char[9]="好" byte=125 u7D short=22909 u597D CJK_UNIFIED_IDEOGRAPHS

    当浏览器的首选语言设置为英语(美国)[en-us]时,输出如下:

    clientLanguage=en-us,zh-cn;q=0.8,zh-tw;q=0.7,zh;q=0.5,en;q=0.3,tr;q=0.2

    "hello &Ecirc;&Agrave;&frac12;&ccedil;&Auml;&atilde;&ordm;&Atilde;" length=14
    ServletRequest"s Charset Encoding = ISO-8859-1  
    ServletResponse"s Charset Encoding = ISO-8859-1  
    char[0]="h" byte=104 u68 short=104 u68 BASIC_LATIN
    char[1]="e" byte=101 u65 short=101 u65 BASIC_LATIN
    char[2]="l" byte=108 u6C short=108 u6C BASIC_LATIN
    char[3]="l" byte=108 u6C short=108 u6C BASIC_LATIN
    char[4]="o" byte=111 u6F short=111 u6F BASIC_LATIN
    char[5]=" " byte=32 u20 short=32 u20 BASIC_LATIN
    char[6]="&Ecirc;" byte=-54 uFFFFFFCA short=202 uCA LATIN_1_SUPPLEMENT
    char[7]="&Agrave;" byte=-64 uFFFFFFC0 short=192 uC0 LATIN_1_SUPPLEMENT
    char[8]="&frac12;" byte=-67 uFFFFFFBD short=189 uBD LATIN_1_SUPPLEMENT
    char[9]="&ccedil;" byte=-25 uFFFFFFE7 short=231 uE7 LATIN_1_SUPPLEMENT
    char[10]="&Auml;" byte=-60 uFFFFFFC4 short=196 uC4 LATIN_1_SUPPLEMENT
    char[11]="&atilde;" byte=-29 uFFFFFFE3 short=227 uE3 LATIN_1_SUPPLEMENT
    char[12]="&ordm;" byte=-70 uFFFFFFBA short=186 uBA LATIN_1_SUPPLEMENT
    char[13]="&Atilde;" byte=-61 uFFFFFFC3 short=195 uC3 LATIN_1_SUPPLEMENT  

      
      
       
       

         
       

         
       
      


                            function TempSave(ElementID)
                            {
                                    CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value);
                                    CommentsPersistDiv.save("CommentXMLStore");
                            }
                            function Restore(ElementID)
                            {
                                    CommentsPersistDiv.load("CommentXMLStore");
                                    document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent");
                            }
                   
                        


    源码下载:http://file.javaxxz.com/2014/10/10/005653265.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-6-16 09:29 , Processed in 0.458202 second(s), 50 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表