最近再开发一个图书管理的项目,在线发布图书的时候,明明只点击了一下,偏偏却保存了多条记录,无奈之下只好加拦截器防止重复提交:
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,到这里大功告成,你就可以发现已经没有办法重复提交数据了!