SpringBoot 访问动态资源 Thymeleaf 重复提交表单问题解决思路
SpringBoot 访问动态资源 Thymeleaf 重复提交表单问题解决思路
- 现象:F5刷新后弹提示框
- 原因分析:登录时发送/user/login post请求,转发到成功页面。当刷新此页面时,还是发送上一次的请求,表单就重复提交了。
- 解决:防止重复提交的办法:重定向 到成功页面
- 分析:跳转到的成功页面dashboard.html 需要经过模板引擎的解析,因此需要配置视图映射。
registry.addViewController("/main.html").setViewName("dashboard");
//所有的webMvcConfigurer组件都会一起起作用
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器会发送/dhu请求,来到success.html
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
同时,controller中设置资源重定向,即 :
登录成功,防止表单重复提交,可以重定向到主页(springmvc的重定向知识)
@PostMapping(value = "/user/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Map<String,Object> map) {
if(!StringUtils.isEmpty(username) && "1234".equals(password)) {
//登录成功,防止表单重复提交,可以重定向到主页
return "redirect:/main.html"; // /表示重定向到当前项目下
}
map.put("msg", "用户名或密码错误!");
return "index";
}
- 不过,这样也造成一个严重的问题:那就是使用其他浏览器访问对应地址http://localhost:8080/crud/main.html 可以直接跳转到主页,没有经过登录步骤,登录功能失效。
- 解决方案:使用拦截器机制进行登录检查
- 步骤:1.编写自定义拦截器
登录检查
package com.dhu.component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 登录检查
* @author zhou
* @create 2020/5/14
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
//目标方法执行之前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if(user == null) {
//未登录
request.setAttribute("msg", "没有权限请先登录");
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
}else {
//登录,放行请求
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.注册自己的拦截器,使它生效
@Override
//注册拦截器
public void addInterceptors(InterceptorRegistry registry) {
// /**表示//拦截任意多层路径下的任意请求
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
//springboot2.0默认拦截静态资源,所以需要排除
.excludePathPatterns("/", "/index.html","/user/login", "/asserts/**", "/webjars/**", "/asserts/css/**", "/asserts/js/**", "/asserts/img/**");
}
其中,我这里添加了视图映射
//所有的webMvcConfigurer组件都会一起起作用
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
- 运行效果:
- 直接访问main.html时,由于用户没有登录所有访问失败