在搭建struts2项目时如果在web.xml中不指定struts.xml文件的路径,struts2会默认到/WEB-INF/classes中寻找加载其配置文件的,但我就是想把struts的配置文件放到我指定的位置下,这时该如何处理呢?我做了以下实验:

先看一下项目的文件结构:

我把struts的配置文件放到了/WEB-INF/deploy/pms/app-config/struts-config/下,并且在web.xml中的配置如下:

 <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>
struts-default.xml,struts-plugin.xml,/WEB-INF/deploy/pms/app-config/struts-config/struts.xml
</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

满怀信心的部署项目,并潇洒的启动tomcat,擦,不想看到的问题还是来了,打印信息如下:

为什么不能加载配置文件呢(保证配置文件是无误的),难道不能解析这个路径,那把配置文件放到src的指定文件夹下试试(因为它不是默认从src发布的文件夹下找嘛),

并且修改了web.xml

 <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>
struts-default.xml,struts-plugin.xml,config/struts.xml
</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

再次部署启动,居然没错了。郁闷。。。,难道我非得把配置文件放到src下吗,有点不甘心,看看你struts2的源码怎么读取文件的吧,从tomcat的打印信息中可以看到,加载配置文件的类是XmlConfigurationProvider

16:10:36,403  INFO ContextLoader:301 - Root WebApplicationContext: initialization completed in 2546 ms
16:10:36,622  INFO XmlConfigurationProvider:42 - Parsing configuration file [struts-default.xml]
16:10:36,763  INFO XmlConfigurationProvider:42 - Parsing configuration file [struts-plugin.xml]
16:10:36,809  INFO XmlConfigurationProvider:42 - Parsing configuration file [config/struts.xml]
16:10:37,059  INFO StrutsSpringObjectFactory:42 - Initializing Struts-Spring integration...

那就在struts2源码中直接找这个类,在这个类中搜了一下打印的日志信息“Unable to locate configuration files of the name”,找到这个信息是在XmlConfigurationProvider类的private List<Document> loadConfigurationFiles(String fileName, Element includeElement)方法中打印的,方法实现如下:

  private List<Document> loadConfigurationFiles(String fileName, Element includeElement) {
List<Document> docs = new ArrayList<Document>();
List<Document> finalDocs = new ArrayList<Document>();
if (!includedFileNames.contains(fileName)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Loading action configurations from: " + fileName);
} includedFileNames.add(fileName); Iterator<URL> urls = null;
InputStream is = null; IOException ioException = null;
try {
urls = getConfigurationUrls(fileName);
} catch (IOException ex) {
ioException = ex;
} if (urls == null || !urls.hasNext()) {
if (errorIfMissing) {
throw new ConfigurationException("Could not open files of the name " + fileName, ioException);
} else {
if (LOG.isInfoEnabled()) {
LOG.info("Unable to locate configuration files of the name "
+ fileName + ", skipping");
}
return docs;
}
} URL url = null;
while (urls.hasNext()) {
try {
url = urls.next();
is = fileManager.loadFile(url); InputSource in = new InputSource(is); in.setSystemId(url.toString()); docs.add(DomHelper.parse(in, dtdMappings));
} catch (XWorkException e) {
if (includeElement != null) {
throw new ConfigurationException("Unable to load " + url, e, includeElement);
} else {
throw new ConfigurationException("Unable to load " + url, e);
}
} catch (Exception e) {
throw new ConfigurationException("Caught exception while loading file " + fileName, e, includeElement);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
LOG.error("Unable to close input stream", e);
}
}
}
} //sort the documents, according to the "order" attribute
Collections.sort(docs, new Comparator<Document>() {
public int compare(Document doc1, Document doc2) {
return XmlHelper.getLoadOrder(doc1).compareTo(XmlHelper.getLoadOrder(doc2));
}
}); for (Document doc : docs) {
Element rootElement = doc.getDocumentElement();
NodeList children = rootElement.getChildNodes();
int childSize = children.getLength(); for (int i = 0; i < childSize; i++) {
Node childNode = children.item(i); if (childNode instanceof Element) {
Element child = (Element) childNode; final String nodeName = child.getNodeName(); if ("include".equals(nodeName)) {
String includeFileName = child.getAttribute("file");
if (includeFileName.indexOf('*') != -1) {
// handleWildCardIncludes(includeFileName, docs, child);
ClassPathFinder wildcardFinder = new ClassPathFinder();
wildcardFinder.setPattern(includeFileName);
Vector<String> wildcardMatches = wildcardFinder.findMatches();
for (String match : wildcardMatches) {
finalDocs.addAll(loadConfigurationFiles(match, child));
}
} else {
finalDocs.addAll(loadConfigurationFiles(includeFileName, child));
}
}
}
}
finalDocs.add(doc);
loadedFileUrls.add(url.toString());
} if (LOG.isDebugEnabled()) {
LOG.debug("Loaded action configuration from: " + fileName);
}
}
return finalDocs;
}

在方法的16行,该方法又调用了getConfigurationUrls(filename)方法:

  protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException {
return ClassLoaderUtil.getResources(fileName, XmlConfigurationProvider.class, false);
}

