【问题标题】:Spring REST @RequestBody is always emptySpring REST @RequestBody 始终为空
【发布时间】:2016-03-09 03:28:28
【问题描述】:

所以在我修复了“不支持 415 媒体”错误 (415 media not supported) 后,我遇到了一个新问题。我的RequestBody 总是空的。当我通过 Chrome PostMan 发送请求时,我总是得到一个只有空值的序列化实体。我在我的项目中使用Spring (4.2.3.RELEASE)Jackson-databind (2.6.3)jackson-core (2.6.3)。我在我的项目中使用基于注释的配置(@EnableWebMvc 让 spring 自动发现 HTTPMessageConverters)。


其他帖子

我知道 stackoverflow 上的其他帖子也有几乎相同的问题。然而他们没有给我答案。此外,大多数帖子都是针对较旧的 Spring 版本(4.0 之前),所以现在有些事情已经完全不同了。

类似帖子:

@RepsonseBody is always empty in Spring

Spring's @RequestBody providing empty string on POST

Using HttpServletRequest request


弹簧控制器

在我的 Spring @RestController 我有以下代码:

@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT)
public UserLocation updateUserLocation(@PathVariable("id") int id, UserLocation user) {        
        return user;        
}

我正在为我的数据绑定使用单独的模型类 (UserLocation)。这是因为这样我可以更好地控制我的 API 发送和接收的数据。


数据绑定类(UserLocation)

UserLocation 类由 3 个属性和一个构造函数以及所需的 getter 和 setter 组成。 (我可以公开这些属性,但我首先要解决这个问题)。

public class UserLocation {

    private Float latitude;

    private Float longitude;

    private Date lastActive;
}

JSON 正文

通过我的 AngularJS Ajax 调用 ($http.PUT),我使用以下数据调用 spring 控制器:

 {
    "latitude": 52.899370,
    "longitude": 5.804548,
    "lastActive": 1449052628407
 }

邮递员请求

我正在开发一个 Cordova 应用程序,因此为了测试请求而不需要将我的应用程序构建到我的手机上,我正在使用 Chrome PostMan 插件

我正在拨打以下电话:

URL:http://server:port/app/location/update/1

Method:PUT

Headers:Content-Type: application/json

Body:

{
    "latitude": 52.899370,
    "longitude": 5.804548,
    "timestamp": 1449052628407
}

请求结果

通过请求,我得到以下结果:

{"latitude":null,"longitude":null,"lastActive":null}

这意味着 Spring 确实为我的 UserLocation 类创建了一个新实例,但它没有用主体中的数据填充它。..


Spring PUT 方法

在 Spring 控制器中使用 PUT 方法时,实体不是立即更新吗?所以这意味着控制器中没有额外的逻辑来更新实体吗? (如果实体当然是 Hibernate/JPA 模型,可以更新)。


我似乎无法找出问题所在。有谁知道我做错了什么?


更新

@RequestBody 添加到我的控制器代码中:

@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT)
public UserLocation updateUserLocation(@PathVariable("id") int id, @RequestBody UserLocation user) {        
            return user;        
}

让我回到原来的问题 (415 media not supported)。添加它会引发 415 Media not supported 错误,我似乎无法修复。


已修复。解决方法如下

【问题讨论】:

  • 我认为这与问题无关,但是对于 PostMan,您发送的是 "lattitude" 而不是 "latitude""timestamp" 而不是 "lastActive"
  • @francescoforesti,感谢您的提醒。我以为我已经改变了这一点。我会在帖子中更改它。 (代码已经是最新的)
  • @Mr.wiseguy 你的问题解决了吗?
  • @TomSebastian,是的。在这种情况下,Driss Amri 和你们都给出了解决方案。整体解决方案可见stackoverflow.com/questions/34067101/…
  • 这可能不是一个答案,但我认为如果您将 Lombok 与 IntelliJ 一起使用并遇到此问题,它可能会有所帮助。对我来说,这是因为我使用带有 @Data 注释的 Lombok,这意味着 getter 和 setter 应该是隐式生成的,但它们不是。龙目岛做得不好。我尝试显式添加 getters/setters 方法并且它有效。

标签: java json spring rest put


【解决方案1】:

我在你的控制器中没有看到 UserLocation 对象的@RequestBody?还要确保你的属性有 getter 和 setter。

public UserLocation updateUserLocation(@PathVariable("id") int id, UserLocation user) {        

在执行 HTTP PUT 时,您必须添加额外的逻辑来将对象持久保存到数据库中。您将需要调用您的 DAO 或存储库来保存您的对象。通常,您将传入的 UserLocation 对象映射到您坚持的真实 JPA/Hibernate 实体。这不会自动发生。

【讨论】:

  • '@RequestBody' 自从引入 '@RestController' (Spring 4.0) 之后就不再需要了。我正在返回 Spring 为我制作的 UserLocation 实例。这会导致一个空的 JSON 字符串(请参阅我的帖子)。感谢您提供有关坚持的信息。然后我仍然需要实现该代码。
  • 据我所知,@RequestBody 不是可选的。我认为您将它与@ResponseBody 混淆了? docs.spring.io/spring/docs/current/javadoc-api/org/…
  • 添加@RequestBody 让我回到我原来的问题。这会引发 415 media not supported 错误。
  • 您是否使用邮递员发送“Content-Type: application/json”标头?
  • 每个@RequestBody bean 都必须实现 Serilizable 接口。
【解决方案2】:

问题是您错过了使用 @RequestBody 注释 UserLocation 参数

..updateUserLocation(@PathVariable("id") int id, @RequestBody UserLocation user)

还要确保为UserLocation 成员变量生成getterssetters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 2016-12-24
    相关资源
    最近更新 更多