自定义jsp标签来防止表单的重复提交

  在之前的工作和学习中总是会遇到表单重复提交的问题,使用了网上的各种解决方法 js,禁用提交按钮,阻止用户后退等操作,但是效果总有一些欠缺。在这里参考了某位老师的意见,决定使用session和自定义表单的形式进行解决。

1、实现思路:

   在页面存放一个含有唯一值key value对将其存放在session(这里采用jsp自定义标签的方式进行实现,避免在jsp页面中写很多的java脚本 导致页面混乱)

   在提交表单时,后台的处理逻辑获取request中的session 并去取出其中指定的值,第一次获取对应的值后就将其对应的值设置为null,则用户无论以(刷新,后退,重新)等方式进行再次提交。则第二次或者多次提交到后台获取的数据为null时,则判断为重复提交。

2、jsp自定义标签的原理

自定义jsp标签来防止表单的重复提交

3、编写jsp的自定义标签

    继承SimplTagSupport类,并重新覆盖其中的doTag对象,在其中获取session,并设置唯一的key-value对

 <code>

  /**
 * 防止表单重复提交的jsp标签类
 * @author xieqx
 *
 */
public class TokenTag extends SimpleTagSupport{

//在调用方法之前,该类对象已经被注入了PageContext(可以从其中获取session) 
//该对象由setJspContext()方法调用 返回JspContext (其实返回的真实类型为PageContext 
//JspContext 其实为PageContext的父类)

@Override
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext)getJspContext();  //获取jsp的九大域对象
HttpSession session = pageContext.getSession();
session.setAttribute("token", UUID.randomUUID().toString());
}
}  

</code>


4、编写tld文件

<code>

 <?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
   
  <!-- tld版本 --> 
  <tlib-version>1.0</tlib-version>
  <!-- 在jsp页面引入该标签时使用的前缀 -->
  <short-name>xieqx</short-name>
  <!-- 指定使用该标签库中标签的URI -->
  <uri>http://www.babasport.com/xiu</uri>
   <tag>
        <!-- 标签名称  -->
    <name>token</name>
    <!-- 标签的实现类 -->
    <tag-class>cn.xiu.simpletag.TokenTag</tag-class>
    <!-- 此标签的主体部分的内容。   
                       其值可为
            scriptless 标签中所含有的内容可以为 文本、EL和JSP语言
            tagdependent 标签主题内容由标签处理类来解析, 标签主体所有代码原封不动地传递给标签处理类
                                                        意思是  如果标签主题中的内容为 <a></a> 等html标签或者el表达式等语言 在页面展示时不进行解析,
                                                        而是直接传递给标签处理泪
            empty 空标记,即起始标记和结束标记之间没有内容
                       默认为empty -->
    <body-content>empty</body-content>
  </tag>
</taglib>

</code>

      有关tld文件中标签元素的详细内容请参考:http://blog.****.net/u012031380/article/details/53517400

将编写好的tld文件放置到项目的WEB-INF下在项目启动后会自动的加载。

5、在jsp页面中进行引入相应的标签进行使用

  <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

  <!-- 引入要使用的自定义的jsp标签 -->
  <%@ taglib uri="http://www.babasport.com/xiu" prefix="xieqx" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'simpleTag2.jsp' starting page</title>
    
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">    
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->


  </head>
  <body>
     <xieqx:token /> //使用自定义的token标签
     <input type="button" value="提交" onclick="submit();" />
     <script type="text/javascript">
        function submit(){
        window.location.href="${pageContext.request.contextPath}/token.do";
        } 
     </script>
  </body>
</html>


5、使用servlet作为后台处理类

public class TokenServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
String uuid = (String) session.getAttribute("token");
if(uuid!=null){
//销毁session 防止表单重复提交
System.out.println("模拟表单第一次提交"+uuid);
session.setAttribute("token", null);
}else{
System.out.println("表单重复提交!!!");
}
}
}

6、调试运行

第一次访问:

自定义jsp标签来防止表单的重复提交

以后的所有提交操作均显示表单重复提交

自定义jsp标签来防止表单的重复提交

演示完毕,有啥差错大家请指教。