Spring提供了通过RedirectAttributes属性设置flash属性的方法,这是Spring3.1引入的Model的一个子接口。
在我们开发注册功能的时候,经常会有这样一个需求。当用户将填写好的信息提交到服务器后,控制器应判断用户填写信息的合理性,若有错误应该将提示错误的信息和用户填好的信息返回注册界面。这个功能可以用session实现,但是flash属性可以更好地实现这个功能。因为flash也是将对应的信息存到session,但是flash中的session是一次性的,即刷新后就会清除该session。
示例:
注册界面 register.jsp:
<div class="registered">
<div class="reg">
<div class="title">新用户注册</div>
<form action="register/reg.do" method="post" id="registerUser">
<ul class="cont">
<li style="color:red;font-size:20px;">${errorMsg}</li>
<li>
<input type="text" class="input user" id="user" name="name" placeholder="请输入用户名" value="${user.name}" >
<div class="tips" id="userTips">不建议用真实姓名</div>
</li>
<li>
<input type="password" class="input password" id="password" name="password" placeholder="请输入密码">
<div class="tips" id="passwordTips">6~20位,字母、数字和常用字符两种及以上的组合(不含空格)</div>
</li>
<li>
<input type="password" class="input passwordTwo" id="passwordTwo" name="passwordTwo" placeholder="再次确认密码">
<div class="tips" id="passwordTwoTips"></div>
</li>
<li>
<input type="text" class="input phone" id="phone" name="mobile" placeholder="请输入手机号码" value="${user.mobile}">
<div class="tips" id="phoneTips">请输入手机号码</div>
</li>
<li>
<input type="text" class="input invite" id="invite" name="invite" placeholder="邀请人手机号码" value="${invite}">
<div class="tips" id="inviteTips">如无可不填写</div>
</li>
<li>
<input type="text" class="input code" id="picCode" name="captchacode" placeholder="请输入图中字符">
<img src="captcha" class="refresh" onclick="this.src='captcha?t='+new Date()*1">
<div class="tips" id="picCodeTips"></div>
</li>
<li>
<input type="text" class="input code codeTwo" id="phoneCode" name="phoneCode" placeholder="输入手机验证码">
<input type="button" class="btn" id="countdownTime" onclick="countdown('countdownTime');" value="获取手机验证码">
<div class="tips" id="phoneCodeTips"></div>
</li>
<li><input type="checkbox" id="protocol"><label for="protocol">我已阅读并同意</label><a class="protocol" onclick="showDiv('.protocolBox')">《用户注册协议》</a></li>
<li><security:csrfInput/><input type="button" class="subBtn" onclick="register();" value="注册"></li>
</ul>
</form>
</div>
</div>
public class AccountController extends BaseController {
/**
* 登录界面
*
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
return "front/account/login";
}
/**
* 注册界面
*/
@RequestMapping(value = "/reg.html", method = RequestMethod.GET)
public String reg(Model model) {
return "front/account/registered";
}
}
验证信息的控制器RegisterController.java:
public class RegisterController extends BaseController {
//短信发送Service
@Autowired
private SmsService smsService;
//验证码生成
@Autowired
private ImageCaptchaService imageCaptchaService;
//用户判断映射
@Autowired
TUsersMapper userMapper;
//写入User用的 Service
@Autowired
UserService userService;
@RequestMapping(value="/reg.do", method = RequestMethod.POST)
public String regSubmit(TUsers user,String passwordTwo,String invite,String captchacode,String phoneCode,HttpServletRequest request,RedirectAttributes model){
HttpSession session = request.getSession();
//验证图片验证码
String captchaId = session.getId();
if(!imageCaptchaService.validateResponseForID(captchaId, captchacode)){
model.addFlashAttribute("errorMsg", "图片验证码错误");
return "redirect:/account/reg.html";
}
//验证手机短信验证玛
Map<String,String> phoneSMSvalidateResult = smsService.phoneSMSvalidate(session, user.getMobile(), phoneCode);
if(!phoneSMSvalidateResult.get("errCode").equals("0")){
model.addFlashAttribute("user", user);
model.addFlashAttribute("invite", invite);
model.addFlashAttribute("errorMsg", phoneSMSvalidateResult.get("message"));
return "redirect:/account/reg.html";
}
userService.regist(user,invite);
//注册成功,返回登录界面
return "redirect:/account/login.html";
}
}
RegisterController中的RedirectAttributes将相关信息通过addFlashAttribute方法存到对应的key中,并重定向到AccountController,而AccountController中用Model接收这些信息,并将这些信息传到注册界面。由于是用了RedirectAttributes的flush属性,所以注册界面刷新一次后,就会将sesion清除掉,AccountController中的Model就没有存储任何信息