在 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 必须具有 city
和 place
属性才能工作。
更多信息,你可以看看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。
我还没有尝试过@RequestParam
和Model
的这种特定组合,但看起来您可以通过创建自定义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 变量绑定到自定义模型对象的主要内容,如果未能解决你的问题,请参考以下文章
在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型