Spring提供它自订的标签库,可以与相关的组件结合,提供页面与表单物件、错误讯息的数据绑 定功能,为节省篇幅,在这边以 SimpleFormController 来进行修改扩充,加入Spring的<bind>标 签功能,首先修改一下form.jsp:
<%@page contentType="text/html"%> <%@page?pageEncoding="UTF-8"%> <%@taglib prefix="spring"uri="http://www.springframework.org/tags"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login Form</title> </head> <body> <h1>登入表单</h1> <spring:bind path="command.*"> <font color="red"> <b>${status.errorMessage}</b> </font><br> </spring:bind> 请输入使用者名称与密码:<p> <form name="loginform" action="/SpringBindDemo/login.do" method="post"> <spring:bind path="command.username"> 名称 <input type="text" name="${status.expression}" value="${status.value}"/><br> </spring:bind> <spring:bind path="command.password"> 密码 <input type="password" name="${status.expression}" value="${status.value}"/><br> </spring:bind> <input type="submit" value="确定"/> </form> 注意:输入错误会再回到这个页面中。 </body> </html>
<spring:bind>的"path"属性设定了要绑定的表单物件名称,这个名称是设定在 loginController 中的 "commandName"属性,预设名称是"command",当设定为"command.*"时,表示绑定表单物件上 所有相关的数据, "status"的"errorMessage"会显示在 Controller 中设定的错误讯息,这待会在 Controller 的实作中会再看到说明。
在表单中,对于"username"栏位,绑定了"command.username"属性,"status"的"expression"会显 示绑定的属 性名称,而"value"则显示表单物件中所储存的值,这边设计的程式在登入失败后会 回到 form.jsp,这样可以在同一个页面上显示错误讯息与之前输 入错误的值。
为了配合 form.jsp 上的绑定标签之讯息显示,可以对 SimpleFormDemo 专案中 LoginController 类 别作一些修正:
package onlyfun.caterpillar; import org.springframework.validation.BindException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.mvc.SimpleFormController; import org.springframework.web.servlet.*; public class LoginController extends SimpleFormController { public LoginController() { setCommandClass(LoginForm.class); } protected ModelAndView onSubmit(Object command, BindException errors) throws Exception { LoginForm form = (LoginForm) command; if("caterpillar".equals(form.getUsername()) && "123456".equals(form.getPassword())) { return new ModelAndView(getSuccessView(),"user", form.getUsername()); } else { // 返回 Form 页面时,要有一个 errors 的 Model 实例 errors.reject("loginfail", "使用者名称或密码错误"); return new ModelAndView(getFormView(), errors.getModel()); } } }
Spring标签绑定需要一个BindException物件,所以这次使用了onSumit()的另一个版本,当验证失 败时,在 BindException中使用reject()方法,表示拒绝接受这次输入的数据,reject()接受两个参 数,第一个是error code,如果您有设定 MessageSource(参考 3.3.2),这会到您设定的.properties 档中依error code为键(Key),以找出相对应的讯息,如果没有设定MessageSource,则使用第二 个参数所设定的值作为错误讯息输出。
errors的getModel()方法返回一个Map物件,之前使用reject()所储存的错误讯息就包括在这个物件 中,将之设定给ModelAndView,这之后会处理为绑定讯息以在标签上输出。剩下的未呈现JSP网 页、类别与定义档等,都与 SimpleFormController 相同,如果登入错误,则会显示以下的内容, 数据绑定标签将错误讯息与之前输入的资料显示在对应的标签上。