3

I've created a Struts2 project which is working fine when I place my struts.xml file inside src directory.

Below is my web.xml configuration.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"      
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
         id="WebApp_ID" version="3.0">    
    <display-name>struts2project</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
         org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

If I put my struts.xml inside WEB-INF directory instead, it is not getting loaded.

Please do not give answers as "it is irrelevant" or something else. I'm just asking whether (and how) we can change the default location of struts.xml or not.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
Sumit Kamboj
  • 846
  • 2
  • 10
  • 17

4 Answers4

4

To be completely clear, you don't even need struts.xml, the only needed configuration file is web.xml.

From Configuration Files

From a Struts developer point of view, the one required configuration file used by the framework is web.xml. From here, you have full control over how Struts configures both itself and your application. By default, Struts will load a set of internal configuration files to configure itself, then another set to configure your application, however it is possible to build an entire Struts application without writing a single configuration file other than web.xml.

[...]

File      Optional    Location (relative to webapp)          Purpose
-----------------------------------------------------------------------------------------
web.xml      no           /WEB-INF/                 Web deployment descriptor to include 
                                                    all necessary framework components
-----------------------------------------------------------------------------------------
struts.xml   yes          /WEB-INF/classes/         Main configuration, contains 
                                                    result/view types, action mappings,
                                                    interceptors, and so forth

To answer your question, however, it is possible to add configuration files other than the default ones by using the config initialization parameter in web.xml.

From web.xml

Key Initialization Parameters

config - a comma-delimited list of XML configuration files to load.

So it is enough to specify the new struts.xml in web.xml to achieve your goal:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
    <init-param>
        <param-name>config</param-name>
        <!-- Edit after @AleskandrM's comments/answer because 
             1) every possible configuration file must be specified,
                otherwise they will be hidden by this setting and 
             2) settings are relative to /WEB-INF/classes/, and hence
                the /WEB-INF/ must be replaced by ../ and
             3) the order is important as well. You cannot extend 
                struts-default package in your struts.xml if it isn't loaded yet. 
        -->

        <param-value>/WEB-INF/struts.xml</param-value>

        <param-value>struts-default.xml,struts-plugin.xml,../struts.xml</param-value>
    </init-param>
</filter>

That said, I generally avoid this kind of customizations: you will earn basically nothing, apart from potential drawbacks that you might be the only one in the world to get, due to having left the main road.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • I don't think `/WEB-INF/struts.xml` will work because location is relative to webapp `/WEB-INF/classes/ `. Also http://stackoverflow.com/q/13839153/1700321. – Aleksandr M Jun 03 '15 at 13:13
  • @AleksandrM Are you sure there is the need to specify every configuration file and not only the ones with a special position ? With my configuration I'd be "hiding" struts-default.xml and struts-plugin.xml ? It seems too overkill to me :| – Andrea Ligios Jun 03 '15 at 13:26
  • I am sure. -> https://github.com/apache/struts/blob/master/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java#L361. – Aleksandr M Jun 03 '15 at 13:29
  • A good way to trick a coworker in need of a plugin :P I'll edit the answer referencing your, after your is accepted – Andrea Ligios Jun 03 '15 at 13:31
  • 1
    ...And the order is important as well. You cannot extend `struts-default` package in your `struts.xml` if it isn't loaded. – Aleksandr M Jun 03 '15 at 14:10
  • 2
    Added it too. What a mess for moving a file that isn't even needed in a place that should not even allow it :S – Andrea Ligios Jun 03 '15 at 14:16
3

The correct configuration to put struts.xml directly into WEB-INF folder is:

<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,../struts.xml</param-value>
    </init-param>
</filter>

Read Andrea answer and this one to find out why.

Also the order in which you define xml files is important as well. E.g. You cannot extend struts-default package (from struts-default.xml) in your struts.xml if it isn't loaded yet.

Community
  • 1
  • 1
Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
0

struts.xml should only be in the classpath of the application . Its location is irrelevant.

Rajendra Gupta
  • 381
  • 1
  • 16
0

Struts 2 loads default configuration files (struts-default.xml, struts-plugin.xml, struts.xml) using StrutsPrepareAndExecuteFilter (org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter).

To understand about loading of these files by framework -

These filenames are defined as constant in Dispatcher.class (used in StrutsPrepareAndExecuteFilter) file of Struts framework.

DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";

init_TraditionalXmlConfigurations() method present in Dispatcher.class loads these xmls.

private void init_TraditionalXmlConfigurations() {
        String configPaths = initParams.get("config");
        if (configPaths == null) {
            configPaths = DEFAULT_CONFIGURATION_PATHS;
        }
        String[] files = configPaths.split("\\s*[,]\\s*");
        for (String file : files) {
            if (file.endsWith(".xml")) {
                configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
            } else {
                throw new IllegalArgumentException("Invalid configuration file name");
            }
        }
    }

To Override the default path setting for these xmls you can provide the paths of these XMLs while defining the StrutsPrepareAndExecuteFilter in web.xml as answered by other users here.

Manoj Kumawat
  • 869
  • 7
  • 12