如何确保URL参数映射到Spring MVC中的右侧字段?

时间:2011-04-25 22:34:29

标签: java spring-mvc

说我有两个独立的课程:

class Foo {
   int bar;
}

class Baz {
   int bar;
}

我希望在Spring MVC控制器中接受每个实例:

@RequestMapping("/someurl")
public ModelAndView myController(Foo f, Bar b) {
  // etc
}

如何构建包含f.bar和b.bar唯一值的网址? Spring接受?bar=somevalue并将somevalue分配给f.barb.bar,但我希望每个都有唯一的值。

更一般地说,如何将参数调整到控制器(通过带有GET参数的URL)以仅应用于特定对象的字段?

2 个答案:

答案 0 :(得分:2)

我能想到的两种方式。

1)创建一个包含foo和bar的包装器对象,以便在查询字符串中使用唯一的绑定路径。在方法签名中有多个绑定目标“有效”,但正如您所发现的那样存在一些问题。如果实际值来自表单字段,并且您希望表单使用Spring表单标签“正常工作”,那么这也是您的最佳选择。

2)创建一个自定义PropertyEditor,它可以解释带有某种命名空间的数字,然后只解析并绑定与当前绑定目标一起的数字部分。例如,您的查询字符串看起来像?bar=foo/12//bar/45(我可以确定更好的表示形式),然后在PropertyEditor的setAsText方法中解析出您想要的内容。如果您从表单字段中获取这些值,那将会很痛苦。

答案 1 :(得分:2)

好的,像这样处理网址:

/someurl?fooId=3&barId=5

你需要写这样的东西:

@RequestMapping("/someurl")
public ModelAndView myController(
            @RequestParam("fooId") int fooId, 
            @RequestParam("barId") int barId) {
   Foo foo = new Foo();
   foo.bar = fooId;

   Bar bar = new Bar();
   bar.bar = barId;

   // etc.
}

您可以选择超越该解决方案并创建自定义转换器:

public class FooConverter implements Converter<Integer, Foo> {
    @Override
    public Foo convert(Integer source) {
        Foo foo = new Foo();
        foo.bar = source;
        return foo;
    }
}

public class BarConverter implements Converter<Integer, Bar> {
    @Override
    public Bar convert(Integer source) {
        Bar bar = new Bar();
        bar.bar = source;
        return bar;
    }
}

然后在春季注册后:

<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="xyz.FooConverter"/>
            <bean class="xyz.BarConverter"/>
        </set>
    </property>
</bean>

您可以使用更短的解决方案(自动转换Foo和Bar):

@RequestMapping("/someurl")
public ModelAndView myController(
            @RequestParam("fooId") Foo foo, 
            @RequestParam("barId") Bar bar) {

   // etc.
}