水还真是深,在getConfigurationUrls(filename)方法中又调用了其他类的方法,ClassLoaderUtil.getResources(fileName, XmlConfigurationProvider.class, false)方法如下:

  public static Iterator<URL> getResources(String resourceName, Class callingClass, boolean aggregate) throws IOException {

          AggregateIterator<URL> iterator = new AggregateIterator<URL>();

          iterator.addEnumeration(Thread.currentThread().getContextClassLoader().getResources(resourceName));

          if (!iterator.hasNext() || aggregate) {
iterator.addEnumeration(ClassLoaderUtil.class.getClassLoader().getResources(resourceName));
} if (!iterator.hasNext() || aggregate) {
ClassLoader cl = callingClass.getClassLoader(); if (cl != null) {
iterator.addEnumeration(cl.getResources(resourceName));
}
} if (!iterator.hasNext() && (resourceName != null) && ((resourceName.length() == 0) || (resourceName.charAt(0) != '/'))) {
return getResources('/' + resourceName, callingClass, aggregate);
} return iterator;
}

也该到尽头了吧!!从代码中可以看出,struts加载的配置文件都是从类加载器加载.class文件的路径中去寻找的,把配置文件放到WEB-INF下,它当然加载不到了,除非你写成http://xxx/工程名+配置文件路径,否则只能把配置文件写到src下了,这点struts2设计的还真是让人有点郁闷!

struts2中struts.xml 放置路径的问题的更多相关文章

  1. struts2中struts.xml配置文件详解【未整理】

    1.    深入Struts2的配置文件 本部分主要介绍struts.xml的常用配置. 1.1.    包配置: Struts2框架中核心组件就是Action.拦截器等,Struts2框架使用包来管 ...

  2. struts2中struts.xml配置文件详解

    struts.xml的常用配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts ...

  3. struts2中struts.xml和web.xml文件解析及工作原理

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp ...

  4. Struts2中.properties文件放置路径(classpath)

    一.web应用的classpath简介   classpath路径,即WEB-INF下面的classes目录,所有src目录下面的java.xml.properties等文件编译后都会在此. Stru ...

  5. Struts2中Struts.xml的作用

    struts.xml 为Struts 2的核心配置文件.struts.xml文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等.struts.xml中主要配置Stru ...

  6. Struts2 中Struts.xml结果页面配置

    结果页面的配置: 红色的比较常用 

  7. struts2中改变struts.xml默认路径

    struts2.X配置文件默认存放路径在/WEB-INF/classes目录下,即将struts.xml放在src的目录下. 但是为了方便管理,开发人员把struts.xml放到其他位置,处理方法如下 ...

  8. Struts2笔记——struts.xml配置详解

    访问HelloWorld应用的路径的设置 * 在struts1中,通过<action path=“/primer/helloWorldAction.action”>节点的path属性指定访 ...

  9. struts2——配置struts.xml文件

    在struts2框架中struts.xml是应当放到src的根目录,程序编译后会将struts.xml放到WEB-INF/classes目录下. Struts2在web.xml中的一般配置如下: &l ...

随机推荐

  1. TSQL语句和CRUD(20161016)

    上午 TSQL语句 1.创建数据库 create database test2; 2.删除数据库 drop database test2; 3.创建表 create table ceshi ( ids ...

  2. Burpsuite暴力破解

    神器:burpsuite 闲话不多说,直接开搞 1.打开文件BurpLoader.jar,进入Proxy--Options,启用代理 2.打开浏览器(IE),进入Internet选项-连接-局域网设置 ...

  3. java自加和自减

    public class Add { public static void main(String[] args) { int i = 0; i=i++ + ++i; int j = 0; j= ++ ...

  4. Linux学习之Vim使用

    一 为何要学Vim 所有的Unix Like系统都有自带vi编辑器 一些软件的编辑接口会自动调起vi 作为vi的升级版,vim具有程序编辑功能,而且具有代码颜色高亮显示.辨别代码的正确性等功能 以上优 ...

  5. 《Django By Example》第十章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译本章过程中几次想放弃,但是既然 ...

  6. CSS.05 -- 规避脱标 定位的盒子居中、CSS标签规范、溢出隐藏、内容移除(网页优化)、CSS精灵图

    规避脱标   定位的盒子居中显示 Margin:0 auto : 只能让标准流的盒子居中对齐 当A是B的父系,B可以使用 margin-left:auto: 来获得相当于定位right:0:的效果 M ...

  7. Git 入门和常用命令详解

    git 使用使用教程   git 使用简易指南  常用 Git 命令清单 下载   https://git-scm.com/downloads 工作流 本地仓库由三部分组成. 工作区:保存实际的文件( ...

  8. .net做的exe和electron做的exe之间的通信问题

    目前工作遇到个问题: .net做的exe和electron做的exe,之间进行数据通信 目前找到两个相对方便的方法: 1.命名管道 ①.net命名管道资料: 进程间通信 - 命名管道实现 ②elect ...

  9. Linux命令速查大全

    常用基本命令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir 创建目录 -p 创建目录,若无父目录,则创建p(par ...

  10. (转)Java ConcurrentModificationException异常原因和解决方法

    转载自:http://www.cnblogs.com/dolphin0520/p/3933551.html 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会 ...