Java Spring Restful编辑-什么';这是保存更改的最佳做法

Java Spring Restful编辑-什么';这是保存更改的最佳做法,java,spring,hibernate,rest,Java,Spring,Hibernate,Rest,所以我有一个弹簧控制器: @Controller @RequestMapping("/user") public class UserController() { @RequestMapping(value = "/edit/{id}", method = RequestMethod.PUT) public @ResponseBody HTTPResponseDTO edit(@RequestBody String data, @PathVariable long id) {

所以我有一个弹簧控制器:

@Controller
@RequestMapping("/user")
public class UserController() {

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.PUT)
    public @ResponseBody HTTPResponseDTO edit(@RequestBody String data, @PathVariable long id) {
        // marshall data String to User entity
        ObjectMapper mapper = new ObjectMapper();
        User marshaledUser = mapper.readValue(data, User.class);
        User databaseUser = session.get(id, User.class);
        //hibernate things to save
        ...
        // session.save(user);
    }
数据字符串采用以下json格式:

{"name":"value1",
 "email":"value2",
 "note":"value3"}
响应的内容很简单,如下所示:

{"result":"success"}
当客户端传入数据json时,它将只传入正在编辑的值,例如:

{"email":"value2"}
在这种情况下,其他未提供的字段将被视为null

然而,“note”是一个可为空的字段,用户可以清除“note”字段-在我当前的设计中,当它这样做时,它将类似于:

{"note":null}
问题1: 因此,我的两难处境是:我如何判断用户是有意将其设置为null,还是仅仅因为它不是从数据字符串传入的,才将其设置为null

问题2: 当控制器接收到数据字符串时,我将有一个来自该数据的实体,然后我将按id查询数据库以获取现有的用户对象。合并这两个对象的最佳实践是什么?查找marshaledUser中存在哪些字段并将其设置为databaseUser看起来像是许多重复性工作:

if (marshaledUser.name != null) {
    databaseUser.name = marshaledUser.name;
}
if (marshaledUser.email != null) {
    databaseUser.email = marshaledUser.email;
}
if (marshaledUser.note != null) { // refer to question 1...
    databaseUser.note = marshaledUser.note;
}

一个对象可以有5个以上的字段-如果几乎相同的语句看起来不值得的话。。处理这个问题的最佳实践是什么?

我认为第一种方法是从数据库中读取目标对象并将其转换为json。然后使用下面描述的技术合并您的请求json

问题1:这就是我的困境:我如何判断用户是有意将其设置为null,还是仅仅因为它不是从数据字符串传入的才将其设置为null

你不能。因此,要么改变方法,始终传递一个完整的用户(我会这么做),而不是只传递几个字段,要么将JSON解组到映射(或JsonObject)。如果键存在,但具有空值,则该值已传递且为空。如果密钥不存在,则表示尚未传递

问题2:当控制器接收到数据字符串时,我将有一个来自此数据的实体,然后我将按id查询数据库以获取现有的用户对象。合并这两个对象的最佳实践是什么

与问题1相同。如果客户端传递一个完整的用户对象,而不是只传递几个字段,那么就简单多了。这个方法看起来就像

@RequestMapping(value = "/edit/{id}", method = RequestMethod.PUT)
public @ResponseBody HTTPResponseDTO edit(@RequestBody User user, @PathVariable long id)
    user.setId(id);
    session.merge(user);
}
或者至少,您可以简单地将传递的用户的每个字段复制到持久性字段,而不必关心它是否已被发送


此外,返回包含
result=success
的HttpResponseDTO也是多余的。如果该方法正常完成,它将返回200-OK HTTP状态。如果没有,那么您应该返回另一个HTTP状态代码。

您的代码片段没有提供有关如何解析数据的任何线索。@holmis83不确定这会有什么帮助,但我刚刚更新了问题以包含封送处理功能-我正在使用org.codehaus.jackson.map.ObjectMapper来完成此工作。相关: