In this blog post, I want to explain the behavior and the reason for this problem, as well as how we solve this problem.
To load the resources there are multiple Resource Locators available (https://wro4j.readthedocs.io/en/stable/ResourceTypes/). Based on conventions and definition in wro.xml.
The default behavior is to use the ServletContextUriLocator which will look for the resources via the dispatcher. If the File(s) cannot be loaded it will be tried to load them from extern with the current request context.
This is a feature of Wro4j to also provide the possibility to load external resources. For this, the UrlUriLocater will be used. In this locator, it is checked if the URL is a wildcard. Unfortunately, the check is working with a flag “enableWildcards” which is initialized with false (https://github.com/wro4j/wro4j/blob/v1.9.0/wro4j-core/src/main/java/ro/isdc/wro/model/resource/locator/wildcard/WildcardUriLocatorSupport.java#L32)
enableWildcards && super.hasWildcard(uri);
The second problem is that the Super method “hasWildcard” is working with a pattern that also returns false if “HTTP” is part of the URL (https://github.com/wro4j/wro4j/blob/b09a44747011006578d3a916fa464a39f633e860/wro4j-core/src/main/java/ro/isdc/wro/model/resource/locator/wildcard/DefaultWildcardStreamLocator.java#L52).
/** * Character to distinguish wildcard inside the uri. If the file name contains '*' or '?' character, it is considered * a wildcard. * <p> * A string is considered to contain wildcard if it doesn't start with http(s) and contains at least one of the * following characters: [?*]. */ private static final String WILDCARD_REGEX = "^(?:(?!http))(.)*[\\*\\?]+(.)*";
Therefore following URI is used for retrieving the external Resource:
In Hybris the default Behavior for not found Pages is to display a custom 404 pages. This is necessary to display a pretty Page to the user.
The wro.xml config from Hybris OOTB looks like this:
The Wildcard line
In the wro.xml the following wildcard is defined:
If no files exist in the cms folder it will be tried to load them via external locator, which results in a URI like this:
Unfortunately, if a page is called that does not exist in hybris, the custom 404 Page is returned with code 200 (OK) instead of HTTP Status 404 (NOT FOUND). (see de.hybris.platform.yacceleratorstorefront.controllers.pages.DefaultPageController.java#get)
- Add the prefix “classpath” to the resources URLs
to indicate that this line should only be interpreted by the ClasspathUriLocator.
This solution is the quickest but not the longest one, as the problem could reoccur if resources cannot be found locally (maybe deleted as they are no longer necessary or were refactored).
<filter-mapping> <filter-name>resourceFilter</filter-name> <url-pattern>/_ui/*</url-pattern> <url-pattern>*.js</url-pattern> <url-pattern>*.css</url-pattern> </filter-mapping> .. <serverl-mapping> <servlet-name>DefaultServletAdapter</servlet-name> ... <url-pattern>*.js</url-pattern> <url-pattern>*.css</url-pattern> </servlet-mapping>
- Change the Storefront Implementation so that the custom 404 Page also returns the HTTP Status Code 404.