Spring部分更新对象数据绑定 [英] Spring Partial Update Object Data Binding

查看:78
本文介绍了Spring部分更新对象数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试在Spring 3.2中实现一个特殊的部分更新功能。我们使用Spring作为后端,并有一个简单的Javascript前端。我无法找到一个直接的解决方案来满足我们的要求,即 update()函数应该采用任意数量的字段:值并相应地更新持久性模型。

We are trying to implement a special partial update function in Spring 3.2. We are using Spring for the backend and have a simple Javascript frontend. I've not been able to find a straight-forward solution to our requirements, which is The update() function should take in any number of field:values and update the persistence model accordingly.

我们对所有字段进行了内联编辑,因此当用户编辑字段并确认时,id和修改后的字段将作为json传递给控制器​​。控制器应该能够从客户端(1到n)接收任意数量的字段并仅更新那些字段。

We have in-line editing for all of our fields, so that when the user edits a field and confirms, an id and the modified field get passed to the controller as json. The controller should be able to take in any number of fields from the client (1 to n) and update only those fields.

例如,当id ==的用户时1编辑他的displayName,发布到服务器的数据如下所示:

e.g., when a user with id==1 edits his displayName, the data posted to the server looks like this:

{"id":"1", "displayName":"jim"}

目前,我们在UserController中有一个不完整的解决方案,如下所述: / p>

Currently, we have an incomplete solution in the UserController as outlined below:

@RequestMapping(value = "/{id}", method = RequestMethod.POST )
public @ResponseBody ResponseEntity<User> update(@RequestBody User updateUser) {
    dbUser = userRepository.findOne(updateUser.getId());
    customObjectMerger(updateUser, dbUser);
    userRepository.saveAndFlush(updateUuser);
    ...
}

此处的代码有效,但有一些问题: @RequestBody 创建一个新的 updateUser ,填写 id displayName CustomObjectMerger 将此 updateUser 与数据库中对应的 dbUser 合并,更新 updateUser 中包含的唯一字段。

The code here works, but has some issues: The @RequestBody creates a new updateUser, fills in the id and the displayName. CustomObjectMerger merges this updateUser with the corresponding dbUser from the database, updating the only fields included in updateUser.

问题是Spring填充了<$ c $中的一些字段c> updateUser ,带有默认值和其他自动生成的字段值,在合并时,会覆盖我们在 dbUser 中的有效数据。明确声明它应该忽略这些字段不是一个选项,因为我们希望我们的更新也可以设置这些字段。

The problem is that Spring populates some fields in updateUser with default values and other auto-generated field values, which, upon merging, overwrites valid data that we have in dbUser. Explicitly declaring that it should ignore these fields is not an option, as we want our update to be able to set these fields as well.

我正在寻找一些方法让Spring自动合并显式发送到 update()函数的信息到 dbUser (不重置默认/自动字段值)。有没有简单的方法可以做到这一点?

I am looking into some way to have Spring automatically merge ONLY the information explicitly sent into the update() function into the dbUser (without resetting default/auto field values). Is there any simple way to do this?

更新:我已经考虑过以下选项,几乎可以满足我的要求但不完全。问题是它需要更新数据为 @RequestParam 而(AFAIK)不执行JSON字符串:

Update: I've already considered the following option which does almost what I'm asking for, but not quite. The problem is that it takes update data in as @RequestParam and (AFAIK) doesn't do JSON strings:

//load the existing user into the model for injecting into the update function
@ModelAttribute("user")
public User addUser(@RequestParam(required=false) Long id){
    if (id != null) return userRepository.findOne(id);
    return null;
}
....
//method declaration for using @MethodAttribute to pre-populate the template object
@RequestMapping(value = "/{id}", method = RequestMethod.POST )
public @ResponseBody ResponseEntity<User> update(@ModelAttribute("user") User updateUser){
....
}

我考虑重新编写我的 customObjectMerger(),以便更适当地使用JSON,计算并仅考虑来自<的字段code> HttpServletRequest的。但是,即使不得不首先使用 customObjectMerger(),当spring提供几乎正是我正在寻找的东西时,也会感到hacky,减去缺少的JSON功能 。如果有人知道如何让Spring这么做,我会非常感激!

I've considered re-writing my customObjectMerger() to work more appropriately with JSON, counting and having it take into consideration only the fields coming in from HttpServletRequest. but even having to use a customObjectMerger() in the first place feels hacky when spring provides almost exactly what I am looking, minus the lacking JSON functionality. If anyone knows of how to get Spring to do this, I'd greatly appreciate it!

推荐答案

我刚刚遇到同样的问题。我目前的解决方案是这样的。我还没有做太多的测试,但是在初步检查时看起来效果还不错。

I've just run into this same problem. My current solution looks like this. I haven't done much testing yet, but upon initial inspection it looks to be working fairly well.

@Autowired ObjectMapper objectMapper;
@Autowired UserRepository userRepository;

@RequestMapping(value = "/{id}", method = RequestMethod.POST )
public @ResponseBody ResponseEntity<User> update(@PathVariable Long id, HttpServletRequest request) throws IOException
{
    User user = userRepository.findOne(id);
    User updatedUser = objectMapper.readerForUpdating(user).readValue(request.getReader());
    userRepository.saveAndFlush(updatedUser);
    return new ResponseEntity<>(updatedUser, HttpStatus.ACCEPTED);
}

ObjectMapper是一个类型为org.codehaus.jackson.map.ObjectMapper的bean 。

The ObjectMapper is a bean of type org.codehaus.jackson.map.ObjectMapper.

希望这有助于某人,

修改:

遇到子对象问题。如果子对象收到要部分更新的属性,则会创建一个新对象,更新该属性并进行设置。这会擦除该对象上的所有其他属性。如果我遇到一个干净的解决方案,我会更新。

Have run into issues with child objects. If a child object receives a property to partially update it will create a fresh object, update that property, and set it. This erases all the other properties on that object. I'll update if I come across a clean solution.

这篇关于Spring部分更新对象数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