views:

486

answers:

1

Here's how my method looks like:

@RequestMapping(value = "/form", method = RequestMethod.POST)
public String create(@ModelAttribute("foo") @Valid final Foo foo,
        final BindingResult result, final Model model) {
    if (result.hasErrors())
      return form(model);
    fooService.store(foo);
    return "redirect:/foo";
}

So, I need to bind the IP address to the Foo object probably by calling getRemoteAddr() on HttpServletRequest. I've tried creating CustomEditor for Foo, but it doesn't seem to be the proper way. @InitBinder looks more promising but I've yet to found out how.

The IP address is mandatory on the object and Spring combined with JSR-303 bean validation will give a validation error unless it is there.

What would be the most elegant way to solve this?

+4  A: 

You can use @ModelAttribute-annotated method to prepopulate the object with IP address:

@ModelAttribute("foo")
public Foo getFoo(HttpServletRequest request) {
    Foo foo = new Foo();
    foo.setIp(request.getRemoteAddr());
    return foo;
}

@InitBinder("foo")
public void initBinder(WebDataBinder binder) {
    binder.setDisallowedFields("ip"); // Don't allow user to override the value
}

EDIT: There is a way to do it using @InitBinder only:

@InitBinder("foo")
public void initBinder(WebDataBinder binder, HttpServletRequest request) {
    binder.setDisallowedFields("ip"); // Don't allow user to override the value
    ((Foo) binder.getTarget()).setIp(request.getRemoteAddr());
}
axtavt
Thanks a lot, I never saw an example like this in the Spring documentation. I chose the first way because the pure `@InitBinder` way seems somewhat clumsy with the casting.
hleinone