Spring MVC 回退重新整理表單重複提交
阿新 • • 發佈:2019-02-19
基於Spring MVC進行Java Web開發時,如果使用表單進行提交資料,然後跳轉到某個URL由Controller進行處理,最後返回邏輯檢視,框架會通過viewResolver來解析具體的View,然後向返回給瀏覽器顯示【參考】。
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> <property name="viewClass" value="com.tplink.cloud.web.IcomJstlView"/> <property name="order" value="1"/> </bean>
比如最開始的登陸介面使用表單提交,其URL為 http://ip:port//app/account/, 表單內容如下:
當用戶名輸入使用者名稱和密碼,點選登陸按鈕,form表單提交,URL變為 http://ip:port/app/account/login,由對應的Controller進行處理:<form id="loginForm" name="loginForm" method="post" action="login"> <div id="login_form"> <p class="inputPrompt"></p> <input name="username" class="username" type="text" placeholder="郵箱" /> <input name="password" class="password" type="password" placeholder="密碼" /> <input class="buttonsubmit" type="submit" value="登陸" /> </div> </form>
之後瀏覽器頁面顯示為 /WEB-INF/jsp/index.jsp ,但是由於 InternalResourceViewResolver 是使用forward進行轉發的,所以URL還是 http//ip:port/app/account/login。@Controller @RequestMapping("/account") @SessionAttributes({"username", "accountType", "resetUsername", "resetVeriCode"}) public class AccountController { private AccountService accountService; @Autowired public AccountController(AccountService accountService) { this.accountService = accountService; } @RequestMapping("/login") public String login( @RequestParam String username, @RequestParam(value = "password", required = false) String password, @CookieValue(required = false) String token, HttpServletRequest request, HttpServletResponse response, ModelMap model) { //****** return "index"; }
此時如果點選瀏覽器回退鍵,頁面跳轉到最初的登陸介面URL:http://ip:port//app/account/ , 然後點選 前進按鍵,頁面出現 “重新整理重複提交表單” 的提示,點選重新整理,表單就重複提交然後跳轉到URL:http://ip:port/app/account/login了。
網上搜索可知,有很多處理方式,如使用PRG方法,即 Post - Redirect - Get 方式,還可以直接不適用表單Form,而是用javascript+ajax進行提交。
方法一:
PRG方法,只要在Controller中新增一個action如下:
@RequestMapping("/go")
public String go(@RequestParam String type) {
return type;
}
然後修改開始的action的return內容如下:
@RequestMapping("/login")
public String login(
@RequestParam String username,
@RequestParam(value = "password", required = false) String password,
@CookieValue(required = false) String token,
HttpServletRequest request, HttpServletResponse response,
ModelMap model) {
//******
return "redirect:/account/go?type=index";
}
由於此時使用redirect方法進行轉發,登陸之後對應的URL為:http://ip:port/app/account/go?type=index , 這樣點選回退再前進,頁面直接跳轉到 重定向之後的 URL,從而解決問題,從此也可以看出 forward 和 redirect 的區別【參考】
方法二:
不使用表單From提交,直接用javascript+ajajx提交,然後redirect(用到JQuery, 同時刪除登陸介面的from標籤):
var login = {
init : function(){
// validate input and password
$('.buttonsubmit').click(login.submitCheck);
},
submitCheck : function(){
var checkAccount = resetPassword.checkAccount();
if (checkAccount) {
var codeCheck = CheckUtil.ajaxCheckAccountPassword($(
'.username').val(), $('.password').val());
if (codeCheck == CheckUtil.STATUS.FAILED) {
$('.inputPrompt').html('使用者名稱密碼不匹配!');
return false;
}
if (codeCheck == CheckUtil.STATUS.PASSED) {
location.href = "go?type=index";
}
}
}
};
$(document).ready(login.init);