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