JSF is unable to find resources in sub-folders

佐手、 提交于 2019-12-04 06:10:20

问题


I have a Javaee7, JSF2 web app running in Glassfish 4.0 using maven.

I have all of my resources in my /src/main/webapp/resources folder, but because I am using a framework, they are sometime nested in multiple subfolders, (i.e. resources/theme/plugin/bootstrap/script.js).

The CSS, JS and image files that are stored one directory below the resources folder (i.e. resources/theme/custom.css) would load fine with this code:

<h:outputScript library="theme" name="custom.js" />  

But if I try to load a resource that's located in sub-folders, it doesn't work:

<h:outputScript library="theme" name="plugin/bootstrap/script.js" /> 

I've also tried this:

<h:outputScript name="theme/plugin/bootstrap/script.js" /> 

and

<h:outputScript name="plugin/bootstrap/script.js" /> 

But everything returns "Unable to load resource".

Here is the start of my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
        <param-value>/resources</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
        <param-value>true</param-value>
    </context-param>
    <!-- sets the default time zone for the web app -->
    <context-param>
        <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
        <param-value>true</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

And here is the pom.xml if that helps

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.WebStore</groupId>
<artifactId>MyApp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>MyApp</name>

<properties>
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
         <groupId>javax.mail</groupId>
         <artifactId>mail</artifactId>
         <version>1.4.3</version>
    </dependency>
    <dependency>
        <groupId>net.coobird</groupId>
        <artifactId>thumbnailator</artifactId>
        <version>[0.4, 0.5)</version>
      </dependency>
    <dependency>
        <groupId>org.omnifaces</groupId>
        <artifactId>omnifaces</artifactId>
        <version>1.7</version>
    </dependency>
    <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
    </dependency>
    <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>16.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>
    <!--<dependency>
        <groupId>org.glassfish.main.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>4.0</version>
    </dependency>-->
    <dependency>
        <groupId>org.apache.derby</groupId>
        <artifactId>derby</artifactId>
        <version>10.10.1.1</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
    <dependency>
        <groupId>com.paypal.sdk</groupId>
        <artifactId>rest-api-sdk</artifactId>
        <version>0.5.2</version>
    </dependency>     
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <compilerArguments>
                    <endorseddirs>${endorsed.dir}</endorseddirs>
                </compilerArguments>
            </configuration>
        </plugin>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${endorsed.dir}</outputDirectory>
                        <silent>true</silent>
                        <artifactItems>
                            <artifactItem>
                                <groupId>javax</groupId>
                                <artifactId>javaee-endorsed-api</artifactId>
                                <version>7.0</version>
                                <type>jar</type>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

</project>

I checked to see if there are security constraints that may prevent the access to the resources, but all of them pertain to a certain folder of xhtml files, so I doubt that is the issue. For example, most of my security constraints are /admin/* or /user/* etc.

Any help would be appreciated! thanks!


回答1:


You'll either need to conform to JSF's resource library naming structure or abandon the nested directory structure you have altogether


JSF's somewhat complicated resource library naming convention is messing with you. Consider the following template as what constitutes a valid resource component path, per the JSF specification:

resources/<resourceIdentifier>

Where <resourceIdentifier> is bound by the following structure:

[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]

Here are the rules:

  1. If libraryVersion is present, it must be preceded by libraryName

  2. If libraryVersion is present, any leaf files under libraryName must be ignored.

  3. If resourceVersion is present, it must be preceded by resourceName

  4. There must be a / between adjacent segments in a

  5. If libraryVersion or resourceVersion are present, both must be a _ separated list of integers, neither starting nor ending with _

  6. If resourceVersion is present, it must be a version number in the same format as libraryVersion. An optional “file extension” may be used with the resourceVersion. If “file extension” is used, a “.” character, followed by a “file extension” must be appended to the version number.

As an example, resources/basic/2_3/script.js/1_3_4.js fulfils the requirements for a valid resource path

According to the rules above:

  • <resources>/theme/custom.css is fine and evaluates properly: [libraryName]/resourceName

  • <resources>/theme/plugin/bootstrap/script.js will fail because it's evaluated as: [libraryName/][libraryVersion/]resourceName[/resourceVersion]. According to the rules, several bits of that path fail the criteria for successful evaluation of the resource path




回答2:


I just had a similar problem, because I wanted to keep jquery scripts in a separate folder.
I got it working by just adding the sub-folder to the library name: <h:outputScript library="script/jquery" name="jquery.js"/> but I don't know how reliable this is.



来源:https://stackoverflow.com/questions/24472095/jsf-is-unable-to-find-resources-in-sub-folders

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!