`
SE7EN
  • 浏览: 3190 次
  • 性别: 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>

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

相关推荐

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

    在本文中,我们将深入探讨如何通过XML配置来解决Struts中的重复提交问题。 首先,理解重复提交的原因。在Web应用中,用户点击提交按钮后,如果网络延迟或刷新页面,同一个请求可能被发送多次。Struts框架默认情况下...

    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...

    Struts-config.xml配置详解

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

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

    首先,要在`struts.xml`配置文件中启用文件上传支持,设置`struts.multipart.parser`为`jakarta`或`native2ascii`。然后,在Action类中创建一个`java.io.File`或者`org.apache.struts2.dispatcher.multipart....

    struts核心jar包及xml配置文件

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

    Struts struts-config.xml配置

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

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

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

    struts.xml常用配置解析

    Struts.xml配置文件是Struts2框架的核心配置文件,它定义了应用的行为和结构。本文主要解析了其中两个重要的配置元素:`&lt;include&gt;`标签和Action的别名。 首先,我们来看 `&lt;include&gt;` 标签的使用。当Struts2的应用中...

    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

    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文件来完成,同时也可以结合注解的方式进行更加...

    struts-config.xml配置文件详解

    在 Struts-config.xml 文件中,数据源配置是通过 `&lt;data-sources&gt;` 元素实现的,该元素可以包含多个 `&lt;data-source&gt;` 子元素,每个 `&lt;data-source&gt;` 元素可以配置一个数据源。数据源配置中可以设置 driverClass、url...

    struts2的web.xml配置文件

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

    struts.xml和struts.properties配置详解

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

    struts2 Https 配置

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

    struts.xml和applicationContext.xml、web.xml的配置

    在Java Web开发中,`struts.xml`, `applicationContext.xml` 和 `web.xml` 是三个至关重要的配置文件,它们各自负责不同的职责,并协同工作来构建一个完整的应用框架。以下是关于这三个配置文件的详细说明。 首先,...

    Struts2中struts_xml的Action配置详解

    总之,`struts_xml`中的Action配置是Struts2应用的基石,通过它可以灵活地定义请求与业务逻辑的映射关系,以及后续的页面跳转和拦截器链,从而构建出高效、可维护的Web应用。深入了解和熟练掌握这部分知识对于提升...

Global site tag (gtag.js) - Google Analytics