字符编码

乱码问题

乱码问题是开发中经常碰到的问题,每次遇到这种问题都是从网上搜解决方案,然后拷贝代码去试,不行再去找,成功解决就放一边了,开发完成后也不去追究究竟是什么原因造成的乱码问题,只知道是编码问题,但如果进一步问,是什么样的编码问题导致的就不得而知了。
其实编码没有那么深奥,可以这样理解:计算机在存储字符时,使用的是二进制的数字,为了存储字符,就需要制定一套规则用于将二进制的数字与字符一一对应起来,这样形成的一套规则就叫编码规则,而这套规则包含的所有字符组成一个字符集。那么,在使用该编码规则对将字符转换成二进制存储起来,那么当需要取字符时,很显然也只能使用这套规则就二进制数字进行解码。那么乱码的原因就是因为编码和解码使用了不同的编码规则,并且解码使用的编码规则不兼容编码时编码规则,导致二进制数字不能被正常解析,出现乱码。
有了这样的理解后,接下来就需要了解下常用的编码规则都有哪些,这些规则之间的不同之处是什么。

编码及字符集

  • ASCII及ISO8859-1

    ASCII是美国信息交换标准代码的英文(American Standard Code for Information Interchange)首字母缩写,使用单字节表示一个字符,总共有7位,表示的字符集有128个字符。ISO8859-1是ASCII的扩展字符集,也是单字节编码,但是使用了8位来表示,字符集中有256个字符。按照字符的二进制数字大小排列,前128个字符完全相同,因此使用ASCII编码的字符可以使用ISO8859-1进行解码。

  • GB及GBK

    GB及GBK是适用于汉字的编码方式,按照时间先后主要有以下几种:
    • GB2312 中国国家标准简体中文字符集,收录了6763个汉字。采用2个字节来表示,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节。
    • GBK 汉字内码扩展规范,K为汉字“扩展”的拼音首字母大写。是GB2312的扩展,汉字和字符更多,向下完全兼容GB2312,因此使用GB2312编码的汉字,可以使用GBK进行解码。
    • GB18030 国家标准 GB-18030-2005《信息技术中文编码字符集》是最新的内码集,有70244个汉字,向下完全兼容GB2312和GBK。多字节编码,单字节双字节和四字节。

    以上三种的0-128与ASCII完全一致,即兼容ASCII编码

  • UTF-8/UTF-16
    • UTF-8 8-bit Unicode Transformation Format ,可变长度字符编码,与ASCII兼容。

Java Web中的编解码

Java的网络通信采用ISO8859-1编码方式,因此HTTP请求在传递之前都要经过ISO8859-1编码后进行传输,而后在接收端再使用ISO8859-1进行解码。比如传递一个参数是中文,中文是GBK编码的,将参数使用GBK编码后,再使用ISO8859-1解码。解码后进行传输,浏览器接收后使用GBK进行编码,再使用ISO8859-1进行解码,得到正确的字符。整个过程如下面的代码所示:

    public static void main(String[] args) throws UnsupportedEncodingException {

        String s = "你好";  
         
        //服务器端,对汉字字符串进行GBK编码,再使用ISO8859-1进行解码,传输解码后的字符串
        // 编码  
        byte[] gbk = s.getBytes("gbk");  
        // 解码 
        String s3 = new String(gbk, "iso8859-1");
           
        //客户端接收到上s3后,先使用iso8859-1进行编码,再使用gbk进行解码,得到原始字符
        s3 = new String(s3.getBytes("iso8859-1"), "gbk");  
          
        System.out.println(s3);  
            
    }

如果不进行上述操作时,直接传递字符串s,相当于直接传递的是s的ISO8859-1的编码,那么浏览器在接收到s的ISO8859-1的编码后,无论使用任何解码方式都没办法正常解码,出现乱码:

    public static void main(String[] args) throws UnsupportedEncodingException {
        
        //服务器端对s不做任何处理,网络传输时s会被按照iso8859-1进行编码
        String s = "你好";  
        
        //客户端接收到上s的编码二进制后,无论使用GBK还是UTF-8或者其他任一一种编码方式都无法解析出正确的s
        String s3 = new String(s.getBytes("iso8859-1"), "iso8859-1");
        String s4 = new String(s.getBytes("iso8859-1"), "GBK");
        String s5 = new String(s.getBytes("iso8859-1"), "UTF-8");
          
        System.out.println(s3);
        System.out.println(s4);
        System.out.println(s5);
            
    }

所以,在服务器端在发送汉字时,最稳妥的办法时,对汉字使用GBK或者UTF-8(UTF-8字符集也包含汉字)进行编码,最好是使用UTF-8进行编码因为有些浏览器比如Safari不支持GBK而UTF-8大多都支持,再使用ISO8859-1进行解码。这样汉字乱码问题就解决了。

基于Spring Boot搭建的一个多功能在线学习系统的实现细节。系统分为管理员和用户两个主要模块。管理员负责视频、文件和文章资料的管理以及系统运营维护;用户则可以进行视频播放、资料下载、参与学习论坛并享受个性化学习服务。文中重点探讨了文件下载的安全性和性能优化(如使用Resource对象避免内存溢出),积分排行榜的高效实现(采用Redis Sorted Set结构),敏感词过滤机制(利用DFA算法构建内存过滤树)以及视频播放的浏览器兼容性解决方案(通过FFmpeg调整MOOV原子位置)。此外,还提到了权限管理方面自定义动态加载器的应用,提高了系统的灵活性和易用性。 适合人群:对Spring Boot有一定了解,希望深入理解其实际应用的技术人员,尤其是从事在线教育平台开发的相关从业者。 使用场景及目标:适用于需要快速搭建稳定高效的在线学习平台的企业或团队。目标在于提供一套完整的解决方案,涵盖从资源管理到用户体验优化等多个方面,帮助开发者更好地理解和掌握Spring Boot框架的实际运用技巧。 其他说明:文中不仅提供了具体的代码示例和技术思路,还分享了许多实践经验教训,对于提高项目质量有着重要的指导意义。同时强调了安全性、性能优化等方面的重要性,确保系统能够应对大规模用户的并发访问需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值