﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-SE7EN-Dev</title><link>http://www.blogjava.net/SE7EN/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 06:00:19 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 06:00:19 GMT</pubDate><ttl>60</ttl><item><title>通过xml配置搞定Struts重复提交问题(转)</title><link>http://www.blogjava.net/SE7EN/archive/2008/08/14/222083.html</link><dc:creator>SE7EN</dc:creator><author>SE7EN</author><pubDate>Thu, 14 Aug 2008 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/SE7EN/archive/2008/08/14/222083.html</guid><wfw:comment>http://www.blogjava.net/SE7EN/comments/222083.html</wfw:comment><comments>http://www.blogjava.net/SE7EN/archive/2008/08/14/222083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SE7EN/comments/commentRss/222083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SE7EN/services/trackbacks/222083.html</trackback:ping><description><![CDATA[在webWork中有Token标签，可以直接搞定重复提交的问题，但在Struts2.0以下的版本，传统的做法只有通过提供的Token编程来搞定，代码虽然不多但是，这样的细节涉及了两个Action，对于页面的跳转控制来说是一个额外的负担，必须处处小心，本文阐述了如何通过Filter通过配置来避免struts的Form重复提交问题。 <br />
<strong>核心代码如下：</strong> <br />
package com.yapulan.util.filter; <br />
<br />
import java.io.IOException; <br />
import java.util.HashMap; <br />
import java.util.Iterator; <br />
import java.util.List; <br />
<br />
import javax.servlet.Filter; <br />
import javax.servlet.RequestDispatcher; <br />
import javax.servlet.ServletException; <br />
import javax.servlet.FilterConfig; <br />
import javax.servlet.http.HttpServletRequest; <br />
import javax.servlet.http.HttpServletResponse; <br />
import javax.servlet.FilterChain; <br />
import javax.servlet.ServletRequest; <br />
import javax.servlet.ServletResponse; <br />
<br />
import org.apache.log4j.Logger; <br />
import org.apache.struts.action.Action; <br />
import org.apache.struts.action.ActionForm; <br />
import org.apache.struts.action.ActionForward; <br />
import org.apache.struts.action.ActionMapping; <br />
import org.dom4j.Document; <br />
import org.dom4j.Element; <br />
import org.dom4j.io.SAXReader; <br />
<br />
/** <br />
* 重复提交令牌自动加载器 功能：读取过滤器中设置的信息，读入令牌设置组 <br />
*/ <br />
<br />
public class TokenFilter implements Filter { <br />
<br />
private String TokenConfig = "TokenConfig.xml"; <br />
private HashMap TokenMap = null; <br />
private HashMap ErrorMap = null; <br />
protected FilterConfig filterConfig; <br />
static Logger logger = Logger.getLogger(TokenFilter.class.getName()); <br />
<br />
public void init(FilterConfig config) throws ServletException { <br />
this.filterConfig = config; <br />
this.TokenConfig = config.getInitParameter("tokenfile"); <br />
logger.debug("Tokenlist init OK!"); <br />
} <br />
<br />
/** <br />
* 初始化系统的xml文件,读入令牌列表 <br />
*/ <br />
@SuppressWarnings({ "unchecked", "deprecation" }) <br />
public void initConfig(ServletRequest srequest) { <br />
<br />
HttpServletRequest httpRequest = (HttpServletRequest) srequest; <br />
try { <br />
<br />
TokenMap = new HashMap(); <br />
ErrorMap = new HashMap(); <br />
<br />
SAXReader reader = new SAXReader(); <br />
Document document = reader.read(httpRequest.getRealPath(this.TokenConfig)); <br />
List list1 = document.getRootElement().selectNodes("/TokenList/Token/TokenForm"); <br />
List list2 = document.getRootElement().selectNodes("/TokenList/Token/TokenAction"); <br />
List list3 = document.getRootElement().selectNodes("/TokenList/Token/ErrorPage"); <br />
<br />
Iterator iter1 = list1.iterator(); <br />
Iterator iter2 = list2.iterator(); <br />
Iterator iter3 = list3.iterator(); <br />
while (iter1.hasNext()&amp;&amp;iter2.hasNext()&amp;&amp;iter3.hasNext()) { <br />
Element element1 = (Element) iter1.next(); <br />
Element element2 = (Element) iter2.next(); <br />
Element element3 = (Element) iter3.next(); <br />
TokenMap.put(element1.getStringValue(), element2.getStringValue()); <br />
ErrorMap.put(element1.getStringValue(), element3.getStringValue()); <br />
} <br />
logger.debug("TokenFilter Read " <br />
+ httpRequest.getRealPath(this.TokenConfig) <br />
+ " is OK!"); <br />
} catch (Exception e) { <br />
logger.error("TokenFilter Read " <br />
+ httpRequest.getRealPath(this.TokenConfig) <br />
+ " is Error!"); <br />
} <br />
<br />
} <br />
<br />
public void doFilter(ServletRequest srequest, ServletResponse sresponse, <br />
FilterChain chain) throws IOException, ServletException { <br />
<br />
HttpServletRequest httpRequest = (HttpServletRequest) srequest; <br />
<br />
try { <br />
//取出实际的文件路径直接调用文件,如index.html,login.jsp等 <br />
String toURI = httpRequest.getRequestURI().replaceFirst(httpRequest.getContextPath(), ""); <br />
if (TokenMap==null) <br />
{ <br />
initConfig(httpRequest); <br />
} <br />
//检测为提交jsp页 <br />
if (TokenMap.get(toURI) != null) <br />
{ <br />
FromTokenAction token = new FromTokenAction(); <br />
token.execute(null, null, srequest, sresponse); <br />
httpRequest.getSession().setAttribute("PRE_TOKEN_FORM", toURI); <br />
logger.debug("TokenFilter save '"+toURI +"' at 'PRE_TOKEN_FORM' of Session!"); <br />
logger.debug("TokenFilter saveToken to '"+toURI +"' is OK!"); <br />
chain.doFilter(srequest, sresponse); <br />
return; <br />
} <br />
<br />
@SuppressWarnings("unused") <br />
String preURI =(String)httpRequest.getSession().getAttribute("PRE_TOKEN_FORM"); <br />
//检测到为Action接收提交页面 <br />
if (TokenMap.get(preURI).equals(toURI)) <br />
{ <br />
TOTokenAction token = new TOTokenAction(); <br />
token.execute(null, null, srequest, sresponse); <br />
chain.doFilter(srequest, sresponse); <br />
return; <br />
} <br />
<br />
<br />
} catch (Exception e) <br />
{ <br />
logger.error(e); <br />
} <br />
<br />
chain.doFilter(srequest, sresponse); <br />
} <br />
<br />
public void setFilterConfig(final FilterConfig filterConfig) { <br />
this.filterConfig = filterConfig; <br />
} <br />
<br />
public void destroy() { <br />
TokenMap.clear(); <br />
ErrorMap.clear(); <br />
this.filterConfig = null; <br />
} <br />
<br />
//检测到需要令牌增加一个令牌 <br />
public class FromTokenAction extends Action { <br />
public ActionForward execute(ActionMapping mapping, ActionForm form, <br />
HttpServletRequest request, HttpServletResponse response) { <br />
this.saveToken(request); <br />
return null; <br />
} <br />
} <br />
<br />
//到达Action前检测令牌 <br />
public class TOTokenAction extends Action { <br />
public ActionForward execute(ActionMapping mapping, ActionForm form, <br />
HttpServletRequest request, HttpServletResponse response) { <br />
@SuppressWarnings("unused") <br />
String preURI =(String)request.getSession().getAttribute("PRE_TOKEN_FORM"); <br />
//如果检测令牌错误执行错误页,正确将继续执行 <br />
if (!isTokenValid(request, true)) <br />
{ <br />
@SuppressWarnings("unused") <br />
String toURI = (String)ErrorMap.get(preURI); <br />
if (toURI!=null) <br />
{ <br />
RequestDispatcher disp = request.getRequestDispatcher(toURI); <br />
try { <br />
disp.forward(request, response); <br />
<br />
}catch(Exception e) <br />
{ <br />
logger.error(e); <br />
} <br />
} <br />
} <br />
return null; <br />
} <br />
} <br />
<br />
} <br />
<br />
<strong>Web.xml的配制</strong> <br />
<br />
&lt;!-- 令牌自动加载配制 --&gt; <br />
&lt;filter&gt; <br />
&lt;filter-name&gt;tokenFilter&lt;/filter-name&gt; <br />
&lt;filter-class&gt;com.yapulan.util.filter.TokenFilter&lt;/filter-class&gt; <br />
&lt;init-param&gt; <br />
&lt;param-name&gt;tokenfile&lt;/param-name&gt; <br />
&lt;param-value&gt;/WEB-INF/TokenConfig.xml&lt;/param-value&gt; <br />
&lt;/init-param&gt; <br />
&lt;/filter&gt; <br />
<br />
<span style="color: blue">注意:将代码包中web.xml做以下修改 <br />
&lt;filter-mapping&gt; <br />
&lt;filter-name&gt;tokenFilter&lt;/filter-name&gt; <br />
&lt;url-pattern/*&lt;/url-pattern&gt; <br />
&lt;/filter-mapping&gt;</span> <br />
<br />
<br />
<br />
<strong>设置好过滤器，只要配置列表即可避免所有的重复提交问题，不必在编程时再次考虑了</strong> <br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />
&lt;TokenList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TokenConfig.xsd"&gt; <br />
&lt;Token&gt; <br />
&lt;TokenForm&gt;/index.jsp&lt;/TokenForm&gt; <br />
&lt;TokenAction&gt;/TokenAction.do&lt;/TokenAction&gt; <br />
&lt;ErrorPage&gt;/error.html&lt;/ErrorPage&gt; <br />
&lt;/Token&gt; <br />
&lt;Token&gt; <br />
&lt;TokenForm&gt;/index1.jsp&lt;/TokenForm&gt; <br />
&lt;TokenAction&gt;/TokenAction1.do&lt;/TokenAction&gt; <br />
&lt;ErrorPage&gt;/error1.jsp&lt;/ErrorPage&gt; <br />
&lt;/Token&gt; <br />
&lt;Token&gt; <br />
&lt;TokenForm&gt;/index2.jsp&lt;/TokenForm&gt; <br />
&lt;TokenAction&gt;/TokenAction2.do&lt;/TokenAction&gt; <br />
&lt;ErrorPage&gt;/error2.jsp&lt;/ErrorPage&gt; <br />
&lt;/Token&gt; <br />
&lt;Token&gt; <br />
&lt;TokenForm&gt;/index3.jsp&lt;/TokenForm&gt; <br />
&lt;TokenAction&gt;/TokenAction3.do&lt;/TokenAction&gt; <br />
&lt;ErrorPage&gt;/error3.jsp&lt;/ErrorPage&gt; <br />
&lt;/Token&gt; <br />
&lt;/TokenList&gt; <br />
<br />
注意：本代码可以很好的验证非法的提交，对于管理非法的提交是一个不可多得的具有一定安全意义封装。 <br />
请热心的朋友分析有无其它没有考虑的细节问题，并且是否有可以进一部完善的地方，谢谢！
<img src ="http://www.blogjava.net/SE7EN/aggbug/222083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SE7EN/" target="_blank">SE7EN</a> 2008-08-14 18:35 <a href="http://www.blogjava.net/SE7EN/archive/2008/08/14/222083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat数据连接池</title><link>http://www.blogjava.net/SE7EN/archive/2008/08/14/222082.html</link><dc:creator>SE7EN</dc:creator><author>SE7EN</author><pubDate>Thu, 14 Aug 2008 10:27:00 GMT</pubDate><guid>http://www.blogjava.net/SE7EN/archive/2008/08/14/222082.html</guid><wfw:comment>http://www.blogjava.net/SE7EN/comments/222082.html</wfw:comment><comments>http://www.blogjava.net/SE7EN/archive/2008/08/14/222082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SE7EN/comments/commentRss/222082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SE7EN/services/trackbacks/222082.html</trackback:ping><description><![CDATA[在Java Web开发中都要与数据库打交道，为了不频繁地打开和关闭数据库，以减少数据库操作负荷,可使数据库在开发过程中保持打开状态，在这里我们采用配置数据源的方式(JNDI)，而不是传统地JDBC方式。下面就针对常规型的MySQL5.0.15和<span class="hilite3">Tomcat</span>6.0的数据源的基本配置进行简单的介绍： <br />
首先声明,如果数据源没有配置好的话，在开发过程中会抛出诸如下列异常等： <br />
1、<span class="hilite1">org</span>.<span class="hilite2">apache</span>.<span class="hilite3">tomcat</span>.<span class="hilite5">dbcp</span>.<span class="hilite5">dbcp</span>.<span class="hilite6">SQLNestedException</span>: Cannot create JDBC driver of class '' for connect URL 'null' <br />
2、Caused by: java.sql.SQLException: No suitable driver <br />
3、Name jdbc is not bound in this context <br />
现在开始讲下如何配置好数据源同时也是解决上述异常的办法： <br />
方案一： <br />
步骤一、在<span class="hilite3">Tomcat</span>6.0解压目录conf下找到context.xml,在其中的&lt;Context&gt;&lt;/Context&gt; 中加入如下代码(要根据自己的情况稍加修改)： &lt;Resource name="jdbc/myznt" auth="Container" type="javax.sql.DataSource" password="localhost" username="root" driverClassName="<span class="hilite1">org</span>.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/myznt" maxActive="100" maxIdle="30" maxWait="5000"/&gt; <br />
步骤二、在工程应用中/WEB-INF/下的web.xml中加入如下代码(要根据自己的情况稍加修改): <br />
&lt;resource-ref&gt; <br />
&lt;description&gt;MySQL DataSource&lt;/description&gt; <br />
&lt;res-ref-name&gt;jdbc/myznt&lt;/res-ref-name&gt; <br />
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt; <br />
&lt;res-auth&gt;Container&lt;/res-auth&gt; <br />
&lt;/resource-ref&gt; <br />
步骤三、把MySQL-Connector-java-3.0.12-bin.jar(可换更高版本)加到<span class="hilite3">Tomcat</span>安装目录中的lib目录下和工程中的lib目录下。 <br />
通过这三步，一个基本的数据源就配置成功了! <br />
方案二 <br />
步骤一、在<span class="hilite3">Tomcat</span>6.0解压目录conf下找到server.xml,在其中的&lt;GlobalNamingResources&gt;&lt;/GlobalNamingResources&gt;中加入如下代码(要根据自己的情况稍加修改)： <br />
&lt;Resource name="jdbc/myznt" auth="Container" type="javax.sql.DataSource" password="localhost" username="root" driverClassName="<span class="hilite1">org</span>.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/myznt" maxActive="100" maxIdle="30" maxWait="5000"/&gt; <br />
步骤二、在<span class="hilite3">Tomcat</span>6.0解压目录conf下找到context.xml,在其中的&lt;Context&gt;&lt;/Context&gt;中加入并修改成如下代码(要根据自己的情况稍加修改): <br />
&lt;Context path="/znt" debug="1" reloadable="true" docBase="E:\EclipseWorkPlace\MyZNT\WebRoot"&gt; <br />
&lt;ResourceLink global="jdbc/myznt" name="jdbc/myznt" type="javax.sql.Datasource"/&gt; <br />
................&lt;!--此间可能有系统其它自配的内容，可不管--&gt; <br />
&lt;/Context&gt; <br />
步骤三、在工程中/WEB-INF/下的web.xml中加入如下代码(要根据自己的情况稍加修改): <br />
&lt;resource-ref&gt; <br />
&lt;description&gt;MySQL DataSource&lt;/description&gt; <br />
&lt;res-ref-name&gt;jdbc/myznt&lt;/res-ref-name&gt; <br />
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt; <br />
&lt;res-auth&gt;Container&lt;/res-auth&gt; <br />
&lt;/resource-ref&gt; <br />
步骤四、把MySQL-Connector-java-3.0.12-bin.jar(可换更高版本)加到<span class="hilite3">Tomcat</span>安装目录中的lib目录下和工程中的lib目录下。 <br />
通过以上四步就好了! <br />
方案三(具有不稳定性,慎用) <br />
步骤一、在<span class="hilite3">Tomcat</span>6.0解压目录conf下找到server.xml,在其中的&lt;Host&gt;&lt;/Host&gt;中加入如下代码(要根据自己的情况稍加修改)： <br />
&lt;Context path="/znt" docBase="E:\EclipseWorkPlace\MyZNT\WebRoot" <br />
debug="5" reloadable="true" crossContext="true"&gt; <br />
<br />
&lt;Logger className="<span class="hilite1">org</span>.<span class="hilite2">apache</span>.catalina.logger.FileLogger" <br />
prefix="localhost_MysqlTest_log." suffix=".txt" <br />
timestamp="true"/&gt; <br />
&lt;Resource name="jdbc/myznt" auth="Container" type="javax.sql.DataSource" password="localhost" username="root" driverClassName="<span class="hilite1">org</span>.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/myznt" maxActive="100" maxIdle="30" maxWait="5000"/&gt; <br />
&lt;/Context&gt; <br />
步骤二、在工程中/WEB-INF/下的web.xml中加入如下代码(要根据自己的情况稍加修改): <br />
&lt;resource-ref&gt; <br />
&lt;description&gt;MySQL DataSource&lt;/description&gt; <br />
&lt;res-ref-name&gt;jdbc/myznt&lt;/res-ref-name&gt; <br />
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt; <br />
&lt;res-auth&gt;Container&lt;/res-auth&gt; <br />
&lt;/resource-ref&gt; <br />
步骤三、把MySQL-Connector-java-3.0.12-bin.jar(可换更高版本)加到<span class="hilite3">Tomcat</span>安装目录中的lib目录下和工程中的lib目录下。 <br />
通过以上三步，大部分时候还是起作用的，但有时会出现异常，因此不建议使用。 <br />
以上几种方案在实践中经受了测试，方案一和二比较稳定，方案三最好别用，同时只是进行了大致地归纳，其中的哪些地方没有必要或哪里欠妥还没有去测试，望读者进行批评指正。
<img src ="http://www.blogjava.net/SE7EN/aggbug/222082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SE7EN/" target="_blank">SE7EN</a> 2008-08-14 18:27 <a href="http://www.blogjava.net/SE7EN/archive/2008/08/14/222082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>