【发布时间】:2016-04-07 06:35:43
【问题描述】:
我已经将 Spring 版本从 4.0.x 升级到 4.2.3(刚刚是 4.2.4),突然,@RequestBody 注释中的“required = false”属性无法按预期工作(就像在版本更改之前一样)。
带有 HttpStatus 415 的服务器响应 - 不支持的媒体类型。
控制器方法(每个 Spring 版本都相同)。
@RequestMapping(value = "/entity/{entityId}/{from}/{size}", method = RequestMethod.POST)
@ResponseBody
@JsonView(ToShowIn.App.class)
public ResponseEntity<?> getActiveEntityPaged(
@PathVariable int entityId, @PathVariable int from, @PathVariable int size,
@RequestBody(required = false) EntityFilterParam entityFilterParam) {
...
}
真的,这不是问题,因为从客户端,避免发送空,例如,设置空EntityFilterParam 实例足以解决它。但我想了解这个令人烦恼的问题是因为我的概念错误,还是因为新 Spring 版本的错误。
更新#1
版本
<spring-version>4.2.4.RELEASE</spring-version>
<jackson-2-version>2.3.2</jackson-2-version>
请求来自 Android 设备,使用 spring-android 库 (AKA RestTemplate)。
通用方法,适用于 4.0.x 版本,EntityFilterParam 可以为空。
super.doRestList(
new HttpEntity<EntityFilterParam>(EntityFilterParam, this.getHttpHeaders()),
HttpMethod.POST,
urlBuilder);
在 4.2.3 和 4.2.4 上,为解决此问题,EntityFilterParam 不能为空。 -> HttpStatus 415 - 不支持的媒体类型。修复它。
super.doRestList(
new HttpEntity<EntityFilterParam>((EntityFilterParam != null) ? EntityFilterParam : new EntityFilterParam(), this.getHttpHeaders()),
HttpMethod.POST,
urlBuilder);
在doRestList内部,执行RestTemplate请求。
final ResponseEntity<E[]> responseEntity =
(ResponseEntity) super.getRestTemplate()
.exchange(urlBuilder.getURL(), httpMhetod,
requestEntity, this.entityArray.getClass());
在哪里,urlBuilder.getURL()(URL 字符串,这里@PathVariables 工作正常)和this.getHttpHeaders() 返回下一个 HttpHeaders 配置。
RestFactory.httpHeaders = new HttpHeaders();
RestFactory.httpHeaders.setAuthorization(this.getAuthorization(user));
RestFactory.httpHeaders.set(HttpHeaders.CONNECTION, "Close"); // Switch off keep-alive.
RestFactory.httpHeaders.set(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.8");
RestFactory.httpHeaders.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
super.getRestTemplate() 是单例方法,它返回使用我自己的 CloseableHttpClient 配置设置的 RestTemplate 实例。
我知道HttpHeaders.CONTENT_TYPE对于application/json是缺失的,但是有意识的,其实在http body的payload不为空的时候有效,为空的时候就失败了。
发生错误时,在请求流进入控制器方法之前执行415,因此不执行任何操作。
更新#2
另一个有趣的点,Jackson2 将 null 值序列化为“null”字符串,那么 body 的 payload 就不是 null,而是用“null”填充。
【问题讨论】:
-
“已经停止工作”是什么意思?当你省略身体时,你会得到一个例外吗?你得到什么错误?
-
服务器返回 415 Http 状态(不支持的媒体类型)。
-
令人惊讶,因为我报告了这个错误,并且它已在 4.2.2 中修复。见jira.spring.io/browse/SPR-13417
-
因此,在 4.2.3 和 4.2.4 中,该错误又回来了。 :(
-
对 SPR-13417 的修复还附带了一个单元测试,它仍然是绿色的。我已经尝试过以前的 repro 项目 (github.com/spring-projects/spring-framework-issues/tree/master/…),它仍然适用于 4.2.2、4.2.3 和 4.2.4。您能否提供有关此问题的更多详细信息:HTTP 请求标头,Jackson 视图的代码示例 + Controller 方法返回的对象?
标签: spring rest spring-mvc