zoukankan      html  css  js  c++  java
  • 自定义token注解,防止表单重复提交

     WebMvcConfigurerAdapter

    @Configuration
    public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
        /**
         * 支持RESTful
         *
         * @return
         */
        @Bean
        public HttpPutFormContentFilter httpPutFormContentFilter() {
            return new HttpPutFormContentFilter();
        }
        /**
         * 添加静态资源
         *
         * @param registry
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        }
        /**
         * 添加拦截器
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new FormTokenInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);
        }
    }

    注解类

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Token {
     
        boolean save() default false;
     
        boolean remove() default false;
     
    }

    拦截器

    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;
                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)) {
                            response.sendRedirect(request.getContextPath() + "/error_401");
                            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;
        }
    }

    form中加隐藏的input

    <input type="hidden" name="token" value="${token}"/>

    使用token注解

    一个加@Token(save=true),这个方法是你跳到要提交的表单页面的方法,另一个加@Token(remove=true),这个方法是提交表单的方法

    @Token(save = true)
    public String addPage() {}
    
    @Token(remove = true)
    public String addSubmit() {}
  • 相关阅读:
    Ecplilse使用
    JDK安装
    浏览器的前世今生
    RethinkDB
    [css]兼容性
    【js】undefined
    String面试题
    SOS.dll(SOS 调试扩展)
    【ajax跨域】原因原理解决
    腾讯WEB前端开发三轮面试经历及面试题
  • 原文地址:https://www.cnblogs.com/xiaomaoyvtou/p/14115852.html
Copyright © 2011-2022 走看看