○ 提供内容
○ 用户填写表单
○ 提交数据
○ 处理表单展示
○ 用户提交数据的支持
根据配置的InternalResourceViewResolver,将使用"/WEB-INF/views/registerForm.jsp"这个JSP来渲染注册表单。
在JSP中,有一个基础的HTML表单,其中包含用于记录用户的名字、姓氏、用户名和密码的表单域,以及一个提交按钮。 在该JSP中,
标签没有设置action属性。在这种情况下,当表单提交时,它会提交到与展示时相同的URL路径上,即"/spitter/register"。 这意味着需要在服务器端处理该HTTP POST请求。 现在,我们需要在Spitter-Controller中添加一个方法来处理这个表单的提交。图5 .5 注册页提供了一个表单,这个表单会由SpitterController 进行处理,完成为应用添加新用户的功能
当处理注册表单的POST请求时,控制器需要接收表单数据并将其保存为Spitter对象。
为了防止重复提交,应该将浏览器重定向到新创建用户的基本信息页面。
这些行为可以通过shouldProcessRegistration()方法进行测试。
程序清单5.16 测试处理表单的控制器方法
在之前创建的showRegistrationForm()方法的基础上,我们新增了一个processRegistration()方法。该方法接受一个Spitter对象作为参数,该对象具有firstName、lastName、username和password属性。这些属性将使用请求中的同名参数进行填充。
当InternalResourceViewResolver看到视图格式中的"redirect:"前缀时,它知道要将其解析为重定向的规则,而不是视图的名称。在本例中,它会将视图重定向到用户基本信息的页面。例如,如果Spitter.username属性的值为"jbauer",那么视图将重定向到"/spitter/jbauer"。
根据程序清单5.16中的测试,我们的任务应该已经完成。然而,在SpitterController中,我们还需要添加一个处理器方法来处理基本信息页面的请求。showSpitterProfile()方法将完成这项任务。
SpitterRepository通过用户名获取一个Spitter对象,showSpitterProfile()方法将获取到的对象添加到模型中,并返回基本信息页面的逻辑视图名"profile"。和本章其他展示的视图一样,基本信息视图也非常简单。
图5.6展现了在Web浏览器中渲染的基本信息页面。 下面是对这段内容进行梳理和润色后的输出: 如果表单中没有发送username或password,会发生什么情况呢?又或者,如果firstName或lastName的值为空或过长,会有什么影响呢?接下来,让我们看一下如何为表单提交添加校验,以避免数据的不一致性。
图5 .6 Spittr 的基本信息页展现了用户的情况,这些信息是 由SpitterController填充到模型中的
如果用户在提交表单时,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所提供的校验注解
除了表5.1中的注解,Java校验API的实现可能还会提供额外的校验注解。同时,也可以定义自己的限制条件。但就我们来讲,将会关注于上表中的两个核心限制条件。
请考虑要添加到Spitter域上的限制条件,似乎需要使用@NotNull和@Size注解。我们所要做的事情就是将这些注解添加到Spitter的属性上。下面的程序清单展现了Spitter类,它的属性已经添加了校验注解。
程序清单5.18 Spitter:包含了要提交到Spittle POST请求中的域 @NotNull注解,确保值不为null。 @Size注解,限制它们的长度在最大值和最小值之间。 对Spittr应用来说,这意味着用户必须要填完注册表单,并且值的长度要在给定的范围内。
我们已经为Spitter添加了校验注解,接下来需要修改processRegistration()方法来应用校验功能。 下面展示的是启用了校验功能的processRegistration()方法。 程序清单5.19 processRegistration():确保所提交的数据是合法的 与程序清单5.17中最初的processRegistration()方法相比,有了很大的变化。在Spitter参数上添加了@Valid注解,告知Spring需要对该对象进行校验。 添加校验限制仍旧不能阻止表单提交 在Spitter属性上添加校验限制并不能阻止表单提交。即使用户没有填写某个域或某个域的值超过了最大长度,processRegistration()方法仍然会被调用。
因此,我们需要处理校验错误,就像在processRegistration()方法中所示。
如果出现校验错误,这些错误可以通过Errors对象进行访问,该对象现在作为processRegistration()方法的参数。
需要注意的是,Errors参数紧跟在带有@Valid注解的参数后面,@Valid注解所标注的是要进行校验的参数。
processRegistration()方法的第一件事是调用Errors.hasErrors()来检查是否有错误。
如果存在错误,Errors.hasErrors()将返回到registerForm,即注册表单的视图。
这使得用户的浏览器可以返回到注册表单页面,以便他们可以修正错误并重新尝试提交。
现在,会显示一个空的表单,但在下一章中,我们将在表单中显示最初提交的值,并将校验错误反馈给用户。
如果没有错误的话,Spitter对象将会通过Repository进行保存,控 制器会像之前那样重定向到基本信息页面。
本文由博客一文多发平台 OpenWrite 发布!