事出有因

在向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. C语言应用程序的内存图

    1.综述 c语言应用程序加载到内存,这时它所占据的内存分为四个区,分别为栈Stack,堆Heap,静态存储区Static Area,代码存储区Code Area,这四个区分别放置应用程序的不同部分,从 ...

  2. xamarin android如何监听单击事件

    在xamarin android单击事件是最基础的事情,看过菜鸟上的android教程时,java写的都是监听事件,为一个按钮,单选按钮.多选按钮的单击事件有三种,前面两种用的非常普遍,也很简易,我这 ...

  3. ArcGIS API for JavaScript 4.2学习笔记[11] 官方第五章Popups(弹窗)概览与解释

    直接跳过第三第四章了,第三章Layer和第四章可视化,怎么说呢,Layer是组织数据的,是Map的属性之一.可视化属于符号化编程,暂时不看. 第五章是对数据.结果的显示,类似于alert()..NET ...

  4. tp3.2 事务处理

    事务的机制通常被概括为“ACID”原则即原子性(A).稳定性(C).隔离性(I)和持久性(D).  原子性:构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行.  稳定性:数据库在事 ...

  5. vue基础入门

    Hello World   <body> <!-- 在angularJS中用ng-model --> <!-- {{mseeage?message:11}}支持三元表达式 ...

  6. 安全扫描工具 Netsparker

    Netsparker是一款web应用安全漏洞扫描工具 Netsparter官网:https://www.netsparker.com/web-vulnerability-scanner/,与其他安全扫 ...

  7. Linux目录结构详解

    /: 根目录,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中/bin:/usr/bin: 可执行二进制文件的目录,如常用的命令ls ...

  8. java自动化测试-http请求post

    继上文的get请求http://www.cnblogs.com/xuezhezlr/p/7667995.html的简单讲解后,这篇文章大概说一下我所遇到的主要的post请求以及他的测试代码 上文介绍到 ...

  9. spring boot RESTFul API拦截 以及Filter和interceptor 、Aspect区别

    今天学习一下RESTFul api拦截 大概有三种方式 一.通过Filter这个大家很熟悉了吧,这是java规范的一个过滤器,他会拦截请求.在springboot中一般有两种配置方式. 这种过滤器拦截 ...

  10. springboot 注册服务注册中心(zk)的两种方式

    在使用springboot进行开发的过程中,我们经常需要处理这样的场景:在服务启动的时候,需要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,可以故障摘除和负载均衡. 我遇到过两种注 ...