SpringBoot防止表单重复提交(一)
一、重复提交的原因
用户表单登陆后直接转发到相应的页面,这是刷新页面会重复发送上次的请求,也就是会再次提交表单(浏览器会弹出表单重复提交的弹窗)
二、解决方法(存在漏洞)
- 在后台登录成功后
重定向
到指定页面
@PostMapping("/login")
public String login(@RequestParam("name") String name, @RequestParam("pwd")String pwd, Map<String,Object> map){
if (StringUtils.isEmpty(name) || StringUtils.isEmpty(pwd)){
map.put("msg","error");
return "login";
}
// 成功跳转到success后,如果刷新页面。会提示重新提交表单的请求
// return "success";
// 为了防止表单重复提交,这里将请求重定向到主页
return "redirect:/main.html";
}
- 追加映射
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
// 页面跳转,映射
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/main.html").setViewName("success");
}
}
三、漏洞
上面的方法存在漏洞,如果直接访问main.html则不需要登陆就能访问
四、拦截器解决漏洞
- 自定义拦截器类
/**
* 自定义拦截器
*/
public class MyIntercept implements HandlerInterceptor {
/**
*在业务处理器处理请求之前被调用
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object username = request.getSession().getAttribute("username");
if(username == null)
{ // 未登录,返回转发到登录页面
request.setAttribute("msg","先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}
return true;
}
/**
*在业务处理器处理请求执行完成后,生成视图之前执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
*在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- 注入拦截器
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
// 页面跳转,映射
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/change.html").setViewName("login");
registry.addViewController("/main.html").setViewName("success");
}
// 拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
registry.addInterceptor(new MyIntercept())
// 设置拦截的请求
.addPathPatterns("/**")
// 设置不拦截的请求
// 静态资源不需要设置,springboot已经做好了处理
.excludePathPatterns("/index.html","/","/change.html","/login");
}
}
版权声明:本文为XiaoBaiYiMei1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。