`
lmzxx520
  • 浏览: 14275 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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

package com.yapulan.util.filter; 

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.List; 

import javax.servlet.Filter; 
import javax.servlet.RequestDispatcher; 
import javax.servlet.ServletException; 
import javax.servlet.FilterConfig; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.FilterChain; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 

import org.apache.log4j.Logger; 
import org.apache.struts.action.Action; 
import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionForward; 
import org.apache.struts.action.ActionMapping; 
import org.dom4j.Document; 
import org.dom4j.Element; 
import org.dom4j.io.SAXReader; 

/** 
* 重复提交令牌自动加载器 功能:读取过滤器中设置的信息,读入令牌设置组 
*/ 

public class TokenFilter implements Filter { 

private String TokenConfig = "TokenConfig.xml"; 
private HashMap TokenMap = null; 
private HashMap ErrorMap = null; 
protected FilterConfig filterConfig; 
static Logger logger = Logger.getLogger(TokenFilter.class.getName()); 

public void init(FilterConfig config) throws ServletException { 
this.filterConfig = config; 
this.TokenConfig = config.getInitParameter("tokenfile"); 
logger.debug("Tokenlist init OK!"); 
} 

/** 
* 初始化系统的xml文件,读入令牌列表 
*/ 
@SuppressWarnings({ "unchecked", "deprecation" }) 
public void initConfig(ServletRequest srequest) { 

HttpServletRequest httpRequest = (HttpServletRequest) srequest; 
try { 

TokenMap = new HashMap(); 
ErrorMap = new HashMap(); 

SAXReader reader = new SAXReader(); 
Document document = reader.read(httpRequest.getRealPath(this.TokenConfig)); 
List list1 = document.getRootElement().selectNodes("/TokenList/Token/TokenForm"); 
List list2 = document.getRootElement().selectNodes("/TokenList/Token/TokenAction"); 
List list3 = document.getRootElement().selectNodes("/TokenList/Token/ErrorPage"); 

Iterator iter1 = list1.iterator(); 
Iterator iter2 = list2.iterator(); 
Iterator iter3 = list3.iterator(); 
while (iter1.hasNext()&&iter2.hasNext()&&iter3.hasNext()) { 
Element element1 = (Element) iter1.next(); 
Element element2 = (Element) iter2.next(); 
Element element3 = (Element) iter3.next(); 
TokenMap.put(element1.getStringValue(), element2.getStringValue()); 
ErrorMap.put(element1.getStringValue(), element3.getStringValue()); 
} 
logger.debug("TokenFilter Read " 
+ httpRequest.getRealPath(this.TokenConfig) 
+ " is OK!"); 
} catch (Exception e) { 
logger.error("TokenFilter Read " 
+ httpRequest.getRealPath(this.TokenConfig) 
+ " is Error!"); 
} 

} 

public void doFilter(ServletRequest srequest, ServletResponse sresponse, 
FilterChain chain) throws IOException, ServletException { 

HttpServletRequest httpRequest = (HttpServletRequest) srequest; 

try { 
//取出实际的文件路径直接调用文件,如index.html,login.jsp等 
String toURI = httpRequest.getRequestURI().replaceFirst(httpRequest.getContextPath(), ""); 
if (TokenMap==null) 
{ 
initConfig(httpRequest); 
} 
//检测为提交jsp页 
if (TokenMap.get(toURI) != null) 
{ 
FromTokenAction token = new FromTokenAction(); 
token.execute(null, null, srequest, sresponse); 
httpRequest.getSession().setAttribute("PRE_TOKEN_FORM", toURI); 
logger.debug("TokenFilter save '"+toURI +"' at 'PRE_TOKEN_FORM' of Session!"); 
logger.debug("TokenFilter saveToken to '"+toURI +"' is OK!"); 
chain.doFilter(srequest, sresponse); 
return; 
} 

@SuppressWarnings("unused") 
String preURI =(String)httpRequest.getSession().getAttribute("PRE_TOKEN_FORM"); 
//检测到为Action接收提交页面 
if (TokenMap.get(preURI).equals(toURI)) 
{ 
TOTokenAction token = new TOTokenAction(); 
token.execute(null, null, srequest, sresponse); 
chain.doFilter(srequest, sresponse); 
return; 
} 


} catch (Exception e) 
{ 
logger.error(e); 
} 

chain.doFilter(srequest, sresponse); 
} 

public void setFilterConfig(final FilterConfig filterConfig) { 
this.filterConfig = filterConfig; 
} 

public void destroy() { 
TokenMap.clear(); 
ErrorMap.clear(); 
this.filterConfig = null; 
} 

//检测到需要令牌增加一个令牌 
public class FromTokenAction extends Action { 
public ActionForward execute(ActionMapping mapping, ActionForm form, 
HttpServletRequest request, HttpServletResponse response) { 
this.saveToken(request); 
return null; 
} 
} 

//到达Action前检测令牌 
public class TOTokenAction extends Action { 
public ActionForward execute(ActionMapping mapping, ActionForm form, 
HttpServletRequest request, HttpServletResponse response) { 
@SuppressWarnings("unused") 
String preURI =(String)request.getSession().getAttribute("PRE_TOKEN_FORM"); 
//如果检测令牌错误执行错误页,正确将继续执行 
if (!isTokenValid(request, true)) 
{ 
@SuppressWarnings("unused") 
String toURI = (String)ErrorMap.get(preURI); 
if (toURI!=null) 
{ 
RequestDispatcher disp = request.getRequestDispatcher(toURI); 
try { 
disp.forward(request, response); 

}catch(Exception e) 
{ 
logger.error(e); 
} 
} 
} 
return null; 
} 
} 

} 

 Web.xml的配制 

<!-- 令牌自动加载配制 --> 
<filter> 
        <filter-name>tokenFilter</filter-name> 
        <filter-class>com.yapulan.util.filter.TokenFilter</filter-class> 
    <init-param> 
    <param-name>tokenfile</param-name> 
    <param-value>/WEB-INF/TokenConfig.xml</param-value> 
    </init-param> 
     </filter> 
    
    注意:将代码包中web.xml做以下修改 
    <filter-mapping> 
       <filter-name>tokenFilter</filter-name> 
       <url-pattern/*</url-pattern>  
     </filter-mapping> 
     
  

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

<?xml version="1.0" encoding="UTF-8"?> 
<TokenList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TokenConfig.xsd"> 
<Token> 
<TokenForm>/index.jsp</TokenForm> 
<TokenAction>/TokenAction.do</TokenAction> 
<ErrorPage>/error.html</ErrorPage> 
</Token> 
<Token> 
<TokenForm>/index1.jsp</TokenForm> 
<TokenAction>/TokenAction1.do</TokenAction> 
<ErrorPage>/error1.jsp</ErrorPage> 
</Token> 
<Token> 
<TokenForm>/index2.jsp</TokenForm> 
<TokenAction>/TokenAction2.do</TokenAction> 
<ErrorPage>/error2.jsp</ErrorPage> 
</Token> 
<Token> 
<TokenForm>/index3.jsp</TokenForm> 
<TokenAction>/TokenAction3.do</TokenAction> 
<ErrorPage>/error3.jsp</ErrorPage> 
</Token> 
</TokenList> 

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

分享到:
评论

相关推荐

    struts-config.xml struts标准配置文件 struts-config

    struts-config.xml struts标准配置文件 struts-config

    SSH三大框架整合 struts2(使用xml配置)+hibernate(使用xml配置)+spring(使用xml配置)

    通过定义Action类和对应的配置文件struts.xml,我们可以设置URL映射,指定请求如何转发到特定的方法。在XML配置中,我们可以定义action、result、param等元素,以声明式的方式管理应用程序的行为。 接着,Hibernate...

    Struts2解决表单重复提交

    对于第二种原因,即提交表单后刷新浏览器页面导致的重复提交,Struts2框架允许开发者通过配置结果视图的跳转方式来解决。默认情况下,Struts2使用的是dispatcher类型的forward跳转。为了避免刷新页面导致的重复提交...

    Struts2防止重复提交解决方案

    在Web开发中,尤其是使用Struts2框架时,防止重复提交是一个重要的问题,因为它可能导致数据的不一致性或者服务器资源的浪费。Struts2提供了一种通过拦截器来解决这个问题的方法,即`token`拦截器。本文将深入探讨...

    Struts框架中struts-config.xml文件配置小结

    ### Struts框架中struts-config.xml文件配置详解 #### 一、引言 在Java Web开发领域,Struts是一个非常重要的MVC(Model-View-Controller)框架,它极大地简化了Web应用程序的开发过程。而在Struts框架中,`struts...

    Struts-config.xml配置详解

    通过配置数据源,开发者可以使得数据访问更加灵活和易于管理。 2. 元素:form-beans元素用于配置表单验证相关的JavaBean。这个JavaBean通常对应于一个HTML表单,负责封装表单提交的数据。form-bean可以定义多个属性...

    struts.xml配置文件详解

    通过对`struts.xml`配置文件的详细解析,我们可以看到Struts 2框架的强大之处在于其高度可配置性。开发者可以通过简单的XML配置即可实现复杂的功能需求。了解并掌握这些配置项对于高效开发基于Struts 2的应用程序至...

    Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex

    Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex

    Struts2文件上传下载和表单重复提交问题

    综上所述,Struts2文件上传下载和表单重复提交涉及多个技术点,包括Struts2的配置、文件操作、HTTP响应头设置、安全性和异常处理。理解并熟练掌握这些知识点,对于构建健壮的Web应用程序至关重要。

    struts2 防止表单重复提交的例子

    5. **Struts2配置**:在Struts2的配置文件(struts.xml)中,需要添加Token拦截器到Action配置中。例如: ``` ``` 这样,每次请求都会经过Token拦截器的检查。 6. **异常处理**:Struts2提供了`...

    Struts struts-config.xml配置

    通过对`struts-config.xml`配置文件的详细解析,我们可以了解到如何通过不同的元素和属性来配置数据源、表单Bean以及全局异常处理等内容。这对于理解和使用Struts框架来说至关重要。希望本文能帮助读者更好地掌握...

    struts核心jar包及xml配置文件

    本压缩包包含了Struts2的核心库jar文件以及相关的XML配置文件,这些都是开发Struts2应用的基础组件。 **1. Struts2核心jar包** Struts2的核心jar包是实现框架功能的关键,主要包括以下几个部分: - **struts2-core...

    spring在web.xml中和在struts中的不同配置..pdf

    在本文中,我们将探讨Spring在`web.xml`中的配置与在Struts中的配置差异,以及这两种配置方式背后的基本原理。 首先,Spring的核心是ApplicationContext,它是一个管理Bean的容器,可以看作是应用程序的上下文环境...

    struts.xml(struts2配置)

    通过理解和灵活运用`struts.xml`配置,开发者能够构建出高效、可维护的Struts2应用。同时,配合使用Struts提供的插件和标签库,可以进一步提升开发效率。对于初学者,熟练掌握`struts.xml`的配置是学习Struts2的关键...

    struts2-spring4-hibernate4_xml配置的框架

    Struts2-Spring4-Hibernate4 XML配置的框架是一个经典的Java Web开发架构,它整合了三个主流的开源框架:Struts2、Spring4和Hibernate4。这个框架的配置主要通过XML文件来完成,同时也可以结合注解的方式进行更加...

    struts2的web.xml配置文件

    以前和struts2一起使用的配置文件,struts2的核心控制器

    Struts2中Struts.xml配置文件详解

    "Struts2 中 Struts.xml 配置文件详解" Struts2 中的 Struts.xml 配置文件是 Struts2 框架的核心配置文件,用于定义应用程序的行为和结构。在 Struts.xml 文件中,我们可以定义 package、action、interceptor、...

    struts2 Https 配置

    这可以通过在`struts.xml`配置文件中使用`&lt;constant&gt;`标签设置`struts.action.excludePattern`属性来实现。 ```xml &lt;constant name="struts.action.excludePattern" value="^http://.*"/&gt; ``` 3. **过滤器配置*...

    struts.xml和struts.properties配置详解

    总结,`struts.xml`和`struts.properties`是Struts2框架中至关重要的配置文件,通过它们可以灵活地控制应用的行为和设定。理解并熟练运用这两个文件,对于开发高质量的Struts2应用至关重要。在实际项目中,开发者应...

Global site tag (gtag.js) - Google Analytics