一步步学习 《Spring 实战 第5版》--(9)校验表单输入

前面几章我们已经实现了页面的输入功能,但还缺少对用户录入项的校验,以防止用户漏输或者输入错误。本章来实现表单校验功能。

在我们之前的配料表单中,对用户的输入并没有控制。如果用户一个配料都没有选,或者没有给他的配料表命名,我们的页面都不会报错。这在实际的应用系统中是不能发生的。因此,在这一章,我们需要给表单增加输入校验功能。

Spring 支持Java的Bean校验API(Bean Validation API,也就是JSR-303)。它能够帮助我们更容易的声明校验规则,而不用在代码中显式的声明校验逻辑。

要在Spirng MVC中应用校验,需要做到下面三步:

  1. 在要增加校验的类上面声明校验规则,例如在Taco类;
  2. 在控制器中方法声明要进行的校验;
  3. 修改表单视图以展现校验错误。

一、声明校验规则

在Taco类里面,我们要确保name属性不为空,同时配料至少要包含一项。这就要使用@NotNull 和 @Size注解来解决我们的问题,代码如下:

@Data
public class Taco {

  @NotNull
  @Size(min=5, message="Name must be at least 5 characters long")
  private String name;

  @Size(min=1, message="You must choose at least 1 ingredient")
  private List<String> ingredients;

}

注解比较简单,给出了每个字段在大小方面的规则。

我们继续对“Order”订单类增加规则校验。代码如下。

@Data
public class Order {
    @NotBlank(message="名称不能为空")
    private String name;

    @NotBlank(message="街道名称不能为空")
    private String street;

    @NotBlank(message="街道名称不能为空")
    private String city;

    @NotBlank(message="街道名称不能为空")
    private String state;

    @NotBlank(message="街道名称不能为空")
    private String zip;

    @CreditCardNumber()
    private String ccNumber;

    @Pattern(regexp = "^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",
    message="Must be formatted MM/YY")
    private String ccExpiration;

    @Digits(integer=3, fraction = 0,message = "CVV编号不合法")
    private String ccCVV;

}

Order类的校验控制大部分是非空校验,使用了@NotBlank注解。其他几个比较特殊的注解是:

  1. @CreditCardNumber注解。这个注解声明该属性的值必须是合法的信用卡号,防止用户录错信用卡。
  2. @Pattern注解。这个注解采用了正则表达式,这里确保了用户输入的信用卡到期日的格式是“MM/YY”格式。
  3. @Digits注解。这个注解确保它的值包含3位数字。

所有注解都包含了一个message属性,定义了当输入的信息不满足声明的校验规则的时候,展现给用户什么信息。

二、在控制器内执行校验

接下来我们要修改控制器,让表单在POST提交时,对应的控制器方法能够执行相应的校验。

DesignTacoController类的processDesign()方法的代码修改如下:

    @PostMapping
    public String processDesign(@Valid Taco design, Errors errors){
        if(errors.hasErrors()){
            return "design";
        }

        log.info("Processing design: " + design);

        return "redirect:/orders/current";
    }

首先,为这个方法的Taco输入参数增加一个@Valid注解。这个注解会通知Spring MVC要对提交的Taco对象进行校验,这个校验发生在绑定表单数据之后,调用processDesign()方法之前。如果存在校验错误,则错误信息会传递到errors对象中。程序的前几行会校验errors对象是否存在错误,如果存在,则跳转到“design”视图中去。

对OrderController类的processOrder方法也做类似的修改,代码如下:

   @PostMapping
    public String ProcessOrder(@Valid Order order, Errors errors){
        if(errors.hasErrors()){
            return "orderForm";
        }
        log.info("order submitted:" + order);
        return "redirect:/";
    }

作用和原理与之前介绍的类似。

三、增加视图校验

Thymeleaf模板提供了能够访问Errors对象的方法,就是使用fields及th:errors标签,该元素会将对错误的引用带到订单的表单模板上。

表单校验的关键代码是这样的:

<label for="name">Name: </label>
      <input type="text" th:field="*{name}"/>
<!-- end::allButValidation[] -->
      <span class="validationError"
            th:if="${#fields.hasErrors('name')}"
            th:errors="*{name}">Name Error</span>
<!-- tag::allButValidation[] -->
      <br/>

这里使用th:if属性来判断是否需要显示这个报错提示,显然,当判断是hasErrors时需要显示报错信息。

th:errors则判断,当name这个变量存在错误的时候,将显示“Name Error”这个报错信息。

最终显示的报错提示如下,我这里用了汉语的报错信息。


页面的报错信息.png

具体的页面代码,大家可以在官网的代码库中获取。

四、总结

目前为止,我们已经完成了页面的get、post请求,并为页面增加了输入校验规则。SpringMVC中,校验规则的增加是比较方便的,只要分别在要需要校验的类、控制器以及页面中增加相应的内容即可。

后面我们将继续修改这个例子,在其中增加数据库支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355