自定义DTO内的映射请求参数和字段?

时间:2015-05-05 12:59:12

标签: spring spring-mvc model-binding spring-mvc-initbinders

我有以下课程:

public class MyDTO { 

       private String kiosk;
       ...
}

并关注网址:

http://localhost:1234/mvc/controllerUrl?kiosk=false

并遵循控制器方法:

@RequestMapping(method = RequestMethod.GET, produces = APPLICATION_JSON)
@ResponseBody
public ResponseEntity<List<?>> getRequestSupportKludge(final MyDTO myDTO, BindingResult bindingResult) {
    ...
}

现在它运行良好,布尔字段正确解析。

现在url参数已经改变如下:

http://localhost:1234/mvc/controllerUrl?new_kiosk=false

我不想在DTO中更改参数名称。有没有办法说明了new_kiosk请求参数值应该放入kiosk字段?

2 个答案:

答案 0 :(得分:13)

除了设置一个额外的setter,你可以通过制作一个自定义参数解析器来处理这个案例。有几种方法可以解决它,但已经有一个很好的讨论post。如果我是你,我会专注于jkee的回答。一步一步地遵循它,而你应该做的就是用类似的东西来注释你的DTO,

public class MyDTO { 

       @ParamName("new_kiosk")
       private String kiosk;
       ...
}

请注意,即使您无法更改MyDTO课程,仍可以按照自定义解析程序路线进行操作。在这个post中,我已经回答了如何编写参数类型注释。结合这两个帖子,你可以很容易地得到一个注释,例如@ParamMapper将定义从请求到属性的映射。想想像

这样的东西
 getRequestSupportKludge(@ParamMapper("new_kiosk;kiosk") MyDTO myDTO, BindingResult bindingResult)

答案 1 :(得分:3)

有不同的方法可以做到这一点。

如果你可以改变MyDTO类,最简单的方法是按照M.Deinum的建议添加一个setter:

public class MyDTO { 

       private String kiosk;
       ...
       public void setNew_kiosk(String kiosk) {
           this.kiosk = kiosk;
       }
}

这样,您就可以处理http://localhost:1234/mvc/controllerUrl?kiosk=false以及http://localhost:1234/mvc/controllerUrl?new_kiosk=false

如果您不允许这样做(因为DTO是库的一部分,您不允许更改或...),您可以使用映射到/mvc/controllerUrl的过滤器,它将包装请求使用将覆盖以下方法的自定义HttpServlerRequestWrapper

String  getParameter(String name)
Map<String,String[]>    getParameterMap()
Enumeration<String>     getParameterNames()
String[]    getParameterValues(String name)

调用底层请求方法并处理特殊参数名称。示例:

String[]    getParameterValues(String name) {
    String[] values = req.getParameterValues(name); // req is the wrapped request
    if ("kiosk".equals(name) && (values == null) {  // will accept both names
        values = req.getParameterValues("new_kiosk"); // try alternate name
    }
    return values;
}

编写和测试会更加困难,所以只有在你不能修改MyDTO类时才这样做。

您还可以尝试使用WebBindingInitializer的自定义实现。来自Spring Framework Reference Manual

要外部化数据绑定初始化,您可以提供WebBindingInitializer接口的自定义实现,然后通过为AnnotationMethodHandlerAdapter提供自定义Bean配置来启用该接口,从而覆盖默认配置

注意:建议的用法是为整个应用程序注册自定义编辑器 - 而不是您的用例。 Spring Framework被描述为易于扩展但不能覆盖。告诫者......

摘要:尝试使用方法1,如果不能,则使用method2,如果您有其他原因使用自定义WebBindingInitializer

,请仅尝试使用method3