java Spring MVC 自定义方法参数绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6519322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:10:40  来源:igfitidea点击:

Spring MVC customized method parameter binding

javaspringdata-bindingspring-mvc

提问by perdian

I'm looking for a way to customize the default Spring MVC parameter binding. Take this method as an example:

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

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

This is easy, when I have just a Stringthat I want to extract from the request. However, I want to populate a more complete object, so that my method looks like this:

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

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

What I'm looking for is some way to declare a binding like this;

我正在寻找的是某种方式来声明这样的绑定;

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

And have some other kind of implementor (determined by the @FooPopulatorannotation) that does this:

并有一些其他类型的实现者(由@FooPopulator注释确定)来执行此操作:

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

So far I've found out about the @InitBinderbinder annotaion but I'm unsure whether that's really the right choice for this scenarion.

到目前为止,我已经了解了@InitBinder活页夹注释,但我不确定这是否真的是这个场景的正确选择。

What's the best way?

最好的方法是什么?

采纳答案by perdian

回答by Ralph

It is very easy. You can use Converters (that work like one way PropertyEditors but are stateless).

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

See chapter 5.5 Spring 3 Type Conversionin Spring reference.

请参阅Spring 参考中的第5.5Spring 3 类型转换

If such an converter is registered once, you do not need any additional information, you can simply use

如果此类转换器注册一次,则不需要任何其他信息,只需使用

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

For example a simple converter that load an object by its id:

例如一个简单的转换器,它通过它的 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 "helper" that registers all Beans with @CustomConverter anntoation

使用@CustomConverter 注释注册所有 Bean 的“帮助程序”

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);
        }
    }
}

How to use it

如何使用它

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