在 spring 中将 Path 变量绑定到自定义模型对象

Posted

技术标签:

【中文标题】在 spring 中将 Path 变量绑定到自定义模型对象【英文标题】:Bind Path variables to a custom model object in spring 【发布时间】:2013-06-13 12:27:55 【问题描述】:

我有一个模拟我的请求的类,比如

class Venue 
    private String city;
    private String place;

    // Respective getters and setters.

我想支持一个 RESTful URL 来获取有关场地的信息。所以我有这样的控制器方法。

@RequestMapping(value = "/venue/city/place", method = "GET")
public String getVenueDetails(@PathVariable("city") String city, @PathVariable("place") String place, Model model) 
    // code

有没有办法,我可以在 spring 中将我的路径变量绑定到模型对象(在本例中为 Venue),而不是获取每个单独的参数?

【问题讨论】:

【参考方案1】:

Spring MVC 提供将请求参数和路径变量绑定到 JavaBean 的能力,在您的例子中是 Venue。 例如:

@RequestMapping(value = "/venue/city/place", method = "GET")
public String getVenueDetails(Venue venue, Model model) 
    // venue object will be automatically populated with city and place

请注意,您的 JavaBean 必须具有 cityplace 属性才能工作。

更多信息,你可以看看withParamGroup() example from spring-projects/spring-mvc-showcase

【讨论】:

我从没想过连路径变量都可以自动放入一个bean中。有关于这种有趣行为的文档吗?它的正式名称是什么? 这个解决方案的奇怪之处在于 Spring 将接受像 /venue/city/place?city=foo&place=bar 这样的 url,并从查询参数而不是路径参数绑定对象属性。如果有办法告诉 Spring Boot 那些只应该来自路径,而不是查询参数,那就太好了。【参考方案2】:

根据http://static.springsource.org/spring/docs/3.2.3.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates 提供的 Spring 文档,仅对简单类型提供自动支持:

@PathVariable 参数可以是任何简单类型,例如 int、long、 日期等 Spring 自动转换为适当的类型或 如果失败则抛出 TypeMismatchException。

我还没有尝试过@RequestParamModel 的这种特定组合,但看起来您可以通过创建自定义WebBindingInitializer 来实现所需的实现,详见http://static.springsource.org/spring/docs/3.2.3.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-typeconversion。

自定义类将有权访问 WebRequest,并将返回填充了从该请求中提取的数据的域对象。

【讨论】:

我猜,这对我的用例来说有点矫枉过正。不过谢谢你的建议。【参考方案3】:

您可以提供HandlerMethodArgumentResolver 接口的实现。此接口主要用于以 Spring 无法解决的方式解析控制器方法的参数(这实际上是您正在尝试做的事情)。您可以通过实现这两种方法来实现:

public boolean supportsParameter(MethodParameter mp) 
    ...


public Object resolveArgument(mp, mavc, nwr, wdbf) throws Exception 
    ...

您可以通过以下方式将您的实现注入 Spring 上下文:

<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean class="com.path.ImplementationOfHandlerMethodArgumentResolver"/>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

当 Spring 遇到无法解析的参数时,它会调用你的方法supportsParameter() 来查看你的解析器是否可以解析该参数。如果您的方法返回 true,那么 Spring 将调用您的 resolveArgument() 方法来实际解析参数。在此方法中,您可以访问 NativeWebRequest 对象,您可以使用该对象来获取 contextPath 之外的路径。 (在你的情况下是:/venue/city/place) 您可以解析请求路径并尝试获取城市/地点字符串 填充到您的场地对象中。

【讨论】:

以上是关于在 spring 中将 Path 变量绑定到自定义模型对象的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何将微调器绑定到自定义对象列表?

如何在 WordPress 中将类添加到自定义侧边栏

在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型

RxSwift 不将数据绑定到自定义集合视图单元格

如何在 Windows 控制台中将数据输出到自定义流(3> 4> 等)?

将 GeometryDrawing 画笔绑定到自定义控件依赖属性