我们有几个带@RequestMapping
注释的控制器方法可以做一些事情。他们每个人都有一个以上的论点,我们希望受到约束。例如:
@RequestMapping(value = "/a/b", method = RequestMethod.GET)
@ResponseBody
public Response getAB(ARequest aRequest, BRequest bRequest) throws ServiceException {
...
}
这显然工作正常。但是,我们的需求中的一个怪癖是我们获取包含下划线的请求参数。例如; 在上面的端点上,我们会收到一个如下所示的请求:http://x:8000/a/b?req_param=1
。这会导致默认的 Spring 绑定失败,因为在我们想要绑定的对象中,我们定义了req_param
驼峰式 ( reqParam
) 而不是在 Java 代码中使用下划线。
为了解决这个问题,我们实现了我们自己的注解 ( @Camelize
) 和我们自己的自定义WebArgumentResolver
,我们已经在 Spring 上下文中注册了它们。然后我们用 注释我们的控制器方法参数@Camelize
,这会导致我们的自定义WebArgumentResolver
介入并更正绑定。这也很好用。
现在问题出现了,更具体地说,当我们还想验证我们的论点时,这似乎失败了。例如,继续上面的示例:
@RequestMapping(value = "/a/b", method = RequestMethod.GET)
@ResponseBody
public Response getAB(@Camelize @Valid ARequest aRequest, Errors aRequestErrors, BRequest bRequest) throws ServiceException {
...
}
这失败了,但有例外:java.lang.IllegalStateException: Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature!
.
看来我们不能同时使用我们的自定义WebArgumentResolver
和验证使用@Valid
。我们已经将其缩小到 custom WebArgumentResolver
,从某种意义上说,只要this不返回UNRESOLVED
,Spring MVC 就不会打扰验证并抛出上面的异常。
- 谁能确认这是预期的行为?
- 有解决办法吗?目前我们正在考虑删除自定义
WebArgumentResolver
并用过滤器替换它,但这似乎对我们需要的东西非常具有侵入性。
谢谢!
编辑:我们使用的是 Spring 3.0.5。