为了账号安全,请及时绑定邮箱和手机立即绑定

【Spring实战——构建Spring Web应用程序】1.10 处理表单

引言

Web应用功能

○ 提供内容
○ 用户填写表单
○ 提交数据

Spring MVC的控制器提供了

○ 处理表单展示
○ 用户提交数据的支持

  1. 在Spittr应用中,需要一个注册表单供新用户使用。
  2. SpitterController是一个新的控制器,目前只有一个请求处理方法用于展示注册表单。
    程序清单5.13 SpitterController:展现一个表单,允许用户注册该 应用
    file

根据配置的InternalResourceViewResolver,将使用"/WEB-INF/views/registerForm.jsp"这个JSP来渲染注册表单。

  1. 尽管showRegistrationForm()方法很简单,但仍需要进行测试。
  2. 由于该方法简单,测试也相对简单。
    程序清单5.14 测试展现表单的控制器方法
    file
    注意
  3. 视图的名称为registerForm,因此JSP的名称应为registerForm.jsp。
  4. registerForm.jsp必须包含一个HTML 标签,用于用户输入注册应用的信息

程序清单5.15 渲染注册表单的JSP
file

在JSP中,有一个基础的HTML表单,其中包含用于记录用户的名字、姓氏、用户名和密码的表单域,以及一个提交按钮。
在该JSP中,标签没有设置action属性。在这种情况下,当表单提交时,它会提交到与展示时相同的URL路径上,即"/spitter/register"。
这意味着需要在服务器端处理该HTTP POST请求。
file
现在,我们需要在Spitter-Controller中添加一个方法来处理这个表单的提交。

图5 .5 注册页提供了一个表单,这个表单会由SpitterController 进行处理,完成为应用添加新用户的功能

5.4.1 编写处理表单的控制器

当处理注册表单的POST请求时,控制器需要接收表单数据并将其保存为Spitter对象。
为了防止重复提交,应该将浏览器重定向到新创建用户的基本信息页面。
这些行为可以通过shouldProcessRegistration()方法进行测试。
程序清单5.16 测试处理表单的控制器方法
file

  1. 处理POST请求时,最好在请求处理完成后进行重定向,以防止浏览器刷新导致表单重复提交。
  2. 在这个测试中,预期请求会重定向到"/spitter/jbauer",即新创建用户的基本信息页面。
  3. 最后,测试会验证SpitterRepository的mock实现是否真正保存了表单提交的数据。
  4. 现在,我们需要实现处理表单提交的控制器方法。
  5. 通过shouldProcessRegistration()方法,我们可以看到新的SpitterController并没有做太多的事情。
    程序清单5.17 处理所提交的表单并注册新用户

file

  在之前创建的showRegistrationForm()方法的基础上,我们新增了一个processRegistration()方法。该方法接受一个Spitter对象作为参数,该对象具有firstName、lastName、username和password属性。这些属性将使用请求中的同名参数进行填充。
    当InternalResourceViewResolver看到视图格式中的"redirect:"前缀时,它知道要将其解析为重定向的规则,而不是视图的名称。在本例中,它会将视图重定向到用户基本信息的页面。例如,如果Spitter.username属性的值为"jbauer",那么视图将重定向到"/spitter/jbauer"。

根据程序清单5.16中的测试,我们的任务应该已经完成。然而,在SpitterController中,我们还需要添加一个处理器方法来处理基本信息页面的请求。showSpitterProfile()方法将完成这项任务。

file
SpitterRepository通过用户名获取一个Spitter对象,showSpitterProfile()方法将获取到的对象添加到模型中,并返回基本信息页面的逻辑视图名"profile"。和本章其他展示的视图一样,基本信息视图也非常简单。

图5.6展现了在Web浏览器中渲染的基本信息页面。
下面是对这段内容进行梳理和润色后的输出:
如果表单中没有发送username或password,会发生什么情况呢?又或者,如果firstName或lastName的值为空或过长,会有什么影响呢?接下来,让我们看一下如何为表单提交添加校验,以避免数据的不一致性。

图5 .6 Spittr 的基本信息页展现了用户的情况,这些信息是 由SpitterController填充到模型中的

5.4.2 校验表单

如果用户在提交表单时,username或password文本域为空,将导致新建的Spitter对象中的username或password属性为空字符串。这种行为可能会导致安全问题,因为任何人只需提交一个空表单即可登录应用程序。
为了保持一定程度的匿名性,我们应该阻止用户提交空的firstName和/或lastName。一种良好的方式是限制这些输入域的长度,以确保其值在合理的范围内,避免误用。
为了处理验证,可以在processRegistration()方法中添加代码来检查值的合法性。如果值不合法,可以重新向用户显示注册表单。虽然这种方法很简短,但添加一些额外的if语句也不是什么大问题。
与其让验证逻辑混淆处理器方法,不如利用Spring对Java验证API(JSR-303)的支持。从Spring 3.0开始,在Spring MVC中提供了对Java验证API的支持。
使用Java验证API并不需要额外的配置,只需确保在类路径下包含该API的实现,如Hibernate Validator。
Java校验API定义了多个注解,这些注解可以放到属性上,从而限制这些属性的值。所有的注解都位于javax.validation.constraints包中。表5.1列出了这些校验注解。
表5.1 Java校验API所提供的校验注解

注 解 描 述

file

除了表5.1中的注解,Java校验API的实现可能还会提供额外的校验注解。同时,也可以定义自己的限制条件。但就我们来讲,将会关注于上表中的两个核心限制条件。
请考虑要添加到Spitter域上的限制条件,似乎需要使用@NotNull和@Size注解。我们所要做的事情就是将这些注解添加到Spitter的属性上。下面的程序清单展现了Spitter类,它的属性已经添加了校验注解。
程序清单5.18 Spitter:包含了要提交到Spittle POST请求中的域
file
@NotNull注解,确保值不为null。
@Size注解,限制它们的长度在最大值和最小值之间。
对Spittr应用来说,这意味着用户必须要填完注册表单,并且值的长度要在给定的范围内。

我们已经为Spitter添加了校验注解,接下来需要修改processRegistration()方法来应用校验功能。
下面展示的是启用了校验功能的processRegistration()方法。
程序清单5.19 processRegistration():确保所提交的数据是合法的
file
与程序清单5.17中最初的processRegistration()方法相比,有了很大的变化。在Spitter参数上添加了@Valid注解,告知Spring需要对该对象进行校验。
添加校验限制仍旧不能阻止表单提交
在Spitter属性上添加校验限制并不能阻止表单提交。即使用户没有填写某个域或某个域的值超过了最大长度,processRegistration()方法仍然会被调用。

处理校验错误

因此,我们需要处理校验错误,就像在processRegistration()方法中所示。
如果出现校验错误,这些错误可以通过Errors对象进行访问,该对象现在作为processRegistration()方法的参数。
需要注意的是,Errors参数紧跟在带有@Valid注解的参数后面,@Valid注解所标注的是要进行校验的参数。

processRegistration()方法

processRegistration()方法的第一件事是调用Errors.hasErrors()来检查是否有错误。

如果存在错误会怎么样?

如果存在错误,Errors.hasErrors()将返回到registerForm,即注册表单的视图。
这使得用户的浏览器可以返回到注册表单页面,以便他们可以修正错误并重新尝试提交。
现在,会显示一个空的表单,但在下一章中,我们将在表单中显示最初提交的值,并将校验错误反馈给用户。

如果没有错误会怎么样

如果没有错误的话,Spitter对象将会通过Repository进行保存,控 制器会像之前那样重定向到基本信息页面。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消