在做登錄頁面的時候,通常使用form表單同步提交的方法進行提交的,也就是在form表單里去寫action,如果登錄失敗,jsp通過jstl表達式獲取錯誤信息展示在頁面上,但是有一個問題就是,即使你刷新了頁面,錯誤提示一直存在,這是為什么呢;
問題分析,首先form表單采用同步校驗的方式提交,那么你的瀏覽器地址欄的地址就會變成,你提交表單的action的地址,(當然如果你用ajax的異步驗證的話,就不存在這個問題);所以數據到后台校驗不通過的時候,后台會返回登錄頁給你
同時攜帶一些信息,這樣前台就可以通過表達式去獲取信息了,那么此時你可能會去刷新瀏覽器,但是錯誤信息卻還存在,這是為什么呢?因為你的地址欄還是你提交表單的地址,所以當你在刷新的時候,實際上還是向后台提交表單了,所以會出現
頁面還會展示錯誤信息,(解決方案:可以使用ajax提交表單,這樣瀏覽器地址欄不會改變,你再次刷新的時候不會提交表單了,但這不是本文的主要解決方法)那么想一想為什么不用重定向呢?可以使用重定向,但是有一個問題是重定向怎么攜帶數據呢?
好:
Spring 3.1 提供了一個很好用的類:RedirectAttributes。 使用這個類,我們可以把參數隨着重定向傳到頁面,不需自己拼url了。
把上面方法參數中的Model換成RedirectAttributes,參數就自動跟在url后了。
但是,這樣頁面不能用el獲取到,還要另外處理,所以,我們還有一種方式,不拼url,用el獲取參數,就像普通轉發一樣。
還是使用RedirectAttributes,但是這次不用addAttribute方法,spring為我們准備了新方法,addFlashAttribute()。
這個方法原理是放到session中,session在跳到頁面后馬上移除對象。所以你刷新一下后這個值就會丟失。
package com.demo.controller; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller @RequestMapping("/user") public class DemoController { @RequestMapping("/login") // public String login(@RequestParam Map<String, String> user, Model model) { public String login(@RequestParam Map<String, String> user, RedirectAttributes model) { System.out.println("用戶提交了一次表單"); String username; if (user.get("name").isEmpty()) { username = "Tom"; } else { username = user.get("name"); } model.addFlashAttribute("msg", username); // return "home";//此方式跳轉,頁面刷新會重復提交表單 return "redirect:/user/toHome"; } @RequestMapping("/toHome") public String home(@ModelAttribute("msg") String msg, Model model) { System.out.println("拿到重定向得到的參數msg:" + msg); model.addAttribute("msg", msg); return "home"; } }
注意紅色部分,在校驗失敗的時候,重定向到一個Handler,該Handler獲取重定向的參數,將該參數保存並轉發頁面,由於重定向里的參數放到session中,session在跳到頁面后馬上移除對象。所以你刷新一下后這個值就會丟失,所以該Handler第一次返回的時候,將攜帶錯誤信息,此時瀏覽器的地址是該Handler的RequestMapping,當瀏覽器刷新的時候,該Handler已經無法獲取重定向參數(參數為null)了,所以只能返回頁面了;至此完美解決問題。
相當於驗證表單的時候,多進行了一步操作,但是也提醒了我們,增刪改的時候一定要注意使用的方式,即使用異步的操作,或者同步操作時要進行重定向!