java默认字符编码问题及解决

 更新时间:2026年06月17日 11:37:33   作者:las_learn  
这篇文章主要介绍了java默认字符编码问题及解决过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题现象

在进行宝蓝德适配时发现主机的授权信息中客户名称和部门名称展示为乱码, 针对该问题进行分析,

现象如下:

分析思路

分析乱码的原因

分析获取的该参数的值方法:

public String getBin(Pointer lic, String column) {
    Pointer buf = new Memory(256);
    IntByReference bufsize = new IntByReference();
    bufsize.setValue(256);
    if (INSTANCE.license_get_bin(lic, column, buf, bufsize) < 0) {
        return "";
    }
    byte[] value = buf.getByteArray(0, bufsize.getValue());
    return new String(value);
}

可以看出就是通过jni函数获取对应字段的byte数组,转换为字符串,通过远程debug连接后,发现获取的字符串,发现确实是乱码, 进一步分析从jni中获取的byte数组列表,得到的数据为[-28, -72, -83, -24, -81, -107, -25, -84, -74, -23, -98, -81, -26, -104, -112], 通过ai分析得到如下结果:

这组 byte 按 UTF-8 解码对应的字符串是:

测试服务器:

可用下面代码验证:
byte[] b = new byte[] {-28, -72, -83, -24, -81, -107, -25, -84, -74, -23, -98, -81, -26, -104, -112
};
System.out.println(new String(b, StandardCharsets.UTF_8));

说明byte数组转换为字符串确实为预期的值,只能说明是new String(value);时使用到java进程的默认字符集导致的即对应的字符集非UTF-8编码

分析默认编码为何非预期UTF-8

需要分析默认的charset的获取方式,阅读Charset的源码中可以看到,是通过读取file.encoding的property获取。

public static Charset defaultCharset() {
    if (defaultCharset == null) {
        synchronized (Charset.class) {
            String csn = AccessController.doPrivileged(
                new GetPropertyAction("file.encoding"));
            Charset cs = lookup(csn);
            if (cs != null)
                defaultCharset = cs;
            else
                defaultCharset = forName("UTF-8");
        }
    }
    return defaultCharset;
}

通过arthas工具,查看问题节点的file.encoding非UTF-8编码,而为ANSI_X3.4-1968类型。

接下来分析file.encoding是如何设置的,通过分析jdk和从AI结合分析,得到在jvm启动时会尝试从本地的locale中获取,会从LC_CTYPE中获取encoding信息,实际实现为en_US.UTF-8 ,设置encoding就是UTF-8 部分(有兴趣的可以设置LC_CTYPE参数,查询file.encoding值)。

具体jdk代码如下:

setlocale(LC_ALL, "");
if (ParseLocale(env, LC_CTYPE,
                   &(sprops.format_language),
                   &(sprops.format_script),
                   &(sprops.format_country),
                   &(sprops.format_variant),
                   &(sprops.encoding))

在bash中执行locale命令, 获取到的locale输出却是utf-8类型

综合现象和默认值对比,只能是启动java进程的进程上下文中配置的locale被单独设置导致的,在进程启动脚本中添加输出locale的日志,发现确实被修改为POSIX了,非xxx.utf-8. 

解决方案

  • 方案一: 在bes.sh执行启动bes程序前设置locale为UTF-8编码即可。
  • 方案二: 已知会从系统properties中获取,可以加-Dfile.encoding=UTF-8参数的方式设置

总结

1、为了保障程序的通用性,如果已知字符集时new String, IO流操作场景,最好都配置上字符集

2、程序设计时注意程序设置环境变量或参数对子进程的影响。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 对arraylist中元素进行排序实例代码

    对arraylist中元素进行排序实例代码

    这篇文章主要介绍了对arraylist中元素进行排序实例代码,还是比较不错的,这里分享给大家,供需要的朋友参考。
    2017-11-11
  • Spring Boot+Drools规则引擎整合详解

    Spring Boot+Drools规则引擎整合详解

    本篇文章主要介绍了Spring Boot+Drools规则引擎整合,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java单例模式利用HashMap实现缓存数据

    Java单例模式利用HashMap实现缓存数据

    这篇文章主要为大家详细介绍了Java单例模式利用HashMap实现缓存数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Springboot如何通过流返回文件

    Springboot如何通过流返回文件

    这篇文章主要介绍了Springboot如何通过流返回文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java对zip,rar,7z文件带密码解压实例详解

    Java对zip,rar,7z文件带密码解压实例详解

    在日常业务中,会遇到一些琐碎文件需要打包到一个压缩包中上传,业务方在后台接收到压缩包后自行解压,然后解析相应文件。而且可能涉及安全保密,因此会在压缩时带上密码,要求后台业务可以指定密码进行解压。本文将用Java解决这一问题,需要的可以参考一下
    2022-07-07
  • Spring Boot实战之模板引擎

    Spring Boot实战之模板引擎

    这篇文章主要介绍了Spring Boot实战之模板引擎,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • SpringBoot整合SpringSecurity和JWT的示例

    SpringBoot整合SpringSecurity和JWT的示例

    这篇文章主要介绍了SpringBoot整合SpringSecurity和JWT的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Redis中String字符串和sdshdr结构体超详细讲解

    Redis中String字符串和sdshdr结构体超详细讲解

    这篇文章主要介绍了Redis中String字符串和sdshdr结构体,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-04-04
  • Springboot @Configuration与自动配置详解

    Springboot @Configuration与自动配置详解

    这篇文章主要介绍了SpringBoot中的@Configuration自动配置,在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制,只有把这些都搞清楚了,我们在之后使用才会更加得心应手
    2022-07-07
  • java hutool工具类处理JSON的使用方法

    java hutool工具类处理JSON的使用方法

    hutool是一个java基础工具类,该工具类经过长期的发展,API已经非常齐全,下面这篇文章主要给大家介绍了关于java hutool工具类处理JSON的使用方法,需要的朋友可以参考下
    2024-04-04

最新评论