通过xml配置搞定Struts重复提交问题

来源:互联网 发布:金融大数据发展趋势 编辑:程序博客网 时间:2024/04/30 06:17

在webWork中有Token标签,可以直接搞定重复提交的问题,但在Struts2.0以下的版本,传统的做法只有通过提供的Token编程来搞定,代码虽然不多但是,这样的细节涉及了两个Action,对于页面的跳转控制来说是一个额外的负担,必须处处小心,本文阐述了如何通过Filter通过配置来避免struts的Form重复提交问题。
核心代码如下:

Java代码 复制代码
  1. package com.yapulan.util.filter;    
  2.   
  3. import java.io.IOException;    
  4. import java.util.HashMap;    
  5. import java.util.Iterator;    
  6. import java.util.List;    
  7.   
  8. import javax.servlet.Filter;    
  9. import javax.servlet.RequestDispatcher;    
  10. import javax.servlet.ServletException;    
  11. import javax.servlet.FilterConfig;    
  12. import javax.servlet.http.HttpServletRequest;    
  13. import javax.servlet.http.HttpServletResponse;    
  14. import javax.servlet.FilterChain;    
  15. import javax.servlet.ServletRequest;    
  16. import javax.servlet.ServletResponse;    
  17.   
  18. import org.apache.log4j.Logger;    
  19. import org.apache.struts.action.Action;    
  20. import org.apache.struts.action.ActionForm;    
  21. import org.apache.struts.action.ActionForward;    
  22. import org.apache.struts.action.ActionMapping;    
  23. import org.dom4j.Document;    
  24. import org.dom4j.Element;    
  25. import org.dom4j.io.SAXReader;    
  26.   
  27. /**   
  28. * 重复提交令牌自动加载器 功能:读取过滤器中设置的信息,读入令牌设置组   
  29. */    
  30.   
  31. public class TokenFilter implements Filter {    
  32.   
  33. private String TokenConfig = "TokenConfig.xml";    
  34. private HashMap TokenMap = null;    
  35. private HashMap ErrorMap = null;    
  36. protected FilterConfig filterConfig;    
  37. static Logger logger = Logger.getLogger(TokenFilter.class.getName());    
  38.   
  39. public void init(FilterConfig config) throws ServletException {    
  40. this.filterConfig = config;    
  41. this.TokenConfig = config.getInitParameter("tokenfile");    
  42. logger.debug("Tokenlist init OK!");    
  43. }    
  44.   
  45. /**   
  46. * 初始化系统的xml文件,读入令牌列表   
  47. */    
  48. @SuppressWarnings({ "unchecked""deprecation" })    
  49. public void initConfig(ServletRequest srequest) {    
  50.   
  51. HttpServletRequest httpRequest = (HttpServletRequest) srequest;    
  52. try {    
  53.   
  54. TokenMap = new HashMap();    
  55. ErrorMap = new HashMap();    
  56.   
  57. SAXReader reader = new SAXReader();    
  58. Document document = reader.read(httpRequest.getRealPath(this.TokenConfig));    
  59. List list1 = document.getRootElement().selectNodes("/TokenList/Token/TokenForm");    
  60. List list2 = document.getRootElement().selectNodes("/TokenList/Token/TokenAction");    
  61. List list3 = document.getRootElement().selectNodes("/TokenList/Token/ErrorPage");    
  62.   
  63. Iterator iter1 = list1.iterator();    
  64. Iterator iter2 = list2.iterator();    
  65. Iterator iter3 = list3.iterator();    
  66. while (iter1.hasNext()&&iter2.hasNext()&&iter3.hasNext()) {    
  67. Element element1 = (Element) iter1.next();    
  68. Element element2 = (Element) iter2.next();    
  69. Element element3 = (Element) iter3.next();    
  70. TokenMap.put(element1.getStringValue(), element2.getStringValue());    
  71. ErrorMap.put(element1.getStringValue(), element3.getStringValue());    
  72. }    
  73. logger.debug("TokenFilter Read "    
  74. + httpRequest.getRealPath(this.TokenConfig)    
  75. " is OK!");    
  76. catch (Exception e) {    
  77. logger.error("TokenFilter Read "    
  78. + httpRequest.getRealPath(this.TokenConfig)    
  79. " is Error!");    
  80. }    
  81.   
  82. }    
  83.   
  84. public void doFilter(ServletRequest srequest, ServletResponse sresponse,    
  85. FilterChain chain) throws IOException, ServletException {    
  86.   
  87. HttpServletRequest httpRequest = (HttpServletRequest) srequest;    
  88.   
  89. try {    
  90. //取出实际的文件路径直接调用文件,如index.html,login.jsp等    
  91. String toURI = httpRequest.getRequestURI().replaceFirst(httpRequest.getContextPath(), "");    
  92. if (TokenMap==null)    
  93. {    
  94. initConfig(httpRequest);    
  95. }    
  96. //检测为提交jsp页    
  97. if (TokenMap.get(toURI) != null)    
  98. {    
  99. FromTokenAction token = new FromTokenAction();    
  100. token.execute(nullnull, srequest, sresponse);    
  101. httpRequest.getSession().setAttribute("PRE_TOKEN_FORM", toURI);    
  102. logger.debug("TokenFilter save '"+toURI +"' at 'PRE_TOKEN_FORM' of Session!");    
  103. logger.debug("TokenFilter saveToken to '"+toURI +"' is OK!");    
  104. chain.doFilter(srequest, sresponse);    
  105. return;    
  106. }    
  107.   
  108. @SuppressWarnings("unused")    
  109. String preURI =(String)httpRequest.getSession().getAttribute("PRE_TOKEN_FORM");    
  110. //检测到为Action接收提交页面    
  111. if (TokenMap.get(preURI).equals(toURI))    
  112. {    
  113. TOTokenAction token = new TOTokenAction();    
  114. token.execute(nullnull, srequest, sresponse);    
  115. chain.doFilter(srequest, sresponse);    
  116. return;    
  117. }    
  118.   
  119.   
  120. catch (Exception e)    
  121. {    
  122. logger.error(e);    
  123. }    
  124.   
  125. chain.doFilter(srequest, sresponse);    
  126. }    
  127.   
  128. public void setFilterConfig(final FilterConfig filterConfig) {    
  129. this.filterConfig = filterConfig;    
  130. }    
  131.   
  132. public void destroy() {    
  133. TokenMap.clear();    
  134. ErrorMap.clear();    
  135. this.filterConfig = null;    
  136. }    
  137.   
  138. //检测到需要令牌增加一个令牌    
  139. public class FromTokenAction extends Action {    
  140. public ActionForward execute(ActionMapping mapping, ActionForm form,    
  141. HttpServletRequest request, HttpServletResponse response) {    
  142. this.saveToken(request);    
  143. return null;    
  144. }    
  145. }    
  146.   
  147. //到达Action前检测令牌    
  148. public class TOTokenAction extends Action {    
  149. public ActionForward execute(ActionMapping mapping, ActionForm form,    
  150. HttpServletRequest request, HttpServletResponse response) {    
  151. @SuppressWarnings("unused")    
  152. String preURI =(String)request.getSession().getAttribute("PRE_TOKEN_FORM");    
  153. //如果检测令牌错误执行错误页,正确将继续执行    
  154. if (!isTokenValid(request, true))    
  155. {    
  156. @SuppressWarnings("unused")    
  157. String toURI = (String)ErrorMap.get(preURI);    
  158. if (toURI!=null)    
  159. {    
  160. RequestDispatcher disp = request.getRequestDispatcher(toURI);    
  161. try {    
  162. disp.forward(request, response);    
  163.   
  164. }catch(Exception e)    
  165. {    
  166. logger.error(e);    
  167. }    
  168. }    
  169. }    
  170. return null;    
  171. }    
  172. }    
  173.   
  174. }   

 Web.xml的配制 

Java代码 复制代码
  1. <!-- 令牌自动加载配制 -->    
  2. <filter>    
  3.         <filter-name>tokenFilter</filter-name>    
  4.         <filter-class>com.yapulan.util.filter.TokenFilter</filter-class>    
  5.     <init-param>    
  6.     <param-name>tokenfile</param-name>    
  7.     <param-value>/WEB-INF/TokenConfig.xml</param-value>    
  8.     </init-param>    
  9.      </filter>    
  10.        
  11.     注意:将代码包中web.xml做以下修改    
  12.     <filter-mapping>    
  13.        <filter-name>tokenFilter</filter-name>    
  14.        <url-pattern/*</url-pattern>     
  15.      </filter-mapping>    
  16.         
  17.     

 设置好过滤器,只要配置列表即可避免所有的重复提交问题,不必在编程时再次考虑了

Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <TokenList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TokenConfig.xsd">    
  3. <Token>    
  4. <TokenForm>/index.jsp</TokenForm>    
  5. <TokenAction>/TokenAction.do</TokenAction>    
  6. <ErrorPage>/error.html</ErrorPage>    
  7. </Token>    
  8. <Token>    
  9. <TokenForm>/index1.jsp</TokenForm>    
  10. <TokenAction>/TokenAction1.do</TokenAction>    
  11. <ErrorPage>/error1.jsp</ErrorPage>    
  12. </Token>    
  13. <Token>    
  14. <TokenForm>/index2.jsp</TokenForm>    
  15. <TokenAction>/TokenAction2.do</TokenAction>    
  16. <ErrorPage>/error2.jsp</ErrorPage>    
  17. </Token>    
  18. <Token>    
  19. <TokenForm>/index3.jsp</TokenForm>    
  20. <TokenAction>/TokenAction3.do</TokenAction>    
  21. <ErrorPage>/error3.jsp</ErrorPage>    
  22. </Token>    
  23. </TokenList>   

 注意:本代码可以很好的验证非法的提交,对于管理非法的提交是一个不可多得的具有一定安全意义封装。
请热心的朋友分析有无其它没有考虑的细节问题,并且是否有可以进一部完善的地方,谢谢!

原创粉丝点击