原理:在新建頁面中Session保存token隨機碼,當保存時驗證,經過後刪除,當再次點擊保存時因爲服務器端的Session中已經不存在了,全部沒法驗證經過。
注,若是是集羣的方式,則須要將token放入到緩存中便可。
註解Token代碼: java
@Target(ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) public @interface Token { boolean needSaveToken () default false ; boolean needRemoveToken () default false ; }
攔截器TokenInterceptor代碼: mysql
public class TokenInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException { 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( false ).setAttribute( "token" , UUID.randomUUID().toString()); } boolean needRemoveSession = annotation.remove(); if (needRemoveSession) { if (isRepeatSubmit(request)) { return false ; } request.getSession( false ).removeAttribute( "token" ); } } return true ; } else { return super .preHandle(request, response, handler); } } private boolean isRepeatSubmit(HttpServletRequest request) { String serverToken = (String) request.getSession( false ).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 ; } }
而後在Spring MVC的配置文件里加入:
web
Xml代碼spring
<!-- 攔截器配置 --> < mvc:interceptors > <!-- 配置Shiro攔截器,實現註冊用戶的注入 --> < mvc:interceptor > < mvc:mapping path = "/**" /> < bean class = "com.storezhang.video.shiro.ShiroInterceptor" /> </ mvc:interceptor > <!-- 配置Token攔截器,防止用戶重複提交數據 --> < mvc:interceptor > < mvc:mapping path = "/**" /> < bean class = "com.storezhang.web.spring.TokenInterceptor" /> </ mvc:interceptor > </ mvc:interceptors >
相關代碼已經註釋,相信你能看懂。
關於這個方法的用法是:在須要生成token的controller上增長@Token(save=true),而在須要檢查重複提交的controller上添加@Token(remove=true)就能夠了。
另外,你須要在view裏在form裏增長下面代碼:
sql
< input type = "hidden" name = "token" value = "${token}" />
在相關方法中加入註解 服務器
@RequestMapping("/save") @AvoidDuplicateSubmission(needRemoveToken = true) public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response) throws Exception { @RequestMapping("/edit") @AvoidDuplicateSubmission(needSaveToken = true) public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception {
獲取【下載地址】 java後臺框架 springmvc mybatis(oracle 和 mysql) HTML5 全新高大尚mybatis