Spring REST 控制器不处理 gzip 压缩输入

Posted

技术标签:

【中文标题】Spring REST 控制器不处理 gzip 压缩输入【英文标题】:Spring REST controller does not handle gzip compressed input 【发布时间】:2020-12-06 14:48:39 【问题描述】:

我已经根据文档设置了我的 Spring Boot 应用程序,通过在 application.properties 中设置以下属性来处理 HTTP 服务器压缩:

server.compression.enabled=true
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css

不过,在收到 gzip 压缩输入后,Spring REST 控制器似乎无法解码输入。我收到了HttpMessageNotReadableException。以下是日志中的相关行:

2020-08-17 14:44:41,201 DEBUG [http-nio-9972-exec-4] org.springframework.web.filter.CommonsRequestLoggingFilter: BEFORE REQUEST: POST /api/v1/observerConfiguration/observer, client=127.0.0.1, headers=[accept-encoding:"gzip", "deflate", content-encoding:"gzip", "deflate", accept:"*/*", user-agent:"Java/11.0.8", host:"localhost:9972", connection:"keep-alive", transfer-encoding:"chunked", Content-Type:"application/json;charset=UTF-8"]]
2020-08-17 14:44:41,512 WARN  [http-nio-9972-exec-4] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver: Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (PushbackInputStream); line: 1, column: 2]]
2020-08-17 14:44:41,513 DEBUG [http-nio-9972-exec-4] org.springframework.web.filter.CommonsRequestLoggingFilter: AFTER REQUEST: POST /api/v1/observerConfiguration/observer, client=127.0.0.1, headers=[accept-encoding:"gzip", "deflate", content-encoding:"gzip", "deflate", accept:"*/*", user-agent:"Java/11.0.8", host:"localhost:9972", connection:"keep-alive", transfer-encoding:"chunked", Content-Type:"application/json;charset=UTF-8"]]

是否需要一些额外的配置才能让 Spring Boot 处理压缩的 JSON 有效负载?

Spring Boot 版本是v2.3.2.RELEASE

【问题讨论】:

【参考方案1】:

我相信server.compression.enabled=true 是关于response,而不是request。 对于request,您可能需要编写自己的Filter 或使用任何现有的。 在互联网上查找,我可以找到 this 并提供一些可能有帮助的示例。

【讨论】:

【参考方案2】:

Spring 不提供此功能,因为它是 Web 服务器的一部分。 处理此问题的一种方法是提供一个过滤器/组件来处理传入请求。

请参阅此答案以获取更多信息和提示,如Erik 建议的那样实施它:How to decode Gzip compressed request body in Spring MVC

【讨论】:

关于 Spring 的一件事是肯定的。它从不开箱即用。

以上是关于Spring REST 控制器不处理 gzip 压缩输入的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 power mock 对 Spring Boot Rest 控制器和异常处理程序进行单元测试

多个排序可选查询 - 带有分页的Spring REST控制器配置

REST 控制器中的 Spring Boot 绑定和验证错误处理

如何使用 Spring 异常处理 POST REST 更正错误状态代码

Spring的Restful

Spring Security + REST 控制器 Post 方法不显示用户名