Spring Boot Post请求方法没有所有Object值

时间:2017-04-07 20:12:09

标签: spring hibernate request spring-data-jpa thymeleaf

使用Spring Boot,Hibernate JPA和Thymeleaf。

我有一个Order数据库表,目前只保存1条记录。此记录有几列,并且在任何表单上都看不到某些列,它们是在保存订单时设置的,例如创建日期。

在下面的GET请求中,我选择特定的Order,并按预期将所有值返回到Order对象。

这是我的GET请求方法:

@RequestMapping(value = "/editorder/{orderId}", method = RequestMethod.GET)
public String editOrderGet(Model model, @PathVariable long orderId)
{
    Order order = orderService.findById(orderId);
    model.addAttribute("order", order);
    return "/editorder";
}

这是我使用Thymeleaf的编辑订单html表单的一小部分,使用th:object将Order对象绑定到表单,如下所示:

<form role="form" th:action="@{/editorder}" th:object="${order}" method="post">
   <input type="hidden" th:field="*{orderId}"/>
   <button type="submit" class="btn btn-primary">Update Order</button>
   .
   .
</form>

这是我的POST请求方法:

@RequestMapping(value = "/editorder", method = RequestMethod.POST)
public String editOrderPost(Model model, 
        @Valid @ModelAttribute("order") Order order, BindingResult bindingResult)
{
    //rest of code here
}

如您所见,在GET请求中,我将Order对象添加到模型中。 在html表单上,我将Order对象绑定到整个表单。然后在POST请求中我得到Order对象。

但是在POST上它被视为一个新订单,只包含表单中指定的字段,例如它不包含GET请求中看到的创建日期。

我的问题是:

我是否遗漏了某些内容,或者我是否明确需要将每个字段设置为表单上的隐藏字段?

1 个答案:

答案 0 :(得分:1)

在您的GET响应中,您可能会将整个Order对象返回到Model中,但是Thymeleaf在尝试从模板构建实际html时将只选择构建模板所需的项目。因此,只有表单中使用的字段用于在html页面中构建表单。

因此,当您将表单重新提交到POST服务时,只会重新发布表单中可用的字段。

如果您希望在页面上显示这些字段,请在表单中添加这些字段。 Thymeleaf选择它们并在表格中显示。如果你不希望它们显示在页面中,那么就忽略它们。您在POST中收到的Order对象将没有该字段,因为它们不是原始形式。

你可以通过查询数据库来获取它们,任何你如何将订单ID保存为隐藏字段。

public String editOrderPost(Model model, 
        @Valid @ModelAttribute("order") Order order, BindingResult bindingResult){
    Order orderFromDB = orderService.findById(order.getId()); 
    // Code to update the orderFromDB from order object
    orderService.save(order);
}

这会将更新的字段保存到数据库中。

通常,将Entity对象公开给API并不是一个好习惯。尝试使用DTO /值对象。这只能包含定义业务字段的字段。你也可以使用像dozer / mapstruct / modelmapper这样的BeanMapper框架从DTO复制到Entity,反之亦然。