JAVA–利用Filter和session防止页面重复提交

时间:2019-09-28
本文章向大家介绍JAVA–利用Filter和session防止页面重复提交,主要包括JAVA–利用Filter和session防止页面重复提交使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

JAVA–利用Filter和session防止页面重复提交
解决思路:
1 用户访问表单页面,先经过过滤器,过滤器设置一个随机id作为token令牌, 并将该token放入表单隐藏域中.
2 表单响应到浏览器,用户填充数据后提交请求;
3 请求经过过滤器,过滤器获取表单中的令牌进行验证,如果和之前生成的令牌一致,则将请求放行,并且清空令牌;
4 如果用户重复提交表单,请求经过过滤器,过滤器进行验证.因为第一次放行后令牌已经清空失效,令牌不一致,不放行.跳转到提醒界面.

需用知识:
1 过滤器基础知识
2 servlet基础知识
3 filter基础知识
4 jsp基础知识

代码实现

1 jsp实现form表单页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="login" method="post">
		<!-- 利用表单的隐藏域 保存token令牌 -->
		<!--  ${token}等价于req.getsession().getAttribute("token")-->
		
		<input type="hidden" name="token" value="${token}" />
		用户名:<input type="text" name="username"/><br/>
		密码:<input type="password" name="password"/><br/>
		<input type="submit" value="login"/>
	</form>
</body>
</html>

  

2 filter过滤器

package com.woniu.filter.controler;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet Filter implementation class TokenFilte
 */

//过滤所有servlet
@WebFilter("*")

public class TokenFilte implements Filter {

  
    public TokenFilte() {
        // TODO Auto-generated constructor stub
    }

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		//设置编码集
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charser=utr-8");
		//向下转型
		HttpServletRequest req=(HttpServletRequest) request;
		HttpServletResponse resp=(HttpServletResponse) response;
		
		//获取表单的token
		String parameterToken = req.getParameter("token");
		//获取session中的token
		String sessionToken = (String) req.getSession().getAttribute("token");
		
		//判断表单的token,不为空说明用户已经提交form表单,需要验证是否重复提交,
		//为空说明是第一次进入登录页面,需要设置token
		if (parameterToken!=null) {
			//判断两个令牌是否相等,相等则放行,并重置令牌
			if(parameterToken.equals(sessionToken)) {
				//重置令牌
				req.getSession().removeAttribute("token");
				chain.doFilter(request, response);
			}else {//说明是重复提交,转发到提示页面
				req.getRequestDispatcher("repeatReminder").forward(request, response);
				
			}
		}else {//第一次进来,需要设置令牌
			//生成宇宙唯一码
			String token = UUID.randomUUID().toString();
			//设置session
			req.getSession().setAttribute("token",token);
			//放行
			chain.doFilter(request, response);
		}
	
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}

}

  

3 表单响应的servlet
利用线程睡30秒,模拟网络拥堵

package com.woniu.filter.controler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class PrintUser
 */
@WebServlet("/login")
public class Login extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public Login() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			//线程睡30秒,便于演示网络拥堵
			Thread.sleep(30000);
			response.getWriter().write("登录成功");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

  

4 重复提交时响应的servlet
重复提交时跳转到该提醒页面

package com.woniu.filter.controler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class repeatReminder
 */
@WebServlet("/repeatReminder")
public class repeatReminder extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public repeatReminder() {
        super();
        // TODO Auto-generated constructor stub
    }
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().write("页面正在处理,请勿重复提交");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

  

原文地址:https://www.cnblogs.com/xiaobozhi/p/11604490.html