【问题标题】:Customize mapping request parameters and fields inside the DTO ?自定义 DTO 内的映射请求参数和字段?
【发布时间】:2015-07-15 05:32:04
【问题描述】:

我有以下课程:

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 中的参数名称。有没有办法说spring可以理解new_kiosk请求参数值应该放入kiosk字段?

【问题讨论】:

  • 您从前端接受的数据类型(JSON/XML 等)是什么?
  • @RE350 只是获取参数。像这样的网址 controllerUrl?new_kiosk=false
  • 我强烈建议阅读 java bean 规范。属性只是 getter/setter 的名称,如何在内部命名字段并不重要。如果您的字段名为foo,并且您有一个设置foo 值的setBar 方法,那么您就有一个bar 属性。属性 != 字段。
  • @M. Deinum 这对我来说是个惊喜。我总是使用 IDE set get generator。默认情况下,它会根据字段名称生成 set 和 get 方法。
  • @M. Deinum 您是否建议创建名称为 setNew_kioskgetNew_kiosk 的方法?

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


【解决方案1】:

除了设置额外的 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)

【讨论】:

    【解决方案2】:

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

    如果您可以更改 MyDTO 类,最简单的方法是按照 M.Deinum 的建议添加一个设置器:

    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,如果不能,则使用方法2,只有在您有其他原因使用自定义WebBindingInitializer时才尝试使用方法3@

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 2023-01-11
      相关资源
      最近更新 更多