自定义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() {}

 

posted on 2020-12-10 16:32  1zfang1  阅读(300)  评论(0编辑  收藏  举报

导航