在springboot或者ssm中,使用zkcurator远程操作服务端的zookeeper创建新节点时,出现编码或解码问题
编码和解码
由于我使用的
linux
服务器是
centos8
,
centos7
一样,差别不大,我的默认为
en_US.UTF-8
,说明在该系统下使用的语言是
US
的
UTF-8
,US只是影响了
linux
在
命令行
界面或者
图形化
界面无法输入中文,但支持UTF-8解码和编码,这是理论,下面我们来实现是否是如此
1.默认编码和默认解码
下面展示的都是局部代码
编码采用默认编码,即getBytes()
转成字节存储时默认解码为ISO-8859-1
String encodeString = "测试";
client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(Ids.OPEN_ACL_UNSAFE)
.forPath("/testNode", encodeString .getBytes());
解码采用的是默认解码ISO-8859-1
,
String decodeString = new String(event.getData().getData());
有兴趣可以看看源码
static byte[] encode(char[] var0, int var1, int var2) {
try {
return encode("ISO-8859-1", var0, var1, var2);
static char[] decode(String var0, byte[] var1, int var2, int var3) throws UnsupportedEncodingException {
String var5 = var0 == null ? "ISO-8859-1" : var0;
结果中文部分出现乱码,猜想编码正常,解码异常,那就改变解码方式
2.默认编码和UTF-8/utf-8解码
编码采用默认编码,即getBytes()
转成字节存储时默认编码为ISO-8859-1
String encodeString = "测试";
client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(Ids.OPEN_ACL_UNSAFE)
.forPath("/testNode", encodeString .getBytes());
解码采用的是UTF-8
String decodeString = new String(event.getData().getData("utf-8"));
解码后依然出现中文乱码,而且还报错,那可以肯定的是utf-8解码是不可行的,先证明是解码问题
3.默认编码和GBK/gbk解码
编码采用默认编码
String encodeString = "测试";
client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(Ids.OPEN_ACL_UNSAFE)
.forPath("/testNode", encodeString .getBytes());
解码采用的是GBK
String decodeString = new String(event.getData().getData("gbk"));
毫无疑问,输出正常,看了还真不是编码问题,对不同解码方式进行尝试
4.UTF-8/utf-8编码和UTF-8/utf-8解码
编码采用UTF-8
String encodeString = "测试";
client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(Ids.OPEN_ACL_UNSAFE)
.forPath("/testNode", encodeString .getBytes("utf-8"));
解码采用的是默认UTF-8
String decodeString = new String(event.getData().getData("utf-8"));
输出正常,猜想是解码和编码需要配套使用,或者要支持不同编码类型的转换,而且还要看linux支持的编码,一般推荐使用utf-8
既然这么认为,那我就把编码改成GBK
存放到zookeeper
,看看取出时能不能成功转成UTF-8
结果输出乱码
转换失败,中文部分乱码,是编码出错还是解码出错,第五步我做了GBK
编码和GBK
解码,没有乱码出现,说明GBK
编码是允许的
5.GBK/gbk编码和GBK/gbk解码
编码采用GBK
String encodeString = "测试";
client.create().creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(Ids.OPEN_ACL_UNSAFE)
.forPath("/testNode", encodeString .getBytes("gbk"));
解码采用的是默认解码GBK
String decodeString = new String(event.getData().getData("gbk"));
解码后正常输出,不会出现乱码
6.总结
- gbk和utf-8编码和解码在字符集为zh_US.UTF-8的lnux机器是允许的,不过utf-8和gbk不允许相互转换;
- 这里演示中得到一个结论,默认编码时,解码可以是gbk而不能是utf-8;
- 建议使用相同的编码和解码,推荐utf-8;
- 对于gbk编码一般在控制台输出时采用,比如tomcat默认的utf-8,一般修改日志配置文件为gbk,控制台tomcat日志初始乱码就正常了,而idea控制台采用系统的字符集,所以建议采用gbk