服务器乱码专栏问题一: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 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • 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服务器以