Spring的@RequestBody byte[]有什么问题(长度比预期大)?

Ben*_*n M 6 arrays base64 spring spring-mvc converters

我尝试使用@RequestBody byte[] data自动 Base64 解码器,以便接收一些 RSA 加密数据,然后在我的服务中解密:

控制器:

@RequestMapping
void doIt(@RequestBody byte[] data) {
    service.doIt(data);
}
Run Code Online (Sandbox Code Playgroud)

服务:

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)));
}
Run Code Online (Sandbox Code Playgroud)

要求:

Content-Type: application/octet-stream

Request Payload: 
hgLGtzF4D8tlJbVivQgaXXwfI9TbQ//PrYHEez5k93sqJSi17eLCa+r/cGNGvoxDRaPYONvP4yxW0ajKDFrusQ4V4owfhkijS9KzBOTjBeAVmA+5jBsZCdoxwCA65DiP5lJ+GRbn8CjcjCr4DaEWFbWHsyvY4NGGAQLuYv+PyZipfU9pXTEDsBb15NwaHlD5m7Z4CHWdWTt1ARvRaQs56Bp63/IEmGR7w4brA1+iuKPv83FLh0rsxyoJ+F8TeqtuPhm2fHTh1FiHn0Bpaqqoyd/cBl0/utSzu4qoZhB3AiVgLjnT6Iy9p5nVoAozxQo/Es59LrpGZfjYJer073jNIg==
Run Code Online (Sandbox Code Playgroud)

输出:

(Spring) Byte length:          344
(test)   Byte length:          256
(Spring) Base64 String length: 344
(test)   Base64 String length: 344
         Base64 String equals: true
Run Code Online (Sandbox Code Playgroud)

如你看到的:

  • 该请求包含与我放入源代码中的测试数据完全相同的数据。

  • 进行 Base64 编码后,两者具有相同的长度并且“相等”

  • 但是:字节数组的长度不同。

问题:

为什么byte[]Spring生成的比较大呢?(当尝试使用某些 RSA 私钥对其进行解码时,这是没有用的,因为 RSA 期望的长度为 256。)

解决方法:

控制器:

@RequestMapping
void doIt(@RequestBody String data) {
    service.doIt(Base64.decodeBase64(data));
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*n M 4

在 Spring 中,您可以找到将请求内容转换为所需格式的ByteArrayHttpMessageConverter方法(在本例中为)。readInternalbyte[]

代码(Spring 4.0.0.RELEASE)

long contentLength = inputMessage.getHeaders().getContentLength();
ByteArrayOutputStream bos = new ByteArrayOutputStream(contentLength >= 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE);
StreamUtils.copy(inputMessage.getBody(), bos);
return bos.toByteArray();
Run Code Online (Sandbox Code Playgroud)

ByteArrayOutputStream第二行表示:*如果请求有效负载不为空,则获取其内容长度,并以此设置容量。否则,如果内容长度 < 0,则将其设置为 StreamUtils.BUFFER_SIZE (= 4096)。*

我不太确定为什么要这样实现,但这就是它实际的工作原理。