5

我正在使用 Spring MVC,我希望它从数据库中绑定一个持久对象,但我不知道如何设置我的代码以在绑定之前调用数据库。例如,我正在尝试将“BenefitType”对象更新到数据库,但是,我希望它从数据库中获取对象,而不是创建新对象,因此我不必更新所有字段。

    @RequestMapping("/save")
public String save(@ModelAttribute("item") BenefitType benefitType, BindingResult result)
{
    ...check for errors
    ...save, etc.
}
4

4 回答 4

4

所以我最终通过在类中使用同名的@ModelAttribute 注释方法来解决这个问题。Spring 在执行请求映射之前首先构建模型:

@ModelAttribute("item")
BenefitType getBenefitType(@RequestParam("id") String id) {
    // return benefit type
}
于 2011-09-09T15:57:30.627 回答
4

有几种选择:

  • 在最简单的情况下,当您的对象只有简单属性时,您可以将其所有属性绑定到表单字段(hidden如果需要),并在提交后获得完全绑定的对象。复杂属性也可以使用PropertyEditors 绑定到表单字段。

  • 您还可以使用 session 来存储GETPOST请求之间的对象。Spring 3 通过@SessionAttributes注释(来自Petclinic 示例)促进了这种方法:

    @Controller
    @RequestMapping("/owners/*/pets/{petId}/edit")
    @SessionAttributes("pet") // Specify attributes to be stored in the session       
    public class EditPetForm {    
        ...
        @InitBinder
        public void setAllowedFields(WebDataBinder dataBinder) {
            // Disallow binding of sensitive fields - user can't override 
            // values from the session
            dataBinder.setDisallowedFields("id");
        }
        @RequestMapping(method = RequestMethod.GET)
        public String setupForm(@PathVariable("petId") int petId, Model model) {
            Pet pet = this.clinic.loadPet(petId);
            model.addAttribute("pet", pet); // Put attribute into session
            return "pets/form";
        }
        @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST })
        public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
            new PetValidator().validate(pet, result);
            if (result.hasErrors()) {
                return "pets/form";
            } else {
                this.clinic.storePet(pet);
                // Clean the session attribute after successful submit
                status.setComplete();
                return "redirect:/owners/" + pet.getOwner().getId();
            }
        }
    }
    

    但是,如果表单的多个实例在同一会话中同时打开,这种方法可能会导致问题。

  • 因此,对于复杂情况,最可靠的方法是创建一个单独的对象来存储表单字段,并手动将来自该对象的更改合并到持久对象中。

于 2010-09-09T11:04:51.953 回答
0

虽然您的域模型可能非常简单,以至于您可以将 UI 对象直接绑定到数据模型对象,但很可能并非如此,在这种情况下,我强烈建议您设计一个专门用于表单绑定的类,然后在它和控制器中的域对象之间进行转换。

于 2010-09-08T22:47:29.793 回答
0

我有点困惑。我认为您实际上是在谈论更新工作流程?

您需要两个@RequestMapping,一个用于 GET,一个用于 POST:

@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getSave(ModelMap model, @PathVariable Long id)
{
    model.putAttribute("item", benefitDao.findById(id));
    return "view";
}

然后在 POST 上实际更新该字段。

在上面的示例中,您的 @ModelAttribute 应该已经填充了类似上述方法的方法,并且使用 JSTL 或 Spring tabglibs 之类的东西与表单支持对象一起绑定属性。

根据您的用例,您可能还想查看InitBinder 。

于 2010-09-09T04:00:17.300 回答