【发布时间】:2014-02-17 01:39:33
【问题描述】:
我尝试使用@RequestBody byte[] data 作为自动 Base64 解码器,以便接收一些 RSA 加密数据,然后在我的服务中解密:
控制器:
@RequestMapping
void doIt(@RequestBody byte[] data) {
service.doIt(data);
}
服务:
void doIt(byte[] encryptedData) {
String testDataString = "hgLGtzF4D8tlJbVivQgaXXwfI9TbQ//PrYHEez5k93sqJSi17eLCa+r/cGNGvoxDRaPYONvP4yxW0ajKDFrusQ4V4owfhkijS9KzBOTjBeAVmA+5jBsZCdoxwCA65DiP5lJ+GRbn8CjcjCr4DaEWFbWHsyvY4NGGAQLuYv+PyZipfU9pXTEDsBb15NwaHlD5m7Z4CHWdWTt1ARvRaQs56Bp63/IEmGR7w4brA1+iuKPv83FLh0rsxyoJ+F8TeqtuPhm2fHTh1FiHn0Bpaqqoyd/cBl0/utSzu4qoZhB3AiVgLjnT6Iy9p5nVoAozxQo/Es59LrpGZfjYJer073jNIg==";
byte[] testDataBytes = Base64.decodeBase64(testDataString);
System.out.println(encryptedData.length);
System.out.println(testDataBytes.length);
System.out.println(new String(encryptedData).length());
System.out.println(Base64.encodeBase64String(testDataBytes).length());
System.out.println(new String(encryptedData).equals(Base64.encodeBase64String(testDataBytes)));
}
请求:
Content-Type: application/octet-stream
Request Payload:
hgLGtzF4D8tlJbVivQgaXXwfI9TbQ//PrYHEez5k93sqJSi17eLCa+r/cGNGvoxDRaPYONvP4yxW0ajKDFrusQ4V4owfhkijS9KzBOTjBeAVmA+5jBsZCdoxwCA65DiP5lJ+GRbn8CjcjCr4DaEWFbWHsyvY4NGGAQLuYv+PyZipfU9pXTEDsBb15NwaHlD5m7Z4CHWdWTt1ARvRaQs56Bp63/IEmGR7w4brA1+iuKPv83FLh0rsxyoJ+F8TeqtuPhm2fHTh1FiHn0Bpaqqoyd/cBl0/utSzu4qoZhB3AiVgLjnT6Iy9p5nVoAozxQo/Es59LrpGZfjYJer073jNIg==
输出:
(Spring) Byte length: 344
(test) Byte length: 256
(Spring) Base64 String length: 344
(test) Base64 String length: 344
Base64 String equals: true
如你所见:
请求中包含的数据与我放入源代码中的测试数据完全相同。
进行 Base64 编码后,两者的长度相同,并且“相等”
但是:字节数组的长度不同。
问题:
为什么Spring生成的byte[]更大? (尝试使用一些 RSA 私钥对其进行解码时没有用,因为 RSA 期望长度为 256。)
解决方法:
控制器:
@RequestMapping
void doIt(@RequestBody String data) {
service.doIt(Base64.decodeBase64(data));
}
【问题讨论】:
-
我无法理解你的问题。您提供的输出与您显示的测试代码无关,并且此测试代码对我没有任何意义:例如
new String(encryptedData)没有任何意义。 -
我的测试代码中有 5 个
System.out.println(...)。输出中有 5 个值(344、256、344、344、true)。使用new String(byte[]),您可以将字节数组转换为字符串。 Java 文档说:通过使用平台的默认字符集解码指定的字节数组来构造一个新的 {@code String}。。我只是用它来澄清问题。 ...我尝试描述的问题是:Spring 的 HttpMessageConverter 构造了一个比它应该更大的字节数组。如果你使用的东西依赖于每一位(比如 RSA 解密),它根本就不起作用。 -
但是字节数组不包含使用默认平台编码编码为字节的字符。它包含不代表有效字符的任意二进制字节。无论如何,您假设 Spring base64 解码请求主体以将其绑定到字节数组。事实并非如此。它按原样读取请求中的字节流,而不进行任何解码。
-
但它确实解码了它。如我的代码示例所示,我得到了
@RequestBody byte[] data,然后我只需执行new String(data)。如果我使用System.out.println(new String(data)),我可以在我的请求中看到我用作有效负载的相同字符串。所以它以某种方式起作用。甚至equals方法也返回true。 -
所以,你发送一个 base64 字符串,Spring 将它读取为一个字节数组,然后你从这个字节数组构造一个字符串,并看到你发送的 base64 字符串,对吧?如果是这样,那显然意味着 Spring 不会解码任何内容。如果它被解码,您将能够获取一个字节数组(例如包含 1、2、3、4、5),base-64 对其进行编码(这将产生字符串“AQIDBAU =”,在请求中发送它,并将 [1, 2, 3, 4, 5] 视为字节数组)。
标签: spring spring-mvc base64 bytearray converter