防止表单重复提交的代码

来源:互联网 发布:vb与plc通讯 编辑:程序博客网 时间:2024/06/05 18:07
自己控制防止表单重复提交也不是办法,即浪费时间还存在效率问题,现在把项目中这个防止表单重复提交的代码共享一下,如果使用直接拷贝粘贴就可以:Html代码<%@ page contentType="text/html; charset=GBK"%><% TokenProcessor tokemProcessor=TokenProcessor.getInstance(); tokemProcessor.saveToken(request); String token=(String)request.getSession().getAttribute(tokemProcessor.FORM_TOKEN_KEY); %>
生成token,主要工具类Java代码import java.securITy.MessageDigest;import java.security.NoSuchAlgorithmException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;public class TokenProcessor { private long privious;//上次生成表单标识号得时间值 private static TokenProcessor instance=new TokenProcessor(); public static String FORM_TOKEN_KEY="FORM_TOKEN_KEY"; private TokenProcessor(){ } public static TokenProcessor getInstance(){ return instance; } /**//* * 验证请求中得标识号是否有效,如果请求中的表单标识与当前用户session中的相同,返回结果true= */ public synchronized boolean isTokenValid(HttpServletRequest request){ //未避免session对象不存在时候创建Session对象 HttpSession session=request.getSession(false); if(session==null){return false;} String saved=(String)session.getAttribute(FORM_TOKEN_KEY); if(saved==null){ return false; } String token=(String)request.getParameter(FORM_TOKEN_KEY); if(token==null){ return false; } return saved.equals(token); } /**//* * 清楚存储在当前用户session中的表单标识号 */ public synchronized void reset(HttpServletRequest request){ HttpSession session=request.getSession(false); if(session==null){ return; } session.removeAttribute(FORM_TOKEN_KEY); } /**//* * 产生表单标识号并将之保存在当前用户得session中 */ public synchronized void saveToken(HttpServletRequest request){ HttpSession session=request.getSession(); try { byte id[]=session.getId().getBytes(); long current=System.currentTimeMillis(); if(current==privious){ current++; } privious=current; byte now[]=String.valueOf(current).getBytes(); MessageDigest md=MessageDigest.getInstance("MD5"); md.update(id); md.update(now); String token=toHex(md.digest()); session.setAttribute(FORM_TOKEN_KEY, token); } catch (NoSuchAlgorithmException e) { } } /**//* * 将一个字节数转换成十六进制得字符串 * */ public String toHex(byte buffer[]){ StringBuffer sb=new StringBuffer(buffer.length*2); for (int i = 0; i < buffer.length; i++) { sb.append(Character.forDigit((buffer[i]&0x60)>>4, 16)); sb.append(Character.forDigit(buffer[i]&0x0f, 16)); } return sb.toString(); }}提交处理Java代码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 FormDoubleServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=gb2312"); PrintWriter out=response.getWriter(); TokenProcessor tokemProcessor=TokenProcessor.getInstance(); if(!tokemProcessor.isTokenValid(request)){ out.println("重复提交"); } String p1=request.getParameter("p"); if(p1==null||p1.trim().equals("")){ out.println("请输入内容"); }else{ out.println("提交内容被处理"); tokemProcessor.reset(request);//清楚session中的标识 } }}