java字符编码和oracle乱码

编码问题我仍旧没搞懂,最根本的从哪里来就没搞懂。当页面发送请求,编码到后台是什么编码呢?好吧,我默认的都是utf-8.后台接收参数后,可以在控制台打印出来,我也不清楚是什么编码。然后,就是数据库问题。

在mysql数据库,首先会设置mysql安装的字符集为utf-8,然后在连接的jdbc上注明characterEncoding是utf-8.一直这样统一下去,没有出现乱码。

连接oracle就出现问题了,我使用的一个已经安装好的oracle数据库。字符集是American,us7ascii.我插入和查询的中文都是乱码。百度了很久之后,还是进行转码工作。

关于java编码,先看String中的几个方法:

getBytes()

1 byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException
2 
3 
4 Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array. 
5 
6 The behavior of this method when this string cannot be encoded in the given charset is unspecified. The java.nio.charset.CharsetEncoder class should be used when more control over the encoding process is required.

这里先要搞清楚编码(encode)和解码(decode).下面是个人推测,没有考证的解释:

encode:编码,将字符依据某种规则(字符集)解释为一串数字
decode:解码,将一串数字依据某种规则翻译为字符

理解了编码和解码后,从一个字符串开始解析。

字符串str="中文",str是一串字符,通过str.getBytes()可以编码成byte数组。通过new String(bytes)来解码为字符串。下面是测试:

 1  @Test
 2     public void getEncod() throws UnsupportedEncodingException {
 3         String sysencod = System.getProperty("file.encoding");
 4         System.out.println("系统默认编码:"+sysencod);
 5         String str = "中文";
 6         System.out.println("字符实例:"+str);
 7         System.out.println("===============getbytes无参:===============");
 8         byte[] bytes = str.getBytes();
 9         for (int i = 0; i < bytes.length; i++) {
10             System.out.print(bytes[i]);
11         }
12         System.out.println();
13         System.out.println("通过默认字符集,将字符数组解码为字符:"+new String(bytes));
14         System.out.println("通过utf-8字符集,将字符数组解码为字符:"+new String(bytes,"utf-8"));
15         System.out.println("通过gbk字符集,将字符数组解码为字符:"+new String(bytes,"gbk"));
16         System.out.println("通过iso-8859-1字符集,将字符数组解码为字符:"+new String(bytes,"iso-8859-1"));
17 
18 
19         System.out.println("===============getbytes(utf-8):===============");
20         byte[] bytes2 = str.getBytes("utf-8");
21         for (int i = 0; i < bytes.length; i++) {
22             System.out.print(bytes[i]);
23         }
24         System.out.println();
25         System.out.println("通过默认字符集,将字符数组解码为字符:"+new String(bytes2));
26         System.out.println("通过utf-8字符集,将字符数组解码为字符:"+new String(bytes2,"utf-8"));
27         System.out.println("通过gbk字符集,将字符数组解码为字符:"+new String(bytes2,"gbk"));
28         System.out.println("通过iso-8859-1字符集,将字符数组解码为字符:"+new String(bytes2,"iso-8859-1"));
29         System.out.println("===============getbytes(gbk):===============");
30         byte[] bytes3 = str.getBytes("gbk");
31         for (int i = 0; i < bytes.length; i++) {
32             System.out.print(bytes[i]);
33         }
34         System.out.println();
35         System.out.println("通过默认字符集,将字符数组解码为字符:"+new String(bytes3));
36         System.out.println("通过utf-8字符集,将字符数组解码为字符:"+new String(bytes3,"utf-8"));
37         System.out.println("通过gbk字符集,将字符数组解码为字符:"+new String(bytes3,"gbk"));
38         System.out.println("通过iso-8859-1字符集,将字符数组解码为字符:"+new String(bytes3,"iso-8859-1"));
39         System.out.println("===============getbytes(iso-8859-1):===============");
40         byte[] bytes4 = str.getBytes("iso-8859-1");
41         for (int i = 0; i < bytes.length; i++) {
42             System.out.print(bytes[i]);
43         }
44         System.out.println();
45         System.out.println("通过默认字符集,将字符数组解码为字符:"+new String(bytes4));
46         System.out.println("通过utf-8字符集,将字符数组解码为字符:"+new String(bytes4,"utf-8"));
47         System.out.println("通过gbk字符集,将字符数组解码为字符:"+new String(bytes4,"gbk"));
48         System.out.println("通过iso-8859-1字符集,将字符数组解码为字符:"+new String(bytes4,"iso-8859-1"));
49     }

结果:

奇诡的是,虽然getBytes打印的byte数组内容看起来是一样的,但此编码结构却是不同的。并不是一串字符通过某种字符集编码,再解码就可以还原的。这要看该字符是属于何种编码。中文字符只有utf-8和gbk能够存储成功,别的编码会出现漏码像7位编码之类的。而我要解决的就是中文乱码问题。因此,中文编码是关于utf-8和gbk的。

对于存储于oracle的中文字符,采用iso-8859-1.因此,需要考虑的就是utf-8还是gbk转储为iso-8859-1.

经过测试,存储的时候:p=new String(p.getBytes("gbk"),"iso-8859-1");而getBytes("utf-8")失败。

查询结果的时候:result = new String(str.getBytes("ISO-8859-1"),"gbk")可以将oracle的中文正常显示。

附上我用oracle的字符集:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PhpZendo

JavaScript ES6 (五) – 集合

本章我们将学习 ES6 中的 Set(集合) 及 WeakSet 集合 的相关用法及使用场景。

681
来自专栏前端说吧

JS-原生代码或方法实现特定效果总结(更新中...)

3326
来自专栏java一日一条

Java HashMap的工作原理

面试的时候经常会遇见诸如:“java中的HashMap是怎么工作的”,“HashMap的get和put内部的工作原理”这样的问题。本文将用一个简单的例子来解释下...

421
来自专栏一“技”之长

JavaScript基础之二——方法与属性 原

    和编译型语言必须由类产生对象不同,JavaScript语言中并没有严格的类的界定,并且对象的属性和方法也可以进行动态的绑定。属性是对象中封装的一些值数据...

542
来自专栏PhpZendo

带你入门 JavaScript ES6 (五) 集合

本章我们将学习 ES6 中的 Set(集合) 及 WeakSet 集合 的相关用法及使用场景。

572
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)

4.4.3 约束(Pattern的一部分) 前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false...

1948
来自专栏Android-薛之涛

Android Parcelable

      Paracelable是android自己的实现序列化的接口,是anroid推荐使用的.那么什么事序列化呢?简单来说就是将对象转换为可以传输的二进制...

703
来自专栏拂晓风起

CString 在_UNICODE宏定义下和普通ASCII编码下的不同

1063
来自专栏salesforce零基础学习

salesforce 零基础学习(二十四)解析csv格式内容

salesforce中支持对csv格式的内容批量导入,可以使用dataloader,然而有些情况下,当用户没有相关权限使用dataloader导入情况下,就的需...

17610
来自专栏lgp20151222

解决com.fasterxml.jackson.databind.JsonMappingException: No suitable

加序列化(java 的实体类 implement Serializable等)或者处理序列化(改成jsonString就是一种处理方式哦)。

942

扫码关注云+社区