我有一个工作正常的 Controller ,它可以注册和更新实体,下面分别介绍如何创建表单以保存和更新实体

@RequestMapping(value="/registrar.htm", method=RequestMethod.GET)
public String crearRegistrarFormulario(Model model){
   …
}

@RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.GET)
public String crearActualizarFormulario(@PathVariable("id") String id, Model model){
  …
}

直到这里我都没有问题。

我的问题是关于@InitBinder

我需要使用相同的实体Deportista(Sportsman),这是一种用于保存和更新的特殊设置。例如
@InitBinder
public void registrarInitBinder(WebDataBinder binder) { // register or save
    logger.info(">>>>>>>> registrarInitBinder >>>>>>>>>>>>>");
    …
    CustomDateEditor customDateEditor = new CustomDateEditor(...
    …
}

@InitBinder
public void actualizarInitBinder(WebDataBinder binder) { // update
    logger.info(">>>>>>>> actualizarInitBinder >>>>>>>>>>>>>");
    …
    CustomDateEditor customDateEditor = new CustomDateEditor(...
    …
    binder.setDisallowedFields(…) //I need this only for update
}

我已阅读以下内容:
  • How to define multiple initBinders
  • Addiing multiple validators using initBinder

  • 提到的链接围绕不同的entities工作,例如UserCustomer,它通过@InitBinder's value属性,但是我需要使用同一实体,如何配置@InitBinder's value以指示Spring使用或区分每个@InitBinder?一个分别用于保存和更新。

    谢谢

    编辑:从Serge Ballesta的答案,以下也是强制性的:
    @Controller
    @RequestMapping(value="/deportista")
    @SessionAttributes(value={"deportistaRegistrar", "deportistaActualizar"})
    public class DeportistaController {
    …
    
    @RequestMapping(value="/registrar.htm", method=RequestMethod.GET)
    public String crearRegistrarFormulario(Model model){
        Deportista deportista = new Deportista();
        model.addAttribute("deportistaRegistrar", deportista);
        return "deportista.formulario.registro";
    }
    
    @RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.GET)
    public String crearActualizarFormulario(@PathVariable("id") String id, Model model){
        Deportista deportista = this.fakeMultipleRepository.findDeportista(id);
        model.addAttribute("deportistaActualizar", deportista);
        return "deportista.formulario.actualizacion";
    }
    

    让他工作的答案:
    // registrarInitBinder will be used here
    @RequestMapping(value="/registrar.htm", method=RequestMethod.POST)
    public String doCrearRegistrarFormulario(@ModelAttribute("deportistaRegistrar") XXX value,
        BindingResult result, Model model){
       …
    }
    
    // actualizarInitBinder will be used here
    @RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.POST)
    public String crearActualizarFormulario(@PathVariable("id") String id,
        @ModelAttribute("deportistaActualizar") XXX value, BindingResult result, Model model){
      …
    }
    

    最佳答案

    根据javadoc page for @InitBinder ,您可以在一个 Controller 中使用多个init-binders,并使用将应用它们的model属性变量的名称对其进行专用化。范例:

    @InitBinder("saveValue")
    public void registrarInitBinder(WebDataBinder binder) { // register or save
        logger.info(">>>>>>>> registrarInitBinder >>>>>>>>>>>>>");
        …
        CustomDateEditor customDateEditor = new CustomDateEditor(...
        …
    }
    
    @InitBinder("updateValue")
    public void actualizarInitBinder(WebDataBinder binder) { // update
        logger.info(">>>>>>>> actualizarInitBinder >>>>>>>>>>>>>");
        …
        CustomDateEditor customDateEditor = new CustomDateEditor(...
        …
        binder.setDisallowedFields(…) //I need this only for update
    }
    

    然后(XXX是将由提交处理的表单对象的类型)
    // registrarInitBinder will be used here
    @RequestMapping(value="/registrar.htm", method=RequestMethod.POST)
    public String doCrearRegistrarFormulario(@ModelAttribute("saveValue") XXX value,
        BindingResult result, Model model){
       …
    }
    
    // actualizarInitBinder will be used here
    @RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.POST)
    public String crearActualizarFormulario(@PathVariable("id") String id,
        @ModelAttribute("updateValue") XXX value, BindingResult result, Model model){
      …
    }
    

    10-04 19:47