zoukankan      html  css  js  c++  java
  • 关于Java乱码

    乱码本质:读取二进制时采用的编码与最初将字符转成二进制时的编码不一致。

    编码(获得二进制数组的过程)时不抛出异常,数据就不会被破坏。

    Java关于乱码(MessyCode)问题

    Java使用的是Unicode编码;

    String str = "双引号里是字符串字面量";str在JVM中的编码是Unicode编码表示的;

    除了这种程序内部的数据之外,还常常从外部获取各种各样的数据让程序处理,比如文件、数据库,而这些数据的编码格式是多种多样的,可能是UTF-8、GBK,这样的一些数据在JVM中是以什么编码表示的?

    字符集编码编码格式是两个概念

    字符集编码:由某个组织制定的一张字符与编号的映射关系表,如:10001=="我",10002=="们",Unicode字符集就是这样的一张关系表。

    UTF-8是一种实现了Unicode字符集中部分字符编码的编码格式,它存在的目的:为了保存或传输数据。那既然在字符集中已经有了映射关系了,为何还要再来编码?

    因为:考虑到文件大小的问题、使用效率的问题、和其它字符集区分的问题。

    UTF-8编码是对Unicode字符集中哪部分编码?就是"字符编号",例如上面的10001、10002

    对于UTF-8编码规则可网上查阅。

    JVM中表示字符串"我们"使用的编码为"1000110002"这样的格式,即使用的是Unicode的编号,

    当通过IO将一个以UTF-8编码的文本文件读入内存时:

    new InputStreamReader(new FileInputStream(new File("文本文件路径")),"UTF-8");

    这里指定的"UTF-8"即文件的编码格式,它的目的是告诉负责解码的对象要按"UTF-8"的编码格式来解码成JVM使用的Unicode编码,若这里指定为"gbk"则得到乱码。

    String str="文件内容",str此时已是Unicode编码。

    例:

    String yuanlai="我是一个字符串";

    String result=new String(yuanlai.getBytes("utf-8"),"gbk");->输出result乱码,

    将Unicode编码的yuanlai按utf-8的编码格式进行编码,得到utf-8编码的字节数组;将字节数组按GBK的编码格式来解码成Unicode编码的字符。UTF-8和gbk不兼容,二者使用了不同的编码集,故乱码。

    进行http请求时,我们需告诉对方我们发送的数据的编码格式是什么,若对方按照我们告知的编码格式来解码,而我们却把错误的编码格式告诉了对方,则对方收到乱码。

    "这是一个字符串".getBytes(),这样编码得到的字节数组是操作系统默认的编码格式。

    import java.io.UnsupportedEncodingException;
    
    public class MessyCode {
        public static void main(String[] args) throws UnsupportedEncodingException {
            String original="这是一个字符串,是Unicode编码的。恭喜發財";
            System.out.println("原有字符串:"+original);
            //将Unicode编码按照gbk编码格式进行编码
            byte[] GBK_bytes = original.getBytes("gbk");
            /*
            本来是gbk编码的字节数组,我们使用utf-8来解码,当然此时必然会是乱码
            注:若第一次解码时使用这种错误的解码方式,则后面将无法再恢复,
            下面的例子可以看到
             */
            String UTF8_str=new String(GBK_bytes,"utf-8");
            System.out.println("UTF-8解码后的字符串:"+UTF8_str);
            /*
            接下来我们把该字符串按照UTF-8的编码格式再编码回去,
            但这时GBK_bytes和UTF8_bytes已经完全不同了,
             */
            byte[] UTF8_bytes=UTF8_str.getBytes("utf-8");
            /*
            接着我们再来按照GBK的编码格式来解码
            得到的自然是乱码
             */
            String UTF2GBKstr=new String(UTF8_bytes,"gbk");
            System.out.println("GBK解码UTF-8编码后的字符串:"+UTF2GBKstr);
            /*
            但是,若第一次解码时使用单字节的编码格式来解码,则后面是可以再恢复的
            但前提要保证该单字节的编码会利用上所有的8位
            也就是说可以表示256个字符的才行
    
    
            单字节的编码格式有两种,ASCII和ISO-8859-?
            ASCII使用了7位来表示字符,最高位永远为0,其可以表示的范围只有128个字符
            ISO-8859-?(问号表示1,2,...,15,16(没有12),表示15个字符集)
            使用8位来表示字符,总共可以表示256个字符
    
            这两种单字节编码,ISO-8859-1最常用
             */
            //转换为ASCII码的字符串
            String ASCII_str=new String(GBK_bytes,"ASCII");
            System.out.println("ASCII解码后的字符串:"+ASCII_str);
            //再将ASCII转换为GBK
            String GBK_str=new String(ASCII_str.getBytes("ASCII"),"gbk");
            System.out.println("将ASCII编码按照gbk编码格式解码:"+GBK_str);
    
    
            String ISO_str=new String(GBK_bytes,"ISO-8859-1");
            System.out.println("ISO-8859-1解码后的字符串:"+ASCII_str);
            //再将ASCII转换为gbk
            String GBK_str1=new String(ISO_str.getBytes("ISO-8859-1"),"gbk");
            System.out.println("将ISO-8859-1编码按照GBK编码格式解码:"+GBK_str1);
        }
    }
    

    更优地克服困难。

    Java GUI组件上汉字乱码问题

    按钮上文字乱码;解决:Button改成JButton,即awt换成swing

    jsp中超链接传参乱码

    jsp页面中,超链接传参乱码,?后面的键值对的值为中文会出现这种问题

    解决:JSP在tomcat中,D:apache-tomcat-9.0.13confserver.xml中Connector节点(只有一个未注释的Connector节点)内加:

    URIEncoding="GBK"(原来文件没有);然而加这句话后会出现一个新问题:

    当jsp A跳转到jsp B时,?传参有中文,jsp B在加载时使用js获取?后参数,参数会被转码,

    解决:jsp A中:encodeURI(....jsp?键=中文值),encodeURI函数的返回值仍为一个URL,

    jsp B中js函数(页面加载时做什么)里写:decodeURI(转了码的参数值),decodeURI函数返回中文参数值。

    总结:虽然?传参中文乱码可以解决,但尽量别传中文;可以传英文,目标页面接收到再识别判断,这也是可以的。

  • 相关阅读:
    javascript学习笔记(一):基础、输出、注释、引用、变量、数据类型
    black-hole《XSS的原理分析与解剖》阅读笔记
    《xss跨站脚本剖析与防御》实验笔记
    XSS和CSRF的区别
    前端常用插件、工具类库汇总(下)
    前端常用插件、工具类库汇总(上)
    前端特效【第03期】|果汁混合效果-上
    玩转 React 【第03期】:邂逅 React 组件
    前端修炼の道 | 如何成为一名合格前端开发工程师?
    前端特效【第02期】|多功能提交按钮
  • 原文地址:https://www.cnblogs.com/yyjh/p/10618148.html
Copyright © 2011-2022 走看看