需要Spring4 @RequestBody不起作用

时间:2016-01-03 14:41:52

标签: spring rest spring-mvc

我将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) {

    ...
}

真的,这不是问题,因为从客户端,避免发送null,例如,设置空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可以为null。

super.doRestList(
    new HttpEntity<EntityFilterParam>(EntityFilterParam, this.getHttpHeaders()),
    HttpMethod.POST,
    urlBuilder);

在4.2.3和4.2.4上,要解决此问题,EntityFilterParam不能为null。 - &GT; 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主体有效负载不为空时它会有效,并且当它有效时会失败。

当错误发生时,在请求流进入控制器方法之前执行415,因此,不执行任何操作。

更新#2

另一个有趣的观点是,Jackson2将空值序列化为“null”字符串,然后正文有效负载不为空,填充为“null”。

1 个答案:

答案 0 :(得分:0)

我尝试过复制这个问题但没有太大成功。

您是否确认使用curl命令问题仍然存在? 像curl -vvv -X POST https://example.com/entity/12/50/10之类的东西(如果是这样,请在此处粘贴输出)

我对RestTemplatespring-android的此问题并非100%,但如果未提供任何内容类型,则默认情况下模板会添加"Content-Type: application/x-www-form-urlencoded"。如果是这种情况,为"DEBUG"配置"org.springframework.web"日志级别应显示类似

的内容
[INFO] [talledLocalContainer] org.springframework.web.HttpMediaTypeNotSupportedException: 
Content type 'application/x-www-form-urlencoded' not supported

我认为你应该设置Content-Type。你提到这个失败了 - 你能详细说明吗?