服务器乱码专栏问题一:String.getBytes()获取值乱码

2023-11-19

     本文建议阅读时长:15mins

        前记:最近笔者工作比较繁忙,导致本来应该有很多博客需要填坑,一直也没有静下心来好好整理下,今天蹭着夜深人静加之阵阵柔和的轻音乐正好先写上一篇,也算是为自己乱码专栏开个头,当然本专栏主要解决Tomcat服务器以及一些国产中间件在应用使用过程中的乱码情况的总结和原理解释,该篇作为乱码专栏的第一篇。

       回归正题:先说一下今天的出错场景,业务在前端传递String对象到后台,后台在将获取String对象将其转化为byte数组,存入数据库的一个过程。在存入数据库时,我们查看String对象是未乱码的,当我们在oracle数据库中读取查看的时候出现乱码。那么对于这个问题,是否有一个大致的解决思路了呢?

      解决方案:修改jvm属性-Dfile.encoding的编码等于GBK解决。原因简单描述为数据库的编码为gbk,而getBytes获取到byte数组的编码为utf-8,所以在查询过程中出现乱码。当然也可以通过修改oracle数据库的编码为UTF-8解决该问题,只要传入和读取的过程编码保持一致即可。具体分析原因可见下文。

        代码如图1所示,问题也在上面的正题中提到了,那么很明显笔者一开始想的是该jsonStr对象是不是乱码,在测试过程中发现是正常,那么该乱码过程就可能在存库过程和获取字节数组过程中出现乱码,于是乎笔者查了下当前数据库的编码,通过执行该sql语句,查询得知当前数据库的编码为GBK,查询sql如图2。

       结合上面的过程,那么问题清晰可见,我们只需要查明jsonStr.getBytes()的编码过程是否是以GBK编码即可,我们先写一个简单的demo如图3测试一下。基于JDK1.8.0_171测试。

        从上面的图4可以看出,file.encoding属性可以修改当前的getbytes()的编码。查看下面的代码块JDKString.getBytes()源码可知,获取编码的方式是可以通过file.encoding属性控制该值,因此对于上述的问题在后续我们也查出了乱码问题是由于数据库的编码和getbytes()默认的编码不一致导致的乱码,因此我们在知道原理的基础上修改服务器默认的file.encoding的编码,使其与数据库保持一致,即解决当前问题,也彻底搞清了整个过程。当然也可以修改数据库的编码,这样其实是同样的道理,只需要保持输入和输出编码一致,即不会产生乱码问题。

    java.lang.String.class
    public byte[] getBytes() {
      return StringCoding.encode(value, 0, value.length);//调用StringCoding对当前值进行编 
                                                       //码操作,并返回编码后的byte数组。
    }


    java.lang.StringCoding.class
    static byte[] encode(char[] ca, int off, int len) {
        String csn = Charset.defaultCharset().name();  //获取默认的charset编码。
        try {
            // use charset name encode() variant which provides caching.
            return encode(csn, ca, off, len);   //根据上面获取的编码对该对象进行编码操作
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }//下面方法代码忽略,有兴趣自己查看jdk源码
    }


     java.nio.charset.Charset.class
     public static Charset defaultCharset() {
        if (defaultCharset == null) { //如果当前编码为空,则读取jvm中的file.encoding的编码。
            synchronized (Charset.class) {
                String csn = AccessController.doPrivileged(
                    new GetPropertyAction("file.encoding"));
                Charset cs = lookup(csn);   //查找当前file.encoding定义的编码。
                if (cs != null)
                    defaultCharset = cs;    //查找到即返回当前编码,负责则默认返回UTF-8编码
                else
                    defaultCharset = forName("UTF-8");
            }
        }
        return defaultCharset;
    }

        常用几种编码介绍:ASCII、ISO8859-X、GBK、UTF-8等。

        编码介绍转载自常见的几种编码方式_科氏加速度的博客-CSDN博客_常见的几种编码方式

        ASCII:这是美国在19世纪60年代的时候为了建立英文字符和二进制的关系时制定的编码规范,它能表示128个字符,其中包括英文字符、阿拉伯数字、西文字符以及32个控制字符。它用一个字节来表示具体的字符,但它只用后7位来表示字符(2^7=128),最前面的一位统一规定为0

       GBK:GBKGB2312都是针对简体字的编码,只是GB2312只支持六千多个汉字的编码,而GBK支持1万多个汉字编码。而GB18030是用于繁体字的编码。汉字存储时都使用两个字节来储存。

      UTF-8:是Unicode字符的实现方式之一,它使用1-4个字符表示一个符号,根据不同的符号而变化字节长度。互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

       专栏下文预览:笔者对于乱码的问题结合公司同事和自己工作所得大概总结出乱码在请求/响应过程中主要有4个地方可能出现乱码,如下图5所示:对于每个过程中编码解码过程的乱码解决方案不尽相同,这个将在该专栏的后续文章中具体阐述分析。

     与君共勉: 编程就是个不断学习的工作,在结合源码和思考中寻求每一个问题的本源,这样我们才会在这条路上越走越远。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

服务器乱码专栏问题一:String.getBytes()获取值乱码 的相关文章

