【问题标题】:Spring Restful edit - what's the best practice to save changesSpring Restful 编辑 - 保存更改的最佳实践是什么
【发布时间】:2014-11-24 15:54:18
【问题描述】:

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

@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"}

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

但是“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 个字段 - 5 个如果几乎相同事物的语句看起来不值得。处理此问题的最佳实践是什么?

【问题讨论】:

  • 您的代码 sn-p 不提供有关您如何解析数据的任何线索。
  • @holmis83 不知道这有什么帮助,但我刚刚更新了问题以包含元帅功能 - 我正在使用 org.codehaus.jackson.map.ObjectMapper 来完成这项工作。

标签: java spring hibernate rest


【解决方案1】:

问题 1:所以这是我的两难选择:我如何判断用户是故意将其设置为 null,还是仅因为它不是从数据字符串中传入而为 null?

你不能。所以,要么改变你的方法,总是传递一个完整的用户(这就是我会做的),而不是只传递几个字段,或者将 JSON 解组为 Map(或 JsonObject)。如果键存在,但具有空值,则该值已被传递并且为空。如果密钥不存在,那么它还没有被传递。

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

同问题 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 状态代码。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-07
      • 2017-01-13
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多