事出有因

在向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. python模拟shell执行脚本

    工作时候需要模拟shell来执行任务,借助包paramkio import paramiko class ShellExec(object): host = '127.0.0.1' port = 36 ...

  2. Docker了解

    Docker了解1.Docker能做什么:Docker能够解决虚拟机能够解决的问题,同时也能够解决虚拟机由于请求资源过高无法解决的问题. *隔离应用依赖 *创建应用镜像并进行复制 *创建容易分发的即启 ...

  3. grep 与 find 简单命令

    在使用linux的时候,经常会用到查找文件或者查找文本,下面介绍两个命令. grep 使用方法: // 在当前目录下递归查找class字符串 grep "string" -r . ...

  4. Qt编写QUI皮肤生成器

    用Qt写项目写多了,为了满足不同客户的需求,需要定制不同样式的界面,QUI皮肤生成器应运而生.思考这个工具的架构花了一年时间,如何从复杂的配色方案中提取出共性,然后将共性转为具体的QSS文件.思考架构 ...

  5. Struts2-整理笔记(一)介绍、搭建、流程、详解struts.xml

    Struts2是一种前端的技术框架 替代Servlet来处理请求   Struts2优势 自动封装参数 参数校验 结果的处理(转发|重定向) 国际化 显示等待页面 表单的防止重复提交   搭建框架:导 ...

  6. Python 阿里大于发送手机验证码

    1.安装阿里大于的包 pip install top 2.事例脚本 # -*- coding: utf-8 -*- import top.api appkey = '2353xxxx' secret ...

  7. MyBatis单个多个参数传递

    一.传入单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList ...

  8. MicroPython开发之物联网快速开发板

    Python的火热让其运行在MCU端的MicroPython也逐渐迎来了春天.MicroPython的出现让Python这种"胶水语言"成功引用到嵌入式领域,也使得Python控制 ...

  9. 转载自 BotVS 「 珍藏版 」如何搭建一个完整的交易框架

    [img]http://dn-filebox.qbox.me/8c218c119046b2a25df2d9c7b00c1e0fa6899bdd.png[/img]NO:01 交易策略 ≠ 交易系统. ...

  10. HTML知识点总结之table

    table元素 table用来创建表格,表格也可以用来布局,但是嵌套过于复杂,不利于灵活布局,已经几乎没人用它来布局了. 表格基本上有如下几个标签构成: (1)<table>标签用来创建表 ...