3

I have a controller where works fine, It can register and update an entity, just how the following about to create the forms to save and update an entity respectively

@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){
  …
}

Until here I have no problems.

My problem is about the @InitBinder

I need work with the same entity Deportista (Sportsman), one special setting for save and update. For example

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

I have read the following:

The links mentioned work around different entities, for example User and Customer, it through the @InitBinder's value attribute, but I need work with the same entity, how I can configure the @InitBinder's value to indicate Spring use or discriminate each @InitBinder? one for save and update respectively.

Thanks

Edit: From the Serge Ballesta's answer, the following is mandatory too:

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

It to let work his answer:

// 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){
  …
}
Community
  • 1
  • 1
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158

1 Answers1

12

According to the javadoc page for @InitBinder, you can use multiple init-binders in one single controllers, and specialize them with the name of the model attribute variable for which they will be applied. Example :

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

and then (XXX is the type of the form object that will be processed by the submit)

// 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){
  …
}
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • 3
    This works for `@ModelAttribute` but my controllers are annotated with `@RequestBody` instead which deserialises json to my pojo and `@requestbody` does not provide a similar way to specify which binder to use. Is there a solution to be used with @requestbody – mickeymoon May 14 '15 at 16:23
  • As I was searching too, for \@RequestBody, use \@InitBinder("myclass") and then in the method signature: \@RequestMapping(value="view", params="stuff=stuff") public void update(\@Valid \@ModelAttribute MyClass o, BindingResult result, ... etc – Tim Cederquist May 19 '15 at 21:20