【问题标题】:Spring MVC controller custom parameter nameSpring MVC 控制器自定义参数名称
【发布时间】:2013-04-11 15:04:25
【问题描述】:

我有一个 Spring MVC 控制器。我在方法中有 50 个参数。所有参数都有非常具体的名称,例如:FOO[]。 我不想像这样在方法签名中写 50 个参数:

@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody
public String test(
    @RequestParam(value = "FOO[]") String foo,
    @RequestParam(value = "BAR[]") String bar,
// Other 48 parameters
)
{
    return "test";
}

我想将所有参数映射到一个对象上,我的意思是,我想用 getter/setter 编写一个简单的 bean 类,并像方法参数一样使用它。 但是如何为我的类字段设置自定义名称?

例如:

class FooBar {
    @SomeAnnotation_for_binding_the_field_to_my_field_FOO[]
    private String foo;
    private String bar;
    // Other 48 fields
    // getters/setters
}

【问题讨论】:

    标签: spring-mvc controller


    【解决方案1】:

    我知道注释有点酷,但请理性思考。您必须在代码中枚举所有映射。将 FOO[] 映射到 foo 没有任何隐含意义,它似乎超出了您的控制范围。只需将参数作为映射(您始终可以要求 Spring 为您提供所有参数的映射)并执行以下操作:

    @RequestMapping
    public String test(@RequestParam Map<String, Object> map) {
        MyObject mo = new MyObject();
        mo.setFoo(map.get("FOO[]").toString());
        mo.setBar(map.get("WOBBLE13[][]").toString);
        return "whatever";
    }
    

    如果你想让这个过程更加自动化,并且如果存在将参数名映射到属性名的算法,你可以使用 Spring 的 bean wrapper:

    @RequestMapping
    public String test(@RequestParam Map<String, String> map) {
       BeanWrapper bw = new BeanWrapperImpl(new MyObject);
       for (Entry<String, Object> entry : map.entrySet()) {
           bw.setProperty(entry.getKey(), entry.getValue());
       }
    }
    
    private static String decodeName(String n) {
        return n.toLowerCase().substring(0,n.length() - 2);
    }
    

    您可以通过使用不同的 Binder 使该过程更加自动化,您可以(真的,这不是问题)添加一些自定义注释...但实际上,如果您只有一个 50 的案例,那么没有意义参数。如果您坚持,请添加评论。

    【讨论】:

      【解决方案2】:

      这听起来像是使用哈希映射的好时机,其中键作为 var 名称,值作为值。将其包装在表单支持对象中。

      【讨论】:

        【解决方案3】:

        您可以拥有一个资源类,即 FooBarResource.jave,并在您的控制器中将其用作请求主体,如下所示:

        @ResponseBody
        @RequestMapping(value = "/test", method = RequestMethod.POST)
        @Secured({"ROLE_ADMIN"})
            public ResponseEntity<ModelMap> createTest(@Valid @RequestBody FooBarResource body, UriComponentsBuilder builder) {
        

        【讨论】:

        • 我如何在 Java 中命名我的字段 FOO[]? :)
        • 你有一个 FooBar 类,我所做的只是重命名了它:) 你可以使用与你的资源类相同的类。例如,如果您想要控制器中的任何字段,您只需执行 body.getFoo() 即可。您还可以在资源类中对 foo 执行 @NotNull(message = "foo is required") 之类的操作。
        猜你喜欢
        • 2012-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        • 1970-01-01
        • 2016-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多