http://www2.uuzone.com/blog/seril/73267.htm
使用Timmer使Struts修改struts-config.xml文件不用重新启动服务器 1
在做struts应用的时候,经常学要修改struts-config.xml文件,在每次修改完之后只有重新启动服务器才能让修改生效。因此做了一个Listener,在应用启动的时候开始,每隔一段时间就去检查一下struts-config.xml文件的最后修改时间,如果修改时间变化了,就重新读取struts-config.xml,将对应的配置放到ServletContext中去。
一.LoadResourceListener
import java.util.Timer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import kick.utils.Constants;
public class LoadResourceListener implements ServletContextListener {
/* (non-Javadoc)
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent event) {
Timer loadResource = new Timer();
//获取ServletContext
ServletContext servletContext = event.getServletContext();
//创建一个LoadResourceTimerTask 的实例
LoadResourceTimerTask loadResourceTimerTask = new LoadResourceTimerTask(servletContext);
//将刚创建的TimerTask的实例的运行计划订为:马上开始,每隔20×1000ms运行一次
loadResource.schedule(loadResourceTimerTask,0,Constants.DELAY_UPDATE_TIME);
}
/* (non-Javadoc)
* @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
}
}
二.配置LoadResourceListener
在filter的配置下面添加上如下的配置
<listener>
<listener-class>kick.load.resource.LoadResourceListener</listener-class>
</listener>
三.LoadResourceTimerTask类
/*
* Created on 2005-9-6
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package kick.load.resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.TimerTask;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.sql.DataSource;
import kick.utils.Constants;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.FastHashMap;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.config.ConfigRuleSet;
import org.apache.struts.config.DataSourceConfig;
import org.apache.struts.config.FormBeanConfig;
import org.apache.struts.config.MessageResourcesConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ModuleConfigFactory;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ServletContextWriter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class LoadResourceTimerTask extends TimerTask {
private ServletContext context = null;
/**
* <p>
* The resources object for our internal resources.
* </p>
*/
protected MessageResources internal = null;
/**
* <p>
* The Digester used to produce ModuleConfig objects from a Struts
* configuration file.
* </p>
*
* @since Struts 1.1
*/
protected Digester configDigester = null;
/**
* <p>
* The Java base name of our internal resources.
* </p>
*
* @since Struts 1.1
*/
protected String internalName = "org.apache.struts.action.ActionResources";
/**
* <p>
* Commons Logging instance.
* </p>
*
* @since Struts 1.1
*/
protected static Log log = LogFactory.getLog(LoadResourceTimerTask.class);
private List initParams = null;
/**
* <p>
* The set of public identifiers, and corresponding resource names, for the
* versions of the configuration file DTDs that we know about. There
* <strong>MUST </strong> be an even number of Strings in this list!
* </p>
*/
protected String registrations[] = { "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
"/org/apache/struts/resources/struts-config_1_0.dtd",
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
"/org/apache/struts/resources/struts-config_1_1.dtd",
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
"/org/apache/struts/resources/struts-config_1_2.dtd",
"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", "/org/apache/struts/resources/web-app_2_2.dtd",
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", "/org/apache/struts/resources/web-app_2_3.dtd" };
/**
* <p>
* The JDBC data sources that has been configured for this module, if any,
* keyed by the servlet context attribute under which they are stored.
* </p>
*/
protected FastHashMap dataSources = new FastHashMap();
/**
* <p>
* Comma-separated list of context-relative path(s) to our configuration
* resource(s) for the default module.
* </p>
*/
protected String config = "/WEB-INF/struts-config.xml";
private List resourcesName = new ArrayList();
private Set resourceFiles = new HashSet();
public LoadResourceTimerTask(ServletContext context) {
this.context = context;
try {
initInternal();
parseWeb();
parseConfigFile();
parseResource();
// parseConfigFile();
} catch (ServletException e) {
System.out.println(e.getMessage());
e.printStackTrace();
throw new RuntimeException(e);
}
}
/*
* (non-Javadoc)
*
* @see java.util.TimerTask#run()
*/
public void run() {
try {
reLoadConfigFile();
reLoadResource();
} catch (Exception e) {
}
}
/**
*
*/
private void parseConfigFile() {
InitParam initParam = null;
for (int i = 0; i < initParams.size(); i++) {
initParam = (InitParam) initParams.get(i);
String name = initParam.getName();
if (!name.startsWith("config")) {
continue;
}
String prefix = name.substring(6);
String paths = initParam.getValue();
// Process each specified resource path
while (paths.length() > 0) {
// digester.push(config);
String path = null;
int comma = paths.indexOf(',');
if (comma >= 0) {
path = paths.substring(0, comma).trim();
paths = paths.substring(comma + 1);
} else {
path = paths.trim();
paths = "";
}
if (path.length() < 1) {
break;
}
File file = new File(getServletContext().getRealPath(path));
StrutsConfig s = new StrutsConfig();
Digester d = new Digester();
d.push(s);
d.setNamespaceAware(false);
d.setValidating(false);
for (int j = 0; j < registrations.length; j += 2) {
URL url = this.getClass().getResource(registrations[j + 1]);
if (url != null) {
d.register(registrations[j], url.toString());
}
}
d.addObjectCreate("struts-config/message-resources", Resource.class);
d.addSetProperties("struts-config/message-resources", "parameter", "parameter");
d.addSetNext("struts-config/message-resources", "addResource");
// d.addCallMethod("web-struts-config/message-resources",
// "setParameter", 0);
try {
d.parse(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// String resourcePath =
// ((Resource)s.getResources()).toFilePaht();
List rs = s.getResources();
for (int ii = 0; ii < rs.size(); ii++) {
resourcesName.add(((Resource) rs.get(ii)).toFilePaht());
}
}
}
}
public void parseResource() {
int index = 0;
String dirName = "";
String resource = "";
String subFileName = "";
for (int i = 0; i < resourcesName.size(); i++) {
resource = (String) resourcesName.get(i);
index = resource.lastIndexOf("/");
dirName = resource.substring(0, index);
subFileName = resource.substring(index + 1, resource.length());
File file = new File(getServletContext().getRealPath("/WEB-INF/classes/" + dirName));
if (file.isDirectory()) {
String[] fileNames = file.list();
if (fileNames != null) {
for (int j = 0; j < fileNames.length; j++) {
if (fileNames[j] != null) {
if (fileNames[j].trim().startsWith(subFileName.trim())) {
resourceFiles.add(dirName + "/" + fileNames[j]);
// System.out.println("The file Name : '" +
// subFileName + "'");
// System.out.println("Add file name : '" +
// fileNames[j] + "'");
}
}
}
}
}
}
}
private void reLoadConfigFile() {
try {
InitParam initParam = null;
for (int i = 0; i < initParams.size(); i++) {
initParam = (InitParam) initParams.get(i);
String name = initParam.getName();
if (!name.startsWith("config")) {
continue;
}
String prefix = name.substring(6);
String paths = initParam.getValue();
// Process each specified resource path
while (paths.length() > 0) {
// digester.push(config);
String path = null;
int comma = paths.indexOf(',');
if (comma >= 0) {
path = paths.substring(0, comma).trim();
paths = paths.substring(comma + 1);
} else {
path = paths.trim();
paths = "";
}
if (path.length() < 1) {
break;
}
File file = new File(getServletContext().getRealPath(path));
if ((System.currentTimeMillis() - file.lastModified()) < Constants.DELAY_UPDATE_TIME) {
log.debug("The struts-config.xml is changed,will be reload into context.");
log.debug("The file name is : '" + path + "'");
log.debug("Refash the resource file config list!");
parseConfigFile();
log.debug("Refash the resource file list!");
parseResource();
ModuleConfig moduleConfig = initModuleConfig(prefix, path);
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
moduleConfig.freeze();
log.debug("Reload the config file success!");
}
this.initModulePrefixes(this.getServletContext());
}
}
} catch (Exception e) {
}
}
private void reLoadConfig(String prefix, String path) {
try {
ModuleConfig moduleConfig = initModuleConfig(prefix, path);
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
moduleConfig.freeze();
} catch (Exception e) {
}
}
private void reLoadResource() {
Iterator it = resourceFiles.iterator();
String fileName = "";
while (it.hasNext()) {
fileName = (String) it.next();
File file = new File(this.getServletContext().getRealPath("/WEB-INF/classes/" + fileName));
if ((System.currentTimeMillis() - file.lastModified()) < Constants.DELAY_UPDATE_TIME) {
log.debug("Update the '" + file.getName() + "' property file!");
updateConfigFile();
}
}
}
/**
*
*/
private void updateConfigFile() {
InitParam initParam = null;
for (int i = 0; i < initParams.size(); i++) {
initParam = (InitParam) initParams.get(i);
String name = initParam.getName();
if (!name.startsWith("config")) {
continue;
}
String prefix = name.substring(6);
String paths = initParam.getValue();
// Process each specified resource path
while (paths.length() > 0) {
// digester.push(config);
String path = null;
int comma = paths.indexOf(',');
if (comma >= 0) {
path = paths.substring(0, comma).trim();
paths = paths.substring(comma + 1);
} else {
path = paths.trim();
paths = "";
}
if (path.length() < 1) {
break;
}
File file = new File(getServletContext().getRealPath(path));
file.setLastModified(System.currentTimeMillis());
}
}
}