基于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 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>
当用户名输入用户名和密码,点击登陆按钮,form表单提交,URL变为 http://ip:port/app/account/login,由对应的Controller进行处理:
@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";
}
之后浏览器页面显示为 /WEB-INF/jsp/index.jsp ,但是由于 InternalResourceViewResolver 是使用forward进行转发的,所以URL还是 http//ip:port/app/account/login。
此时如果点击浏览器回退键,页面跳转到最初的登陆界面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);