Spring Web MVC - 验证单个请求参数 [英] Spring Web MVC - validate individual request params

查看:34
本文介绍了Spring Web MVC - 验证单个请求参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Spring Web MVC 3.0 中运行一个 webapp,我有许多控制器方法,它们的签名大致如下:

@RequestMapping(value = "/{level1}/{level2}/foo", method = RequestMethod.POST)public ModelAndView createFoo(@PathVariable long level1,@PathVariable long level2,@RequestParam("foo_name") 字符串 fooname,@RequestParam(value = "description", required = false) String description);

我想添加一些验证 - 例如,description 应限制为特定长度或 fooname 应仅包含某些字符.如果此验证失败,我想向用户返回一条消息,而不是仅仅抛出一些未经检查的异常(如果我让数据渗透到 DAO 层,无论如何都会发生这种情况).我知道 JSR303,但没有使用过它,也不太明白如何在 Spring 上下文中应用它.

据我所知,另一种选择是将 @RequestBody 绑定到整个域对象并在那里添加验证约束,但目前我的代码设置为接受单个参数,如上所示.

使用这种方法对输入参数应用验证的最直接方法是什么?

解决方案

没有任何内置的东西可以做到这一点,不是

a> 还是.对于当前的发行版本,如果您想要自动验证,您仍然需要使用 WebDataBinder 将您的参数绑定到一个对象上.如果您正在使用 SpringMVC,那么值得学习这样做,即使它不是您执行此任务的首选.

看起来像这样:

public ModelAndView createFoo(@PathVariable long level1,@PathVariable long level2,@Valid @ModelAttribute() FooWrapper fooWrapper,BindingResult 错误){如果(错误.hasErrors(){//处理错误,如果使用Spring form:error标签就可以返回.}}公共静态类 FooWrapper {@NotNull@大小(最大= 32)私人字符串 fooName;私人字符串描述;//获取集}

如果您的类路径上有 Hibernate Validator 4 或更高版本并使用默认调度程序设置,它应该正常工作".

编辑,因为评论变得有点大:

任何在您的方法签名中但不是 Spring 知道如何注入的预期"对象之一的对象,例如 HttpRequestModelMap 等,都将获取数据边界.对于简单的情况,只需将请求参数名称与 bean 属性名称匹配并调用 setter 即可完成此操作.@ModelAttribute 只是一个个人风格的东西,在这种情况下它没有做任何事情.JSR-303 与方法参数上的 @Valid 集成通过 WebDataBinder 连接.如果您使用 @RequestBody,则您使用的是基于 spring 为请求正文确定的内容类型的对象编组器(通常仅来自 http 标头).调度程序 servlet (AnnotationMethodHandlerAdapter代码>真的)没有办法为任何任意编组器翻转验证开关".它只是将 Web 请求内容传递给消息转换器并返回一个对象.没有生成 BindingResult 对象,所以无论如何都无处设置错误.

您仍然可以将验证器注入控制器并在您获得的对象上运行它,它只是没有与填充 @Valid 神奇集成>BindingResult 给你.

I'm running a webapp in Spring Web MVC 3.0 and I have a number of controller methods whose signatures are roughly as follows:

@RequestMapping(value = "/{level1}/{level2}/foo", method = RequestMethod.POST)
public ModelAndView createFoo(@PathVariable long level1,
        @PathVariable long level2,
        @RequestParam("foo_name") String fooname,
        @RequestParam(value = "description", required = false) String description);

I'd like to add some validation - for example, description should be limited to a certain length or fooname should only contain certain characters. If this validation fails, I want to return a message to the user rather than just throw some unchecked exception (which would happen anyway if I let the data percolate down to the DAO layer). I'm aware of JSR303 but have not worked with it and don't quite understand how to apply it in a Spring context.

From what I understand, another option would be to bind the @RequestBody to an entire domain object and add validation constraints there, but currently my code is set up to accept individual parameters as shown above.

What is the most straightforward way to apply validation to input parameters using this approach?

解决方案

There's nothing built in to do that, not yet anyway. With the current release versions you will still need to use the WebDataBinder to bind your parameters onto an object if you want automagic validation. It's worth learning to do if you're using SpringMVC, even if it's not your first choice for this task.

It looks something like this:

public ModelAndView createFoo(@PathVariable long level1,
        @PathVariable long level2,
        @Valid @ModelAttribute() FooWrapper fooWrapper,
        BindingResult errors) {
  if (errors.hasErrors() {
     //handle errors, can just return if using Spring form:error tags.
  }
}

public static class FooWrapper {
  @NotNull
  @Size(max=32)
  private String fooName;
  private String description;
//getset
}

If you have Hibernate Validator 4 or later on your classpath and use the default dispatcher setup it should "Just work."

Editing since the comments were getting kind of large:

Any Object that's in your method signature that's not one of the 'expected' ones Spring knows how to inject, such as HttpRequest, ModelMap, etc, will get data bound. This is accomplished for simple cases just by matching the request param names against bean property names and calling setters. The @ModelAttribute there is just a personal style thing, in this case it isn't doing anything. The JSR-303 integration with the @Valid on a method parameter wires in through the WebDataBinder. If you use @RequestBody, you're using an object marshaller based on the content type spring determines for the request body (usually just from the http header.) The dispatcher servlet (AnnotationMethodHandlerAdapter really) doesn't have a way to 'flip the validation switch' for any arbitrary marshaller. It just passes the web request content along to the message converter and gets back a Object. No BindingResult object is generated, so there's nowhere to set the Errors anyway.

You can still just inject your validator into the controller and run it on the object you get, it just doesn't have the magic integration with the @Valid on the request parameter populating the BindingResult for you.

这篇关于Spring Web MVC - 验证单个请求参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