Errors/BindingResult 参数应在模型属性、@RequestBody 或 @RequestPart 参数之后立即声明

Posted

技术标签:

【中文标题】Errors/BindingResult 参数应在模型属性、@RequestBody 或 @RequestPart 参数之后立即声明【英文标题】:An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the @RequestBody or the @RequestPart arguments 【发布时间】:2013-09-09 20:47:05 【问题描述】:

我通过剖析示例应用程序来自学 Spring,然后在这里和那里添加代码来测试我在剖析过程中开发的理论。在测试我添加到 Spring 应用程序的一些代码时,我收到以下错误消息:

An Errors/BindingResult argument is expected to be declared immediately after the  
model attribute, the @RequestBody or the @RequestPart arguments to which they apply  

错误信息所指的方法是:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(Integer typeID, BindingResult result, Map<String, Object> model) 
    // find owners of a specific type of pet
    typeID = 1;//this is just a placeholder
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
    model.put("selections", results);
    return "owners/catowners";
  

当我尝试在 Web 浏览器中加载 /catowners url 模式时触发了此错误消息。我已经查看了this page 和this posting,但解释似乎并不清楚。

谁能告诉我如何解决这个错误,并解释它的含义?

编辑: 根据 Biju Kunjummen 的回复,我将语法更改为:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@Valid Integer typeID, BindingResult result, Map<String, Object> model)  

我仍然收到相同的错误消息。有什么我不明白的吗?

第二次编辑:

根据 Sotirios 的评论,我将代码更改为以下内容:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(BindingResult result, Map<String, Object> model) 
    // find owners of a specific type of pet
    Integer typeID = 1;//this is just a placeholder
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
    model.put("selections", results);
    return "owners/catowners";
 

在告诉 eclipse 运行为...再次在服务器上运行后,我仍然收到相同的错误消息。

有什么我不明白的地方吗?

【问题讨论】:

【参考方案1】:

Spring 使用一个名为 HandlerMethodArgumentResolver 的接口来解析处理程序方法中的参数并构造一个对象以作为参数传递。

如果没有找到,则通过null(我必须验证这一点)。

BindingResult 是一个结果对象,其中包含可能在验证 @ModelAttribute@Valid@RequestBody@RequestPart 时出现的错误,因此您只能将其与带有此类注释的参数一起使用.每个注释都有HandlerMethodArgumentResolver

编辑(回复评论)

您的示例似乎表明用户应该提供宠物类型(作为整数)。我会将方法更改为

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@RequestParam("type") Integer typeID, Map<String, Object> model)

你会提出你的请求(取决于你的配置)

localhost:8080/yourcontext/catowners?type=1

这里也没有什么要验证的,所以您不需要或不需要BindingResult。如果您尝试添加它,它将失败。

【讨论】:

大声笑,不要编辑我的问题。 HandlerMethodArgumentResolver 有更多规则。您希望Integer 对象来自哪里? @ModelAttribute 是从 HttpServletRequest 对象构建的,其他对象也是如此。 我试图进行编辑,后来我刚刚对我自己上面的原始帖子进行了编辑。堆栈溢出不允许我删除对您发布的意外编辑。你能建议任何实际的代码来解决这个问题吗?这些答案似乎深奥,而我在上面编辑中的实际代码并没有消除错误。 @CodeMed Integer 来自哪里?是你想要的 url 路径、一些请求参数等吗? 此方法在 Spring PetClinic 应用程序的 OwnerController 类中。我将此方法添加为一些更改的一部分,以创建一个返回给定类型宠物的所有所有者的页面。随后,我希望不必为每种宠物类型创建单独的方法。然而,对于初学者来说,我只是想在输出表中输出一个带有猫主人的页面。这是引发错误的方法。该整数是宠物诊所应用程序数据库中猫的 type_id=1。 @CodeMed 据我了解,您希望用户提供一种类型。我的编辑显示了如何。【参考方案2】:

如果你有一个BindingResult 类型的参数,它本质上是在将http 请求参数绑定到直接在BindingResult 方法参数之前声明的变量时保存任何错误。

所以所有这些都是可以接受的:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@Valid MyType type, BindingResult result, ...)


@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@ModelAttribute MyType type, BindingResult result, ...)

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@RequestBody @Valid MyType type, BindingResult result, ...)

【讨论】:

感谢您抽出宝贵时间撰写周到的答案。我使用我认为您的建议对上面的原始帖子进行了编辑,但它仍然抛出错误消息。有什么我不明白的吗? @Valid 带有整数字段将不起作用。尝试使用包含类型,而不是在其中包含一个整数字段,后跟 BindingResult 参数。 +1,谢谢。我现在已经使用此页面上的各种 cmets 解决了这个问题。

以上是关于Errors/BindingResult 参数应在模型属性、@RequestBody 或 @RequestPart 参数之后立即声明的主要内容,如果未能解决你的问题,请参考以下文章

第265天学习打卡(知识点回顾 springboot 复杂参数)

有一个不应硬编码但应在规则调用时作为参数传递的参数[重复]

此类应在 android manifest 中提供默认构造函数(不带参数的公共构造函数)

withRouter 参数解析 Invariant Violation 时出错:您不应在 <Router> 之外使用 <Route> 或 withRouter()

dateserial是啥意思

[WPF]启动参数