随机推荐

  • java 读取resource下的文件

    目录 一 普通main代码里使用 1 假设有如下结构的代码 1 main方法里复制resource下的文件 2 main方法里读取resource下的文件 2 假设有如下结构的代码 二 对于springboot项目读取resource下的资
  • JDBC数据源连接池(4)---自定义数据源连接池

    JDBC数据源连接池 4 自定义数据源连接池 续上文 JDBC数据源连接池 3 Tomcat集成DBCP 我们已经 了解了DBCP C3P0 以及Tomcat内置的数据源连接池 那么 这些数据源连接池是如何实现的呢 为了究其原理 我在这里写
  • Bootstarp入门教程(5) 排版(2)

    3 缩略语 当鼠标悬停在缩写和缩写词上时就会显示完整内容 Bootstrap实现了对HTML的
  • 如何理解和解决高并发

    如何理解高并发 高并发指的两方面 提升硬件 负载均衡 使用缓存 缓存一致性如何保证 限流 DNS负载均衡 线程池和分布式锁 总结 高并发指的两方面 同一时刻有大量的请求访问系统 有大量的请求并行访问系统 当大量请求短时间内涌入系统的时候 我
  • 2018中国汽车企业排行榜TOP10

    看排名 懂中国汽车 Aming 汽车行业变化很快 但是从上市车企的情况来看 可以看到具体的财报数字 因而可以知道一个更具体的发展情况 不过这次的排行榜主要针对2018年上半年中国已经上市的汽车企业 特别推出利润排行榜与销量排行榜 同时还有利
  • Dockerfile讲解和案例分享

    目录 dockerfile是在容器外部 构建三部曲 dockerfile基本知识 dockerfile执行流程 dockerfile 常用保留字 FROM MAINTAINER RUN EXPOSE WORKDIR USER ENV ADD
  • 40个学术网站

    40个学术网站 满足你的科研需求 2018 03 06 美国留学那点事 文 中外学术情报 微信号 Academic Information 科研工作者每天日常莫过于看文献 做实验 写论文 人生最郁闷的事情不过于是导师说 那个XX 帮我下载下
  • java secretkey用法_Java SecretKeyFactory.generateSecret方法代码示例

    本文整理汇总了Java中javax crypto SecretKeyFactory generateSecret方法的典型用法代码示例 如果您正苦于以下问题 Java SecretKeyFactory generateSecret方法的具体
  • Rust- 类型转换

    Rust is a statically typed language which means that it emphasizes on knowing the types of all variables at compile time
  • Python全栈开发【基础-05】基本数据类型

    专栏介绍 本专栏为Python全栈开发系列文章 技术包括Python基础 函数 文件 面向对象 网络编程 并发编程 MySQL数据库 HTML JavaScript CSS JQuery bootstrap WSGI Django Flas
  • LeetCode 124. 二叉树中的最大路径和 Python

    给定一个非空二叉树 返回其最大路径和 本题中 路径被定义为一条从树中任意节点出发 达到任意节点的序列 该路径至少包含一个节点 且不一定经过根节点 示例 1 输入 1 2 3 1 2 3 输出 6 示例 2 输入 10 9 20 null n
  • n-gram模型中的平滑方法

    当使用n gram模型对测试语料中的句子进行评估时 如果句子中包含在训练集中未出现的n元语法 则计算出来句子出现的概率为0 例如上一篇博客语言模型和n元语法中的例子 此时用该模型来计算下面句子的概率 因此 必须分配给所有可能出现的字符串一个
  • 关于Vue.js和React.js,听听国外的开发者怎么说?

    VueJS 与 ReactJS 到底怎么样如何 听听别人怎么说 使用所有新的库和框架 很难跟上所有这些库和框架 也就是说 这就需要您决定哪些是值得花时间的 让我们看看人们说什么 和Vue JS一起工作是很愉快的 我发现学习曲线很浅 然而 这
  • 【LeetCode75】第五十九题 第N个泰波那契数

    目录 题目 示例 分析 代码 题目 示例 分析 题目顾名思义 让我们求出第N个泰波那契数 也就是除了开头三个数之外 第四个数开始就是等于前三个数之和 不要和斐波那契数弄混了 斐波那契是前两个数的和 泰波那契是前三个数的和 也就是说当前数 我
  • docker容器内修改文件

    1 找到容器对应的ID 使用docker ps命令找到对应的镜像id 2 根据容器id进入到对应文件夹 执行命令 docker exec it 镜像id bin bash 3 进入对应目录 以MySQL为例 执行命令cd etc mysql
  • HTML学习

    HTML 我的第一个网页 基本标签 图片标签 链接标签 列表 表格 媒体元素 页面结构分析 iframe内联框架 表单 我的第一个网页
  • Hystrix 简单请求合并

    频繁的调用provider接太浪费了 就有了将多个请求合并为一个请求的方式 首先在provider中提供一个请求合并的接口 RestController public class UserController 既可以处理多个 也可以处理单个
  • elk之查询(单个或多个)type所有数据,条件查询,分页查询,排序

    java连接es 1 接口 查询 单个或多个 type所有数据 条件查询 分页查询 排序 param client param indexName param typeName public void searchAllStudent Tr
  • 服务计算hw7

    任务目标 设计一个 web 小应用 展示静态文件服务 js 请求支持 模板输出 表单处理 Filter 中间件设计等方面的能力 不需要数据库支持 基本要求 支持静态文件服务 支持简单 js 访问 提交表单 并输出一个表格 对 unknown
  • 服务器乱码专栏问题一:String.getBytes()获取值乱码

    本文建议阅读时长 15mins 前记 最近笔者工作比较繁忙 导致本来应该有很多博客需要填坑 一直也没有静下心来好好整理下 今天蹭着夜深人静加之阵阵柔和的轻音乐正好先写上一篇 也算是为自己乱码专栏开个头 当然本专栏主要解决Tomcat服务器以