Spring Restful编辑 - 保存更改的最佳实践是什么

时间:2014-11-24 15:54:19

标签: 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) {
        // 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"}

responseDTO看似简单:

{"result":"success"}

当客户端传入数据json时,它只会传入正在编辑的值,例如:

{"email":"value2"}

在这种情况下,其他非提供的字段将被视为null。

然而"注意"是一个可以为空的字段,用户可以清除" note" field - 在我目前的设计中,当它这样做时,它将是:

{"note":null}

问题1: 所以这就是我的困境:如何判断用户是否有意将其设置为null,或者只是因为它没有从数据字符串传入而为空?

问题2: 当控制器正在接收数据字符串时,我将有一个来自此数据的实体,然后我将通过id查询数据库以获取现有的User对象。合并这两个对象的最佳做法是什么?查找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个字段 - 如果几乎相同的事情看起来不值得5,那么..处理这个问题的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

  

问题1:所以这就是我的困境:如何判断用户是否有意将其设置为null,或者只是因为它没有从数据字符串传入而为空?

你做不到。所以,要么改变你的方法,要么总是传递一个完整的用户(这就是我要做的事情),而不仅仅是几个字段,或者将JSON解组为Map(或JsonObject)。如果密钥存在但具有空值,则传递的值为null。如果密钥不存在,则表示尚未通过。

  

问题2:当控制器正在接收数据字符串时,我将有一个来自此数据的实体,然后我将通过id查询数据库以获取现有的User对象。合并这两个对象的最佳做法是什么?

与问题1相同。如果客户端传递完整的User对象而不是仅传递几个字段,那将会简单得多。该方法看起来像

@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状态代码。

答案 1 :(得分:0)

我认为1方法是从数据库中读取目标对象并将其转换为json。然后使用描述here

的技术合并您的请求json