事出有因

在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致。

URL url = new URL(requestUrl);
//打开连接
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); ......
...... //获取输出流
out = new OutputStreamWriter(urlConn.getOutputStream());
//发送请求参数
out.write(concatKeyValue(params, false));
out.flush()

回过头来看,问题看似挺容易解决,只需在获取输出流时,指定字符编码集

out = new OutputStreamWriter(urlConn.getOutputStream(), "utf-8");

但实则费了一番工夫。期间心里产生了过以下的问题:

1、String.getBytes(String charset)与String(Byte[] bytes, String charset)的使用。

2、什么场合下会涉及的字符编码的转换呢?

3、在不显示指定charset时,java使用Charset.defaultCharset()来获取默认字符编码。Charset.defaultCharset()的值来自哪里?

为了在以后的开发中,快速解决字符集相关问题。在这里对字符集做了一次比较系统的学习。

字符集与字符编码

字符是各种文字与符号的总称,比如语言符号、图形符号、标点。

字符集是字符的集合,每个字符集包含的字符个数不同,常见的字符集有:unicode字符集、ISO 8859字符集、GB2312字符集、GB18030字符集、BIG5字符集等。

字符编码是以二进制数字来对应字符集中的字符,使得计算机能够识别字符集中的字符。

各个国家在制定编码标准的时候,通常是同时制定字符集与编码规范。因此常见的字符集,如GB2312,除了表示“字符集”这一层含义外,也包含了编码的含义。

Unicode字符集有多种编码方式,如UTF-8、UTF-16等;ASCII只有一种;大多数MBCS(Multi-Byte Chactacter System,即多字节字符系统)(包括GB2312)也只有一种。

Java

Java中的字节码文件始终以unicode编码方式保存。Java运行时创建的字符串变量、常量等字符串均以unicode编码存储在内存中。

当涉及数据读写时,就会涉及字符的编码转换问题,例如从磁盘读取文件时、向磁盘写入文件时、接收网络发送来的数据时等。

数据存储到物理介质或通过物理介质传输时,都是以bit流的形态存在。而要传输正确的bit流,就需要声明和设置恰当的字符编码。

getBytes()与getBytes(charset)

当不指定字符集时,getBytes内部会获取当前操作系统的默认字符集。

getBytes获得字符串的指定编码规范对应的字节数组,此过程称为编码。

//s的字符编码方式为unicode(utf-16), jvm的默认编码规则
String s = "我们";
//得到s的gbk编码, unicode(utf-16) --> gbk
byte[] bytes = s.getBytes("gbk");

String的构造函数String(byte[] bytes, String charset)

//解码,gbk --> unicode(utf-16)
String p = new String(bytes, "gbk");

Charset.defaultCharset()

此方式用来获取默认字符集,默认字符集在jvm启动时已经根据系统环境确认,不可以修改(或者说修改并不会生效)。当jvm的启动时,也可以通过参数-Dfile.encoding指定字符集,或通过环境变量修改默认字符集。

另外也请注意我们运行main方法与web项目的不同,它们启动了jvm的不同实例,所以默认字符集可能不同。所以如果在main方法中打印Charset.defaultCharset().name()的值 与实际运行web项目时输入的值不同,也不要觉得奇怪。

但凡涉及中文(web开发、I/O、数据库读写等),乱码问题会与我们不期而遇,所以理解字符集和字符编码就很有必要。

另外:

当我们使用IDE(idea/eclipse)时,我们可以设置开发环境所使用字符集。请注意:IDE中设置的字符集只能代表IDE在存取源代码文件时使用了何种字符集,而不是class文件使用了何种字符集。

好文推荐:《java中文乱码解决之道(五)—–java是如何编码解码的》

Java应用开发中的字符集与字符编码的更多相关文章

  1. Java Web开发中路径问题小结

     Java Web开发中,路径问题是个挺麻烦的问题,本文小结了几个常见的路径问题,希望能对各位读者有所帮助. (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 图1 ...

  2. [转]字符集、字符编码、XML中的中文编码

    字符集.字符编码.XML中的中文编码 作为程序员的你是不是对于ASCII .UNICODE.GB2321.UTF-7.UTF-8等等不时出现在你面前的这些有着奇怪意义的词感到很讨厌呢,是不是总觉得好象 ...

  3. 字符集、字符编码、XML中的中文编码

    字符集.字符编码.XML中的中文编码 作为程序员的你是不是对于ASCII .UNICODE.GB2321.UTF-7.UTF-8等等不时出现在你面前的这些有着奇怪意义的词感到很讨厌呢,是不是总觉得好象 ...

  4. Java Web 开发中路径相关问题小结

    Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 图1 Eclipse中目录结构如图2所示: 图2 那么针对这个站点的几个基本概 ...

  5. 《Maven在Java项目开发中的应用》论文笔记(十七)

    标题:Maven在Java项目开发中的应用 一.基本信息 时间:2019 来源:山西农业大学 关键词:Maven:Java Web:仓库:开发人员:极限编程; 二.研究内容 1.Maven 基本原理概 ...

  6. Java项目开发中实现分页的三种方式一篇包会

    前言   Java项目开发中经常要用到分页功能,现在普遍使用SpringBoot进行快速开发,而数据层主要整合SpringDataJPA和MyBatis两种框架,这两种框架都提供了相应的分页工具,使用 ...

  7. 关于Unicode,字符集,字符编码,每个程序员都应该知道的事

    关于Unicode,字符集,字符编码,每个程序员都应该知道的事 作者:Jack47 李笑来的文章如何判断一个人是否聪明?中提到: 必要.清晰.且准确的概念,是一切思考的基石.所谓思考,很大程度上,就是 ...

  8. Python中的字符串与字符编码

    本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常谈的话题,同行们都写过很多这方面的文章. ...

  9. 【转】Python中的字符串与字符编码

    [转]Python中的字符串与字符编码 本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常 ...

随机推荐

  1. Windows下RabbitMQ安装及入门

    1.Windows下安装RabbitMQ需要以下几个步骤 (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang. ...

  2. ArcGIS API for JavaScript 4.2学习笔记[9] 同一种视图不同数据(Map)同步

    本例子核心:对MapView对象的map属性值进行替换即可达到更改地图数据的效果. 这个例子用的不是Map对象了,而是用的发布在服务器上的专题地图(WebMap)来加载到MapView上进行显示. 在 ...

  3. 如果没有UX经验,如何创建个人UX作品集?

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 一直以来,这是设计行业的悖论. 当今,许多活跃于我们用户体验行业的专业人士在开始个人职业生涯时都面临 ...

  4. 重温javascript数据类型

    在javaScript中,有五种简单的数据类型,分别是 Undefined Null Boolean Number String 还有一种复杂的数据类型object,object本质是有一组无序的名值 ...

  5. qt中进程的使用

    qt中的进程使用需要用到头文件:include<QProcess> 首先来看看需要用到的主要的函数 (1)进程的定义: QProcess *mprocess; //定义一个进程参数 (2) ...

  6. Qt编写导航按钮

    做各种各样的界面的时候,经常需要做一排按钮用于切换到对应界面,俗称导航按钮或者导航菜单,参照过各种各样的主界面导航布局,特意编写导航按钮自定义控件,结合各种情况,继承自QPushButton.已集成在 ...

  7. elastaticresearch 学习过程

    1.在Windows上安装了es 2.在chrome上装了sense 3.尝试创建 es 的模板

  8. K:java中正则表达式的使用说明及其举例

    从Java1.4起,java核心API就引入了java.util.regex程序包来处理正则表达式,并使用该包下的相关类进行字符串的匹配.搜索.提取.分析结构化内容等工作.需要注意的是,正则表达式本身 ...

  9. Python列表操作

    自带帮助文档: >>> help(list) Help on class list in module builtins: class list(object) | list() - ...

  10. flask连接sqlalchemy数据库,实现简单的登录跳转功能

    环境:python2.7 python库:flask,flask_wtf,wtforms,sqlalchemy 原理:运行app-连接数据库-打开登录页面-输入登录信息(错误->提示错误信息:正 ...