拦截器springmvc防止表单重复提交【3】3秒后自动跳回首页【重点明白如何跳转到各自需要的页面没有实现 但是有思路】
【1】定义异常类
【重点】:异常类有个多参数的构造函数public CmsException(String s, String... args),可以用来接受多个参数:如(“异常信息”,“几秒跳转”,“跳转url”)
1 package com.jspxcms.core.support; 2 3 /** 4 * CmsException CMS异常 5 * 6 * @author liufang 7 * 8 */ 9 public class CmsException extends RuntimeException { 10 private static final long serialVersionUID = 1L; 11 private String[] args; 12 13 public CmsException() { 14 super(); 15 } 16 17 public CmsException(String s) { 18 super(s); 19 } 20 21 public CmsException(String s, String... args) { 22 super(s); 23 this.args = args; 24 } 25 26 public CmsException(String message, Throwable cause) { 27 super(message, cause); 28 } 29 30 public CmsException(Throwable cause) { 31 super(cause); 32 } 33 34 public String[] getArgs() { 35 return args; 36 } 37 38 public void setArgs(String[] args) { 39 this.args = args; 40 } 41 42 }
【2】web.xml中定义异常提示页面
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 3 <display-name>jspxcms</display-name> 4 <context-param> 5 <param-name>contextConfigLocation</param-name> 6 <param-value> 7 /WEB-INF/conf/context-*.xml 8 /WEB-INF/conf/custom-component.xml 9 /WEB-INF/conf/core/core-context-dao.xml 10 /WEB-INF/conf/core/core-context-service.xml 11 /WEB-INF/conf/core/core-context-directive.xml 12 /WEB-INF/conf/ext/ext-context-dao.xml 13 /WEB-INF/conf/ext/ext-context-service.xml 14 /WEB-INF/conf/ext/ext-context-directive.xml 15 /WEB-INF/conf/plugin/**/context-*.xml 16 </param-value> 17 </context-param> 18 <!-- 19 <filter> 20 <filter-name>urlRewriteFilter</filter-name> 21 <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> 22 <init-param> 23 <param-name>statusEnabled</param-name> 24 <param-value>false</param-value> 25 </init-param> 26 <init-param> 27 <param-name>statusPath</param-name> 28 <param-value>/status.jspx</param-value> 29 </init-param> 30 </filter> 31 --> 32 <filter> 33 <filter-name>timerFilter</filter-name> 34 <filter-class>com.jspxcms.common.web.TimerFilter</filter-class> 35 </filter> 36 <filter> 37 <filter-name>encodingFilter</filter-name> 38 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 39 <init-param> 40 <param-name>encoding</param-name> 41 <param-value>UTF-8</param-value> 42 </init-param> 43 <init-param> 44 <param-name>forceEncoding</param-name> 45 <param-value>true</param-value> 46 </init-param> 47 </filter> 48 <filter> 49 <filter-name>openEntityManagerInViewFilter</filter-name> 50 <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> 51 </filter> 52 <filter> 53 <filter-name>shiroFilter</filter-name> 54 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 55 <init-param> 56 <param-name>targetFilterLifecycle</param-name> 57 <param-value>true</param-value> 58 </init-param> 59 </filter> 60 <filter> 61 <filter-name>jspDispatcherFilter</filter-name> 62 <filter-class>com.jspxcms.common.web.JspDispatcherFilter</filter-class> 63 <init-param> 64 <param-name>prefix</param-name> 65 <param-value>/jsp</param-value> 66 </init-param> 67 </filter> 68 69 <!-- 70 <filter-mapping> 71 <filter-name>urlRewriteFilter</filter-name> 72 <url-pattern>/*</url-pattern> 73 <dispatcher>REQUEST</dispatcher> 74 </filter-mapping> 75 --> 76 <filter-mapping> 77 <filter-name>timerFilter</filter-name> 78 <url-pattern>*.servlet</url-pattern> 79 </filter-mapping> 80 <filter-mapping> 81 <filter-name>timerFilter</filter-name> 82 <url-pattern>/cmscp/*</url-pattern> 83 </filter-mapping> 84 <filter-mapping> 85 <filter-name>encodingFilter</filter-name> 86 <url-pattern>/cmscp/*</url-pattern> 87 </filter-mapping> 88 <filter-mapping> 89 <filter-name>openEntityManagerInViewFilter</filter-name> 90 <url-pattern>/cmscp/*</url-pattern> 91 </filter-mapping> 92 <filter-mapping> 93 <filter-name>shiroFilter</filter-name> 94 <url-pattern>/cmscp/*</url-pattern> 95 </filter-mapping> 96 <filter-mapping> 97 <filter-name>timerFilter</filter-name> 98 <url-pattern>*.jspx</url-pattern> 99 </filter-mapping> 100 <filter-mapping> 101 <filter-name>encodingFilter</filter-name> 102 <url-pattern>*.jspx</url-pattern> 103 </filter-mapping> 104 <filter-mapping> 105 <filter-name>openEntityManagerInViewFilter</filter-name> 106 <url-pattern>*.jspx</url-pattern> 107 </filter-mapping> 108 <filter-mapping> 109 <filter-name>shiroFilter</filter-name> 110 <url-pattern>*.jspx</url-pattern> 111 </filter-mapping> 112 113 <filter-mapping> 114 <filter-name>shiroFilter</filter-name> 115 <url-pattern>/</url-pattern> 116 </filter-mapping> 117 <filter-mapping> 118 <filter-name>timerFilter</filter-name> 119 <url-pattern>/</url-pattern> 120 </filter-mapping> 121 <filter-mapping> 122 <filter-name>encodingFilter</filter-name> 123 <url-pattern>/</url-pattern> 124 </filter-mapping> 125 <filter-mapping> 126 <filter-name>openEntityManagerInViewFilter</filter-name> 127 <url-pattern>/</url-pattern> 128 </filter-mapping> 129 130 <filter-mapping> 131 <filter-name>timerFilter</filter-name> 132 <url-pattern>*.jsp</url-pattern> 133 </filter-mapping> 134 <filter-mapping> 135 <filter-name>encodingFilter</filter-name> 136 <url-pattern>*.jsp</url-pattern> 137 </filter-mapping> 138 <filter-mapping> 139 <filter-name>openEntityManagerInViewFilter</filter-name> 140 <url-pattern>*.jsp</url-pattern> 141 </filter-mapping> 142 <filter-mapping> 143 <filter-name>jspDispatcherFilter</filter-name> 144 <url-pattern>*.jsp</url-pattern> 145 </filter-mapping> 146 147 <listener> 148 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 149 </listener> 150 <listener> 151 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 152 </listener> 153 <listener> 154 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 155 </listener> 156 <servlet> 157 <servlet-name>background</servlet-name> 158 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 159 <init-param> 160 <param-name>contextConfigLocation</param-name> 161 <param-value> 162 /WEB-INF/conf/servlet-back.xml 163 /WEB-INF/conf/core/core-controller-back.xml 164 /WEB-INF/conf/ext/ext-controller-back.xml 165 /WEB-INF/conf/plugin/**/controller-back.xml 166 </param-value> 167 </init-param> 168 <load-on-startup>1</load-on-startup> 169 </servlet> 170 <servlet> 171 <servlet-name>foreground</servlet-name> 172 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 173 <init-param> 174 <param-name>contextConfigLocation</param-name> 175 <param-value> 176 /WEB-INF/conf/servlet-fore.xml 177 /WEB-INF/conf/core/core-controller-fore.xml 178 /WEB-INF/conf/ext/ext-controller-fore.xml 179 /WEB-INF/conf/plugin/**/controller-fore.xml 180 </param-value> 181 </init-param> 182 <load-on-startup>1</load-on-startup> 183 </servlet> 184 <servlet> 185 <servlet-name>keepSessionServlet</servlet-name> 186 <servlet-class>com.jspxcms.common.web.KeepSessionServlet</servlet-class> 187 </servlet> 188 <servlet> 189 <servlet-name>captchaServlet</servlet-name> 190 <servlet-class>com.jspxcms.common.captcha.CaptchaServlet</servlet-class> 191 </servlet> 192 193 <servlet-mapping> 194 <servlet-name>background</servlet-name> 195 <url-pattern>/cmscp/*</url-pattern> 196 </servlet-mapping> 197 <servlet-mapping> 198 <servlet-name>foreground</servlet-name> 199 <url-pattern>*.jspx</url-pattern> 200 </servlet-mapping> 201 <servlet-mapping> 202 <servlet-name>keepSessionServlet</servlet-name> 203 <url-pattern>/keep_session.servlet</url-pattern> 204 </servlet-mapping> 205 <servlet-mapping> 206 <servlet-name>captchaServlet</servlet-name> 207 <url-pattern>/captcha.servlet</url-pattern> 208 </servlet-mapping> 209 210 <session-config> 211 <session-timeout>20</session-timeout> 212 </session-config> 213 214 <error-page> 215 <error-code>400</error-code> 216 <location>/errors/400.jsp</location> 217 </error-page> 218 <error-page> 219 <error-code>403</error-code> 220 <location>/errors/403.jsp</location> 221 </error-page> 222 <error-page> 223 <error-code>404</error-code> 224 <location>/errors/404.jsp</location> 225 </error-page> 226 <error-page> 227 <error-code>500</error-code> 228 <location>/errors/500.jsp</location> 229 </error-page> 230 <error-page> 231 <exception-type>javax.validation.ConstraintViolationException</exception-type> 232 <location>/errors/400.jsp</location> 233 </error-page> 234 <!-- shiro中没有权限是抛出异常 --> 235 <error-page> 236 <exception-type>org.apache.shiro.authz.AuthorizationException</exception-type> 237 <location>/errors/403.jsp</location> 238 </error-page> 239 <error-page> 240 <exception-type>org.springframework.dao.DataIntegrityViolationException</exception-type> 241 <location>/errors/data_integrity_violation_exception.jsp</location> 242 </error-page> 243 <error-page> 244 <exception-type>com.jspxcms.core.support.DeleteException</exception-type> 245 <location>/errors/delete_exception.jsp</location> 246 </error-page> 247 <error-page> 248 <exception-type>com.jspxcms.core.support.CmsException</exception-type> 249 <location>/errors/cms_exception.jsp</location> 250 </error-page> 251 252 <welcome-file-list> 253 <welcome-file>index.html</welcome-file> 254 <welcome-file>index.htm</welcome-file> 255 <welcome-file>index.shtml</welcome-file> 256 <welcome-file>index.shtm</welcome-file> 257 <welcome-file>index.jspx</welcome-file> 258 </welcome-file-list> 259 </web-app>
【3】产生异常的地方 此处为拦截器
【重点】相应的new CmsException("请不要重复提交申请!",“3”,“要分别跳转的url地址”);
1 package com.jspxcms.ext.interceptor; 2 3 import java.lang.reflect.Method; 4 import java.util.UUID; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.apache.log4j.Logger; 10 import org.springframework.web.method.HandlerMethod; 11 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 12 13 import com.jspxcms.core.support.CmsException; 14 15 public class TokenInterceptor extends HandlerInterceptorAdapter { 16 private static final Logger LOG = Logger.getLogger(TokenInterceptor.class); 17 18 19 20 @Override 21 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 22 if (handler instanceof HandlerMethod) { 23 HandlerMethod handlerMethod = (HandlerMethod) handler; 24 Method method = handlerMethod.getMethod(); 25 Token annotation = method.getAnnotation(Token.class); 26 if (annotation != null) { 27 boolean needSaveSession = annotation.save(); 28 if (needSaveSession) { 29 request.getSession(true).setAttribute("token", UUID.randomUUID().toString()); 30 } 31 boolean needRemoveSession = annotation.remove(); 32 if (needRemoveSession) { 33 if (isRepeatSubmit(request)) { 34 LOG.warn("please don't repeat submit,url:"+ request.getServletPath()); 35 throw new CmsException("请不要重复提交申请!"); 36 // return false; 37 } 38 request.getSession(true).removeAttribute("token"); 39 } 40 } 41 return true; 42 } else { 43 return super.preHandle(request, response, handler); 44 } 45 } 46 47 private boolean isRepeatSubmit(HttpServletRequest request) { 48 String serverToken = (String) request.getSession(true).getAttribute("token"); 49 if (serverToken == null) { 50 return true; 51 } 52 String clinetToken = request.getParameter("token"); 53 if (clinetToken == null) { 54 return true; 55 } 56 if (!serverToken.equals(clinetToken)) { 57 return true; 58 } 59 return false; 60 } 61 }
【4】jsp页面
【5】页面效果
【后面补充】:测试的时候发现 href用的是/index.jspx 如果不行 根据时间情况改写