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

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

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.13\conf\server.xml中Connector节点(只有一个未注释的Connector节点)内加:

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

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

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

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

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

关于乱码(MessyCode)问题的更多相关文章

  1. java web 学习十(HttpServletRequest对象1)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  2. 5 Http请求中文乱码处理

    java 乱码分很多种,这里主要研究解决http请求中出现乱码的情况. http请求出现中文乱码的主要原因:发送方与接收方编码不一致,服务器默认支持的编码与web应用不一致,如:tomcat 是国外程 ...

  3. win10 环境 gitbash 显示中文乱码问题处理

    gitbash 是 windows 环境下非常好用的命令行终端,可以模拟一下linux下的命令如ls / mkdir 等等,如果使用过程中遇到中文显示不完整或乱码的情况,多半是因为编码问题导致的,修改 ...

  4. java中文乱码解决之道(一)-----认识字符集

    沉寂了许久(大概有三个多月了吧),LZ"按捺不住"开始写博了! java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要么是按照以前的经验修改,要么则是baidu.c ...

  5. Sublime Text 3中文乱码解决方法以及安装包管理器方法

    一般出现乱码是因为文本采用了GBK编码格式,Sublime Text默认不支持GBK编码. 安装包管理器 简单安装 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令 ...

  6. java字符乱码

    在java中处理字符时,经常会发生乱码,而主要出现的地方在读取文本文件时发生,或者是写入到文件中,在其他地方打开乱码. 如下例子: BufferedReader br = null; try { br ...

  7. MAC下 mysql不能插入中文和中文乱码的问题总结

    MAC下 mysql不能插入中文和中文乱码的问题总结 前言 本文中所提到的问题解决方案,都是基于mac环境下的,但其他环境,比如windows应该也适用. 问题描述 本文解决下边两个问题: 往mysq ...

  8. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

  9. 【云知道】究极秒杀Loadrunner乱码

    Loadrunner乱码一击必杀 之前有介绍一些简单的针对Loadrunner脚本或者调试输出内容中乱码的一些设置,但是并没能完全解决一些小伙伴的问题,因为那些设置实在能力有限,还是有很多做不到的事情 ...

随机推荐

  1. ArcEngine临时数据存储 创建内存工作空间

    参考网址,这里 工作中有时候需要使用临时数据,以前都是创建一个默认的shapefile或者gdb,今天发现esri官方帮助文档给出了一个方法,可以创建内存工作空间,代码如下: public stati ...

  2. java.sql.SQLException: Field 'id' doesn't have a default value(用eclipse操作数据库时报了这种奇怪的错误)的原因与解决方法

    1.错误原因 由于id在数据库表中是作为主键,但是在插入的过程中,没有给予数值,并且没有让其自增 2.解决办法 修改数据库表中的id,让其自增(在插入的过程中,不插入id数据时)

  3. linux考试题改错

    符号链接和硬链接有什么区别? 改:符号链接存储文件路径,可以指向不同分区文件,源文件删除后失效. 改:硬链接指向文件索引节点,仅能指向同一分区文件,源文件删除后可以访问. 请描述文件和目录9位权限位的 ...

  4. sonarqube安装的坑

    1.按照官网安装 结果启动不了,看了log日志以后,发现是es报错,不能以root权限启动

  5. 最全的MonkeyRunner自动化测试从入门到精通(5)

    夜神模拟器的安装与配置步骤一:我们为什么会选择使用夜神模拟器呢? 众所周知,Android studio的模拟器运行速度也很快,可以媲美真机.虽然其运行速度很快,可以满足我们测试的需求.但仍存在以下问 ...

  6. Linux3.10.0块IO子系统流程(0)-- 块IO子系统概述

    前言:这个系列主要是记录自己学习Linux块IO子系统的过程,其中代码分析皆基于Linux3.10.0版本,如有描述错误或不妥之处,敬请指出! 参考书籍:存储技术原理分析--基于Linux 2.6内核 ...

  7. 基于UVM的verilog验证

    Abstract 本文介绍UVM框架,并以crc7为例进行UVM的验证,最后指出常见的UVM验证开发有哪些坑,以及怎么避免. Introduction 本例使用环境:ModelSim 10.2c,UV ...

  8. ORACLE——存储过程

    存储过程procedure 被内容来自<oracle从入门到精通——明日科技>一书 存储过程是一种命名的PL/SQL程序快,存储过程被保存在数据库中,它不可以被SQL语句直接执行或调用,只 ...

  9. NIO学习资料

    五大IO模型 https://jiges.github.io/2018/02/07/%E4%BA%94%E5%A4%A7IO%E6%A8%A1%E5%9E%8B/ Getting started wi ...

  10. textarea 标签的使用

    <textarea rows="行数" cols="列数">默认出现文本</textarea> 阻止拉伸:style="res ...