国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

springmvc 用攔截器+token防止重復提交

2019-11-09 20:22:08
字體:
來源:轉載
供稿:網友

原文地址:http://www.cnblogs.com/hdwpdx/archive/2016/03/29/5333943.html

首先,防止用戶重復提交有很多種方式,總體分為前端JS限制和后端限制,我個人認為后端限制比較妥當(本著能做到更優秀得理念,舍去了前端JS限制重復提交得想法).  之前沒有做過防止用戶重復提交,所以直接百度了一大堆,竟然發現基本上可以歸為2到3種真正不同實現得代碼,文章雖然有很多,不過大部分代碼幾乎都出自同一人,原文網址:http://blog.icoolxue.com/submitted-by-sPRing-mvc-to-prevent-data-duplication/,想著這么多人用代碼應該沒問題,所以該復制復制,該手建手建,終于大工搞成,但是測試得時候發現了一個很重要得問題,永遠處于重復提交狀態,我得天啊,這就很尷尬了,于是趕緊打斷點,F6F6F6,終于懷疑了一行代碼,貼代碼:復制代碼 private boolean isRepeatSubmit(HttpServletRequest request) {        String serverToken = (String) request.getsession(true).getAttribute("token");        if (serverToken == null) {            return true;        }        String clinetToken = request.getParameter("token");//就是這行 NULL,永遠是NULL。        if (clinetToken == null) {            return true;        }        if (!serverToken.equals(clinetToken)) {            return true;        }        return false;    }嘿我就那了悶,怎么會接收不到值呢?肯定是頁面有問題了,頁面就只有一句話<input type="hidden" name="token" value="${token}" />我突然腦袋靈光一閃,通過name值傳值必須在form表單里才行,我全是Ajax啊,于是趕緊在傳遞參數中加上token,問題也就順利得結果了!但是我就再想,這么多人復制原文得代碼,然后發到自己得博客,難道沒有出現這種問題嘛?問題解決了,順便總結一下token得使用方法,切記代碼沒問題,復制需謹慎(該改得記得改!)首先自定義一個注解: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;}接著實現一個攔截器借口: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;    }}最后是配置文件:<!-- 攔截器配置 --><mvc:interceptors>        <!-- 配置Token攔截器,防止用戶重復提交數據 -->        <mvc:interceptor>            <mvc:mapping path="/**"/><!--這個地方時你要攔截得路徑 我這個意思是攔截所有得URL-->            <bean class="com.dinfo.interceptor.TokenInterceptor"/><!--class文件路徑改成你自己寫得攔截器路徑!! -->        </mvc:interceptor></mvc:interceptors>最最最重要得一點一定要保證頁面和后臺token得正常傳遞!!!在需要生成token(通常是要點擊提交得那個頁面)得Controller中使用我們剛才自定義好得注解,貼代碼:    @SuppressWarnings({ "unchecked", "finally", "rawtypes" })    @RequestMapping("/SaveDataController/show")    @Token(save=true)    public String saveData(HttpServletRequest request,HttpServletResponse response,String task_id){                Map map = new HashMap();        System.out.println(task_id);        try {            map = saveDataService.queryByTaskId(task_id);        } catch (Exception e) {            e.printStackTrace();            map.put("task_id", task_id);            map.put("savetype", "");            map.put("memoryCodes", "1");            map.put("tablename", "");            map.put("trowkey", "");            map.put("columns", "");            map.put("indextablename", "");            map.put("irowkey", "");            map.put("icolumns", "");        } finally {            request.setAttribute("map", map);            return "savedata/index";        }    }只要通過這個方法跳向得頁面都是隨機生成一個token,然后再真正再提交觸發得方法上加入@token(remove=true),貼代碼:@RequestMapping("/SaveDataController/saveData")    @ResponseBody    @Token(remove=true)    public void saveData(HttpServletRequest request,HttpServletResponse response,                         String tablename,String trowkey,String columns,                         String indextablename,String irowkey,String icolumns,                         String task_id,String savetype,String memoryCodes){        System.out.println(task_id);        saveDataService.saveData(task_id,savetype,memoryCodes,tablename, trowkey, columns, indextablename, irowkey, icolumns);    }OK,到這里大功告成,你就可以發現已經沒有辦法重復提交數據了!有問題可以隨時找我溝通。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 筠连县| 绥德县| 体育| 天镇县| 台中县| 桃源县| 昆明市| 科技| 峨山| 谷城县| 常州市| 获嘉县| 安新县| 广水市| 察隅县| 吕梁市| 松江区| 苏州市| 连山| 特克斯县| 江阴市| 安康市| 浮梁县| 门源| 信丰县| 东丽区| 贡嘎县| 云和县| 马公市| 龙江县| 南召县| 湘潭县| 湖北省| 邓州市| 芜湖县| 白银市| 砚山县| 临潭县| 新昌县| 陈巴尔虎旗| 吉林省|