• JavaWeb防止用户的重复请求提交


      这里实现这个重复提交的防止,是通过在一个FIlter过滤器中生成一个令牌token,保存在Session域中,然后在对这个token加密得到ciphertext(密文),将密文保存在request域中。如果在login.jsp中的一个隐藏表单项中取得这个request域中的密文(ciphertext)。提交到一个LoginServlet,进行判断令牌是否匹配成功,成功的话,就到数据库中查询操作,否则的话就打出提示消息。这样的话,就不会导致每一个请求均去数据库进行查询,导致系统超负荷的工作,不至于导致进行不必要的工作。

      代码如下:

      FilterToken.java

    package cn.geore.token;
    
    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.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    public class FilterToken implements Filter {
    
    	@Override
    	public void destroy() {
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response,
    			FilterChain chain) throws IOException, ServletException {
    		// 取得token
    		String token = uuid();
    		// 将uuid加密,得到密文
    		String ciphertext  = MD5AndSHAEncrypt.cipherKey("MD5", token);
    		// 将生成的token保存在session中
    		HttpServletRequest req = (HttpServletRequest) request;
    		HttpSession session = req.getSession();
    		session.setAttribute("token", token);
    		// 将ciphertext保存在request域中
    		request.setAttribute("ciphertext", ciphertext);
    		chain.doFilter(request, response);
    	}
    
    	@Override
    	public void init(FilterConfig arg0) throws ServletException {
    	}
    
    	// 生成一个token
    	private static String uuid() {
    		return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    	}
    }
    

      

      login.jsp

    <body>
        <form action="<%=request.getContextPath() %>/LoginServlet" method="get">
        	<input type="text" name="discription" />    
        	<input type="hidden" name="ciphertext" value="${requestScope.ciphertext}">
        	<input type="submit" value="提交" />
        </form>
    </body>

      LoginServlet.java

    package cn.geore.token;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		request.setCharacterEncoding("utf-8");
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter pw = response.getWriter();
    		String token = (String) request.getSession().getAttribute("token");
    		// 对token进行加密,判断传来的参数是否为同一个token
    		String ciphertext = request.getParameter("ciphertext");
    		if (ciphertext != null && token != null) {
    			if (ciphertext.equals(MD5AndSHAEncrypt.cipherKey(
    					MD5AndSHAEncrypt.ENCRYPT_ALGORITHM_MD5, token))) {
    				// 令牌正确匹配后,要将令牌从Session域中移除
    				request.getSession().removeAttribute("token");
    				pw.write("令牌正确,没有进行重复表单的提交");
    			}
    		}else {
    			pw.write("您正在进行非法的访问");
    		}
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    	}
    
    }
    

          

  • 相关阅读:
    利用“通过'反射方式'创建的对象”来创建对象的性能问题?
    Linq 学习笔记(一)
    说说数据类型转换帮助类
    使用公共静态属性的方式来代替公共静态字段(C#)
    支持差异数据保存的数据库实体类设计(二)(续)
    编程杂记
    Linq 学习笔记(二)
    UI版本WinDBG常用命令
    Oracle数据库卸载
    SAS框架问世
  • 原文地址:https://www.cnblogs.com/geore/p/7287038.html
Copyright © 2020-2023  润新知