Spring MVC自定义方法参数绑定

per*_*ian 13 java data-binding spring spring-mvc

我正在寻找一种方法来自定义默认的Spring MVC参数绑定.以此方法为例:

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@RequestParam String param) {
  ...
Run Code Online (Sandbox Code Playgroud)

这很简单,当我只想String要从请求中提取时.但是,我想填充一个更完整的对象,以便我的方法如下所示:

@RequestMapping(value="/index.html")
public ModelAndView doIndex(Foo bar) {
  ...
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是一种声明像这样的绑定的方法;

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@FooPopulator Foo bar) {
  ...
Run Code Online (Sandbox Code Playgroud)

并有一些其他类型的实现者(由@FooPopulator注释确定)这样做:

public void doBind(Foo target, ServletRequest originalRequest) {
  target.setX(this.computeStuffBasedOn(originalRequest));
  target.sety(y);
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经发现了@InitBinder粘合剂注释,但我不确定这是否真的是这个版本的正确选择.

什么是最好的方式?

Ral*_*lph 12

这很容易.您可以使用转换器(其工作方式类似于PropertyEditors,但是无状态).

请参见章节5.5 Spring中的Spring 3类型转换参考.

如果这样的转换器注册一次,您不需要任何其他信息,您可以简单地使用

@RequestMapping(value="/index.html")
public ModelAndView doIndex(@RequestParam Foo param) {
Run Code Online (Sandbox Code Playgroud)

例如,通过其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);
    }
}
Run Code Online (Sandbox Code Playgroud)

一个"助手",用@CustomConverter anntoation注册所有Beans

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用它

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

  • 谢谢,这适用于将单个参数转换为用户特定对象,但是我想自己遍历完整的`HttpServletRequest`并使用根据`HttpServletRequest`的状态计算的值填充用户特定对象. (2认同)