Spring Связывание параметров метода MVC

Я ищу способ настроить привязку параметра Spring MVC по умолчанию. Возьмем этот метод в качестве примера:

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@RequestParam String param) {
  ...

Это легко, когда у меня есть только String, который я хочу извлечь из запроса. Однако я хочу заполнить более полный объект, чтобы мой метод выглядел так:

@RequestMapping(value="/index.html")
public ModelAndView doIndex(Foo bar) {
  ...

То, что я ищу, - это способ объявить привязку как это:

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@FooPopulator Foo bar) {
  ...

И у вас есть другой вид реализации (определяемый аннотацией @FooPopulator), который делает это:

public void doBind(Foo target, ServletRequest originalRequest) {
  target.setX(this.computeStuffBasedOn(originalRequest));
  target.sety(y);
}

До сих пор я узнал об аннотации привязки @InitBinder, но я не уверен, действительно ли это правильный выбор для этого сценария.

Какой лучший способ?

Ответ 2

Это очень легко. Вы можете использовать Преобразователи (которые работают как один из свойств PropertyEditors, но не имеют состояния).

См. главу 5.5 Spring 3 Преобразование типов в справочной системе Spring.

Если такой конвертер зарегистрирован один раз, вам не нужна дополнительная информация, вы можете просто использовать

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@RequestParam Foo param) {

Например, простой конвертер, который загружает объект по своему id:

@Component
@CustomConverter //custom qualifyer
public class BUdToUserConverter implements Converter<String, User> {

    @Resource
    private UserDao userDao;

    @Override
    public User convert(String source) {
        Integer id = Integer.parse(source);
        return this.userDao.getByBusinessId(id);
    }
}

A "помощник", который регистрирует все Beans с аннотацией @CustomConverter

public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {

    @Resource
    @CustomConverter
    private List<Converter<?, ?>> customConverter;

     @Override
    protected void installFormatters(final FormatterRegistry registry) {
        super.installFormatters(registry);

        for (Converter<?, ?> converter : customConverter) {
            registry.addConverter(converter);
        }
    }
}

Как использовать его

UserController {
...
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ModelAndView show(@PathVariable("id") User user) {        
        return new ModelAndView("users/show", "user", user);
    }
}