关于String.getBytes()使用的问题

今天遇到了一个问题,其他部门在调用我们开放平台接口时,总出现签名错误,

(客户端和服务器使用的是同一个签名算法JAR包)

问题说明:

1, 在项目部署到tomcat上调用接口时,会出现签名错误。

2, 如果直接在java的main函数调用接口,则不会出现。

注:1,2的请求参数都完全相同,并使用同一个签名算法

签名算法的流程如下:

1、将所有POST参数(key-value)按照key升序将value拼接在一起;

2、将1的结果的首尾加上appSecret值,例如:appSecretvalue1value2appSecret

3、将2的结果进行MD5大写加密。

在2中得到的结果是一样的,但在第3步时出现了不同

MD5算法怎么会不同呢?JAVA里面MD5算法不是统一的吗?

仔细查看了源码,发现是在调用s.getBytes()方法时出现了不同,代码如下:

getMD5String(s.getBytes());

s为需要MD5的字符串

在网上查了下普遍说s.getBytes()方法是得到一个操作系统默认的编码格式的字节数组,在不同的OS系统下,返回的结果不一样。

既然这样,那么我在tomcat中和JAVA的main函数中调用s.getBytes()应该获取的应该改是一样的?我都是在本机运行的,操作系统都是window7,默认编码都是GBK,Why???

查看了s.getBytes()方法源码可以看到,默认是使用:

Charset.defaultCharset()

查看官方JDK对其解释:

public static Charset defaultCharset()

Returns the default charset of this Java virtual machine.

The default charset is determined during virtual-machine startup and typically depends upon the locale and charset of the underlying operating system.

获取JVM默认的的编码格式,其默认编码格式又依赖于底层操作系统的编码格式。

可以猜测如果设置了JVM的编码格式,则使用此编码,如果没有设置则使用操作系统的默认编码格式,那又是在哪设置的JVM的编码格式呢?

 

Debug一下:

1, 通过java的main函数运行,在debug模式下:

1

可以看到在运行时,指定了默认编码为UTF-8

 

2, 通过tomcat启动运行,在debug模式下

2

可以看到,指定的编码格式为GBK

 

更改文件的编码格式为ISO-8859-1,在进行测试

1, 使用java的main函数直接运行

3

可以看到编码格式变为ISO-8859-1了

2, 使用tomcat运行项目:

4

可以看到其编码格式还是GBK的

 

可以得出结论:

1, 在eclipse中使用java的main函数运行程序,其JVM的默认编码为文件的默认编码

2, 在tomcat是运行项目,JVM不是使用文件的默认编码,若tomcat未指定编码,则使用系统的默认编码

 

那么我们要统一编码,该怎么做呢?可以在s.getBytes()方法中加入编码格式,如:s.getBytes(“UTF-8”),统一使用UTF-8的编码格式,我们来试试

 

1, 使用java的main函数直接运行,得到的结果:

      file.encode: ISO-8859-1

      sign: 2B6C5716E9A7D270DA299DCA1A737FF0

2, 使用tomcat运行项目,得到的结果:

      file.encode: GBK

      sign: 2B6C5716E9A7D270DA299DCA1A737FF0

其他方法:

(1) 另外,tomcat也可以指定JVM的编码格式,在catalina.bat或catalina.sh中修改

set “JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%”

为:

set “JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dfile.encoding=UTF-8”

(2) 修改系统的默认编码,目前服务器一般使用linux服务器,将服务器的编码设置为UTF-8

 

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注