防止表单重复提交

来源:互联网 发布:传智播客大数据第三期 编辑:程序博客网 时间:2024/06/10 09:40

一,新建一个注解,标注需要防止重复提交的表单方法

/**

 * 防止重复提交的注解

 * @author hwt

 */

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface CheckTokenAnnocation {

}

 

二,新增自定义标签

 1,在WEB-INF下新建一个tld标签文件,如下:

 

 

myTag.tld内容如下:

<?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 web-jsptaglibrary_2_0.xsd"

version="2.0">

<description>自定义标签</description>

<tlib-version>1.0</tlib-version>

<jsp-version>1.2</jsp-version>

<short-name>myToken</short-name>

<tag>

<name>token</name>

<tag-class>com.hwt.common.TokenTag</tag-class>

<body-content>empty</body-content>

</tag>

</taglib>

 

2. 新建标签类,TokenTag.java (包路径与上面myTag.tldtag-class中的内容一致)

/**

 * 自定义标签:授权令牌

 * @author hwt

 *

 */

public class TokenTag extends TagSupport{

private static final long serialVersionUID = -3347882989992304183L;

 

@Override

public int doStartTag() throws JspException {

//获取request对象

HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();

//令牌UUID

String tokenID = UUID.randomUUID().toString();

request.getSession().setAttribute("stoken", tokenID);

try {

pageContext.getOut().print("<input type='hidden' value='"+tokenID+"' name='rtoken'/>");

catch (IOException e) {

e.printStackTrace();

}

return (SKIP_BODY);

}

}

 

3.在web.xml中配置自定义标签

<jsp-config>

    <taglib>

        <taglib-uri>/mytaglib</taglib-uri>

        <taglib-location>/WEB-INF/myTag.tld</taglib-location>

    </taglib>

 </jsp-config>

 

 

 

三,新建拦截器类

/**

 * 防止重复提交拦截器

 * @author hwt

 *

 */

public class TokenInterceptor extends HandlerInterceptorAdapter{

/**

 * 在进入提交方法的时候拦截

 */

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,

Object handler) throws Exception {

if (handler instanceof HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) handler;

CheckTokenAnnocation ct = handlerMethod.getMethodAnnotation(CheckTokenAnnocation.class);

if (ct != null) {

if(!checkToken(request)){

response.setContentType("text/html;charset=utf-8");

response.getWriter().print("<script>alert('重复提交!');</script>");

return false;

}

}

}

return true;

}

 

/**

 * 判断是否是重复提交

 * @param request

 * @return

 */

private boolean checkToken(HttpServletRequest request){

//request中的token

String rtoken = request.getParameter("rtoken");

//session中的token

HttpSession session = request.getSession();

String stoken = (String) session.getAttribute("stoken");

// token相等或服务器token已销毁时,不是重复提交

if (StringUtils.isBlank(stoken) || StringUtils.equals(rtoken, stoken)) {

session.setAttribute("stoken", UUID.randomUUID().toString());

return true;

}else {

return false;

}

}

}

 

 

 

四,使用:

1.在页面导入自定义标签

2.在表单中加入<my:token/>标签

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

<%@ taglib prefix="my" uri="/mytaglib"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <title>测试重复提交</title>

  </head>

  

  <body>

     <form action="${basepath}/test/test.action" method="post">

      <my:token/>

      <input type="submit" value="提交" />

     </form>

  </body>

</html>

3.在需要防止重复提交的方法上加入注解

@CheckTokenAnnocation

@RequestMapping("/test/test.action")

public String test(){

return "test/MyJsp";

     }



0 0
原创粉丝点击