• struts2中struts.xml 放置路径的问题


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

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

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

     1 <filter>
     2         <filter-name>struts2</filter-name>
     3         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
     4          <init-param>        
     5                <param-name>config</param-name>         
     6                <param-value>
     7                      struts-default.xml,struts-plugin.xml,/WEB-INF/deploy/pms/app-config/struts-config/struts.xml
     8                    </param-value>        
     9          </init-param> 
    10     </filter>
    11 
    12     <filter-mapping>
    13         <filter-name>struts2</filter-name>
    14         <url-pattern>/*</url-pattern>
    15     </filter-mapping>

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

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

    并且修改了web.xml

     1 <filter>
     2         <filter-name>struts2</filter-name>
     3         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
     4          <init-param>        
     5                <param-name>config</param-name>         
     6                <param-value>
     7                      struts-default.xml,struts-plugin.xml,config/struts.xml
     8                    </param-value>        
     9          </init-param> 
    10     </filter>
    11 
    12     <filter-mapping>
    13         <filter-name>struts2</filter-name>
    14         <url-pattern>/*</url-pattern>
    15     </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)方法中打印的,方法实现如下:

      1  private List<Document> loadConfigurationFiles(String fileName, Element includeElement) {
      2         List<Document> docs = new ArrayList<Document>();
      3         List<Document> finalDocs = new ArrayList<Document>();
      4         if (!includedFileNames.contains(fileName)) {
      5             if (LOG.isDebugEnabled()) {
      6                 LOG.debug("Loading action configurations from: " + fileName);
      7             }
      8 
      9             includedFileNames.add(fileName);
     10 
     11             Iterator<URL> urls = null;
     12             InputStream is = null;
     13 
     14             IOException ioException = null;
     15             try {
     16                 urls = getConfigurationUrls(fileName);
     17             } catch (IOException ex) {
     18                 ioException = ex;
     19             }
     20 
     21             if (urls == null || !urls.hasNext()) {
     22                 if (errorIfMissing) {
     23                     throw new ConfigurationException("Could not open files of the name " + fileName, ioException);
     24                 } else {
     25                     if (LOG.isInfoEnabled()) {
     26                     LOG.info("Unable to locate configuration files of the name "
     27                             + fileName + ", skipping");
     28                     }
     29                     return docs;
     30                 }
     31             }
     32 
     33             URL url = null;
     34             while (urls.hasNext()) {
     35                 try {
     36                     url = urls.next();
     37                     is = fileManager.loadFile(url);
     38 
     39                     InputSource in = new InputSource(is);
     40 
     41                     in.setSystemId(url.toString());
     42 
     43                     docs.add(DomHelper.parse(in, dtdMappings));
     44                 } catch (XWorkException e) {
     45                     if (includeElement != null) {
     46                         throw new ConfigurationException("Unable to load " + url, e, includeElement);
     47                     } else {
     48                         throw new ConfigurationException("Unable to load " + url, e);
     49                     }
     50                 } catch (Exception e) {
     51                     throw new ConfigurationException("Caught exception while loading file " + fileName, e, includeElement);
     52                 } finally {
     53                     if (is != null) {
     54                         try {
     55                             is.close();
     56                         } catch (IOException e) {
     57                             LOG.error("Unable to close input stream", e);
     58                         }
     59                     }
     60                 }
     61             }
     62 
     63             //sort the documents, according to the "order" attribute
     64             Collections.sort(docs, new Comparator<Document>() {
     65                 public int compare(Document doc1, Document doc2) {
     66                     return XmlHelper.getLoadOrder(doc1).compareTo(XmlHelper.getLoadOrder(doc2));
     67                 }
     68             });
     69 
     70             for (Document doc : docs) {
     71                 Element rootElement = doc.getDocumentElement();
     72                 NodeList children = rootElement.getChildNodes();
     73                 int childSize = children.getLength();
     74 
     75                 for (int i = 0; i < childSize; i++) {
     76                     Node childNode = children.item(i);
     77 
     78                     if (childNode instanceof Element) {
     79                         Element child = (Element) childNode;
     80 
     81                         final String nodeName = child.getNodeName();
     82 
     83                         if ("include".equals(nodeName)) {
     84                             String includeFileName = child.getAttribute("file");
     85                             if (includeFileName.indexOf('*') != -1) {
     86                                 // handleWildCardIncludes(includeFileName, docs, child);
     87                                 ClassPathFinder wildcardFinder = new ClassPathFinder();
     88                                 wildcardFinder.setPattern(includeFileName);
     89                                 Vector<String> wildcardMatches = wildcardFinder.findMatches();
     90                                 for (String match : wildcardMatches) {
     91                                     finalDocs.addAll(loadConfigurationFiles(match, child));
     92                                 }
     93                             } else {
     94                                 finalDocs.addAll(loadConfigurationFiles(includeFileName, child));
     95                             }
     96                         }
     97                     }
     98                 }
     99                 finalDocs.add(doc);
    100                 loadedFileUrls.add(url.toString());
    101             }
    102 
    103             if (LOG.isDebugEnabled()) {
    104                 LOG.debug("Loaded action configuration from: " + fileName);
    105             }
    106         }
    107         return finalDocs;
    108     }

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

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

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

     1  public static Iterator<URL> getResources(String resourceName, Class callingClass, boolean aggregate) throws IOException {
     2 
     3          AggregateIterator<URL> iterator = new AggregateIterator<URL>();
     4 
     5          iterator.addEnumeration(Thread.currentThread().getContextClassLoader().getResources(resourceName));
     6 
     7          if (!iterator.hasNext() || aggregate) {
     8              iterator.addEnumeration(ClassLoaderUtil.class.getClassLoader().getResources(resourceName));
     9          }
    10 
    11          if (!iterator.hasNext() || aggregate) {
    12              ClassLoader cl = callingClass.getClassLoader();
    13 
    14              if (cl != null) {
    15                  iterator.addEnumeration(cl.getResources(resourceName));
    16              }
    17          }
    18 
    19          if (!iterator.hasNext() && (resourceName != null) && ((resourceName.length() == 0) || (resourceName.charAt(0) != '/'))) { 
    20              return getResources('/' + resourceName, callingClass, aggregate);
    21          }
    22 
    23          return iterator;
    24      }

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

  • 相关阅读:
    看看时间,我的博客都有一年了。
    asp.net 读取数据库生成百度sitemap_baidu.xml和谷歌sitemap.xml
    克隆后自动改IP计算机名的批处理
    网奇iwms插件之“我浏览过的文章”
    Jetty7 Continuation 学习(一)
    PostgreSQL 和 MySQL 创建帐号,数据库,权限
    OpenLayers 学习笔记 (3) 使用 Google Maps 作底图
    Tomcat 和 Jetty 下 JNDI 配置 DBCP 连接池
    PostgreSQL 中 POLYGON 到 MULTIPOLYGON 的转换
    CentOS 5.4 安装 DNS
  • 原文地址:https://www.cnblogs.com/angryprogrammer/p/3228104.html
Copyright © 2020-2023  润新知