Spring @RequestBody 不查找对象

yst*_*an- 3 hibernate spring-mvc

我正在使用 Spring-MVC/Hibernate 编写 REST 服务,似乎 @RequestBody 是接受一堆参数并将其映射到 POJO 的推荐方法。然而,似乎通过 POST 发送的 ID 被转换为 null 而不是实际的对象。一些示例代码会更好地解释。

服务很简单:

@ResponseBody
@RequestMapping(value="add", method = RequestMethod.POST)
public ServiceResponse addTx(@RequestBody Transaction tx) {
    ...
    return ServiceResponse;
}
Run Code Online (Sandbox Code Playgroud)

交易实体有一个账户实体:

@Entity
@Table(name="Transaction")
public class Transaction {
    @Column(name="code")
    private String code;
    @OneToOne
    @JoinColumn(name="accountId")
    private Account account;
    @Column(name="amount")
    private int amount;
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的浏览器发出的 POST 请求负载如下:

{code: "ascasc", amount: 23, accountId: 1, ... }
Run Code Online (Sandbox Code Playgroud)

但在服务器端,构造的 Transaction 对象的 Account 值为 null。即 accountId 1 不会被转换为 Account 对象。我错过了什么吗?

Boh*_*rdt 5

您所描述的行为是正确的。当您使用 时@RequestBody,它对持久层一无所知,它只是将请求正文映射到目标对象。

因此,当您发布包含 的 JSON 时accountId,Spring 会尝试查找accountId目标对象的属性,但它不存在(目标对象只有account属性),因此accountId不会被映射。如果您希望accountId正确映射,则必须像 那样 POST JSON {..., account: { id: 1 }, ...}


顺便说一句,使用传输对象作为 Web 服务的请求/响应对象,然后将它们映射到实体对象是一种相当常见的模式。然后,您可以accountId在传输对象中拥有属性,然后在组装实体时使用该值。原因之一可能是您不想从 Web 服务返回某些模型属性,并且您不想用@JsonIgnore注释污染您的模型层。这种方法还可以让您更改实体类(例如重命名某些属性),而不必破坏 API。然而,这会增加额外的复杂性,因此您必须决定是否值得。