最近再开发一个图书管理的项目,在线发布图书的时候,明明只点击了一下,偏偏却保存了多条记录,无奈之下只好加拦截器防止重复提交:
1:首先定义注解:
首先自定义一个注解:
package com.dinfo.interceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
boolean save() default false;
boolean remove() default false;
}
2:接着实现一个拦截器借口:
package com.dinfo.interceptor; import java.lang.reflect.Method; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class TokenInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = Logger.getLogger(Token.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Token annotation = method.getAnnotation(Token.class); if (annotation != null) { boolean needSaveSession = annotation.save(); if (needSaveSession) { request.getSession(true).setAttribute("token", UUID.randomUUID().toString()); } boolean needRemoveSession = annotation.remove(); if (needRemoveSession) { if (isRepeatSubmit(request)) { LOG.warn("please don't repeat submit,url:"+ request.getServletPath()); return false; } request.getSession(true).removeAttribute("token"); } } return true; } else { return super.preHandle(request, response, handler); } } private boolean isRepeatSubmit(HttpServletRequest request) { String serverToken = (String) request.getSession(true).getAttribute("token"); if (serverToken == null) { return true; } String clinetToken = request.getParameter("token"); if (clinetToken == null) { return true; } if (!serverToken.equals(clinetToken)) { return true; } return false; } }
3: spring 拦截器配置:
<mvc:interceptors> <!-- 配置Token拦截器,防止用户重复提交数据 --> <mvc:interceptor> <mvc:mapping path="/**"/><!--这个地方时你要拦截得路径 我这个意思是拦截所有得URL--> <bean class="com.dinfo.interceptor.TokenInterceptor"/><!--class文件路径改成你自己写得拦截器路径!! --> </mvc:interceptor> </mvc:interceptors>
4:在跳转页面的方法加上 @Token(save=true)
@RequestMapping(value = "/webui/payPage.html", method = RequestMethod.GET) @Token(save=true) public ModelAndView gonext(HttpServletRequest request, HttpServletResponse response, ModelMap model, String id,int number) { ModelAndView mv=new ModelAndView(); FmUtils.FmData(request,model); if(!StringUtils.isEmpty(id)) { TudouBookInfo bookInfo=bookService.findById(id); if(!StringUtils.isEmpty(bookInfo)){ bookInfo.setNumber(number); float price=Float.parseFloat(bookInfo.getPrice()); float totalPrice=number *price; bookInfo.setTotalPrice(totalPrice+""); mv.addObject("book",bookInfo); } } mv.setViewName(MobilePageContants.MY_PAY_PAGE); mv.addObject("token",id); return mv; }
5:在提交的方法上加 @Token(remove=true)
@RequestMapping(value = "/webui/paysave.html", method = RequestMethod.POST) @Token(remove=true) public ModelAndView paysave(HttpServletRequest request, HttpServletResponse response, ModelMap model, String id,String number) { ModelAndView mv=new ModelAndView();
6:OK,到这里大功告成,你就可以发现已经没有办法重复提交数据了!