Java file.encoding

简介: 问题 在idea上开发阿里云SCB接口时,发现一个问题,在main方法中执行方法: STDOrg org = CSBUtil.getRealOrgInfo("李氏餐饮店", "92120610MA16CR3U21"); 能够正确获取到信息。

问题

在idea上开发阿里云SCB接口时,发现一个问题,在main方法中执行方法:

STDOrg org = CSBUtil.getRealOrgInfo("李氏餐饮店", "92120610MA16CR3U21");

能够正确获取到信息。而使用idea启动项目,在项目的定时任务中执行相同的代码,却报出了:

signature verification failed

一模一样的代码,为什么执行结果会一个成功一个签名验证呢。

参数都是一样的,首先排除了参数问题。回头去查看SCB文档,发现:

SDK在将参数签名完成后,在发送给服务端之前,会把请求参数进行URLEncoder编码,编码方式为当前Java系统中的file.encoding系统参数所指定的值。

如请求参数中包含有中文,并且客户单的系统Charset编码参数与服务端的不一致的时候,当使用GET方式调用就可能出现验签失败的问题;

当这种情况发生时要检查两端的Charset编码是否一致, 可以在SDK客户端设置编码方式(如: -Dfile.encoding=UTF-8)使编码与服务器一致。如果你的中文参数是写死在Java程序代码中,需要保证源码的编码方式与服务端要求的一致,否则也会出现签名失败的问题.

怀疑是编码问题。于是在main方法和项目中分别使用:

System.out.println(System.getProperty("file.encoding"));

输出file.encoding属性,果然main中编码为UTF-8,项目中是GBK,至此确认了是编码问题。

main中执行成功,说明对方的编码是使用的UTF-8。因为我的项目在tomcat中部署,所以打开idea的tomcat部署设置:
_

在图中处填入jvm参数:

-Dfile.encoding=UTF-8

如果是jar启动,请在参数中也指定:

-Dfile.encoding=UTF-8

还可以直接修改tomcat配置文件,如果部署在Linux系统,可以在catalina.sh加入如下配置:

JAVA_OPTS="-Xms7168m -Xmx7168m -Dfile.encoding=UTF8"

如果是windows系统,则为:

set "JAVA_OPTS=-Xms7168m -Xmx7168m -Dfile.encoding=UTF8"

忽略内存配置,主要是-Dfile.encoding=UTF8,这时候就解决了file.encoding的问题。
当然如果编码和对方一致,不需做如上处理。

什么决定了file.encoding属性?

在main方法中,main方法所在类文件的编码决定了file.encoding属性。在启动java虚拟机时,idea自动将文件属性中的编码设置为运行时参数。所以在main中执行成功。

在使用tomcat启动项目时,如果不手动设置file.encodinng值,这时系统不知道用什么编码,所以只能采用系统默认编码,windows系统的默认编码是GBK,所以签名验证失败了。

可以看下面关于file.encoding的一段话:

This property is used for the default encoding in Java, all readers and writers would default to use this property. “file.encoding” is set to the default locale of Windows operationg system since Java 1.4.2. System.getProperty(“file.encoding”) can be used to access this property. Code such as System.setProperty(“file.encoding”, “UTF-8”) can be used to change this property. However, the default encoding can not be changed dynamically even this property can be changed. So the conclusion is that the default encoding can’t be changed after JVM starts. “java -Dfile.encoding=UTF-8” can be used to set the default encoding when starting a JVM.

附1:String获取默认编码源码:

查看String的getBytes方法,可以看到如下:

    public byte[] getBytes() {
        return StringCoding.encode(value, 0, value.length);
    }

继续:

    static byte[] encode(char[] ca, int off, int len) {
        String csn = Charset.defaultCharset().name();
        // 省略......
    }

看到获取默认编码的是Charset.defaultCharset(),查看:

    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;
    }

先去获取file.encoding属性,如果没有,默认返回"UTF-8"。在windows系统file.encoding=GBK,所以会导致文中的错误。

附2:idea控制台乱码处理

修改tomcatfile.encoding属性后,发现idea控制台乱码了,处理方法为打开Intellij的安装的bin目录,找到如下两个文件:

idea.exe.vmoptions
idea64.exe.vmoptions

根据系统是32位或64位选择其中一个配置文件,在配置文件中添加:

-Dfile.encoding=UTF-8
目录
相关文章
|
消息中间件 监控 安全
探究Kafka主题删除失败的根本原因
探究Kafka主题删除失败的根本原因
313 0
|
算法 Python
python:判断一个数是否为质数
python:判断一个数是否为质数
|
6天前
|
人工智能 安全 前端开发
老金发现个4277星的Claude Code企业神器,看完我直接跪了
老金拆解GitHub高星项目,教你用Claude Code打造自动化开发系统:Skills规范代码、Agents智能审查、Commands一键操作、Hooks自动触发、GitHub Actions定时巡检、MCP集成外部工具。4277星实战验证,企业级AI编程提效方案,文末附免费开源知识库。
275 12
|
4月前
|
存储 机器学习/深度学习 弹性计算
阿里云服务器租用价格参考:2核4G/4核8G/8核16G价格与选型指南
阿里云服务器2核4G、4核8G、8核16G配置价格参考,目前,2核4G配置按量收费最低0.225元/小时,包年包月平均月价最低47.52元,按年购买u1实例2核4G5M带宽仅需199元且续费不涨价;4核8G配置按量收费最低降至0.45元/小时,包年包月平均月价最低159.84元;8核16G配置按量收费最低0.9元/小时,按月租用平均月价最低319.68元。云服务器实例规格和配置不同,收费标准与活动价格也不同,本文将为您介绍这三大配置的收费标准、活动价格及选型策略,以供选择参考。
|
1月前
|
新能源 数据挖掘 关系型数据库
基于python大数据的新能源汽车数据分析系统
在全球能源与环境双重压力下,新能源汽车快速发展,产生海量数据。本文设计基于Python的新能源汽车数据分析系统,结合MySQL与B/S架构,实现数据高效管理与可视化分析,助力企业优化产品、提升服务,推动产业智能化与可持续发展。
|
2月前
|
安全 Java Unix
UUID v7 一文详解
UUID v7是RFC 9562定义的新型有序UUID,结合时间戳与随机数,兼具全局唯一性、时间有序性和隐私安全,适用于数据库主键与分布式系统,显著提升索引性能与系统效率。
|
运维 Linux Apache
如何使用`systemctl status`命令来查看服务状态?
如何使用`systemctl status`命令来查看服务状态?
1535 0
|
弹性计算 安全 Ubuntu
新手3分钟1Panel安装教程,使用阿里云服务器CentOS操作系统
在阿里云CentOS 7.9服务器上安装1Panel面板,包括远程连接ECS、执行安装命令、设置安装目录(默认/opt)、开启20410端口、配置安全入口和用户密码。记得在阿里云安全组中开放20410端口以访问面板。
1498 0
新手3分钟1Panel安装教程,使用阿里云服务器CentOS操作系统
|
存储 Kubernetes Ubuntu
helm部署mysql
在K8S部署mysql的步骤可用helm来简化,今天就来实战通过helm部署mysql,并且将之前遇到的问题和解决方法列出来
1984 1
helm部署mysql
|
消息中间件 Prometheus 监控
RabbitMQ性能调优指南
【8月更文第28天】RabbitMQ 是一个非常流行的消息队列中间件,它支持多种消息协议,并且可以轻松集成到各种系统中。随着应用的扩展,确保 RabbitMQ 在高负载环境下能够高效稳定地运行变得至关重要。本文将深入探讨如何通过配置、监控以及最佳实践来优化 RabbitMQ 的性能。
2340 1