I am trying to get my application to map all files under /pages/* to JSF and facelets. However, I get a '/register.xhtml Not Found in ExternalContext as a Resource' error when I use the following web.xml with the URL http://localhost:8080/testapp. Any ideas on what might be wrong? Strangely, I can access the file as pages/register.jsf when I change the Faces Servlet mapped url-pattern to *.jsf.
I think actually the more correct definition would include a leading slash.
But you're confusing a URL with a file. "/pages/register.jsf" would be a URL reference. "/pages/register.xhtml" would be a file reference. URLs only look like file references, but their actual usage is entirely different.
An IDE is no substitute for an Intelligent Developer.
Joined: Jul 03, 2008
I added the extra leading slash so the welcome-file-list now looks like:
When I hit the URL http://localhost:8080/testapp, it now finds the resource, but it doesn't recognize it as a web page that it should render in the browser. Instead, it asks if I want to save or open the resource. Any ideas on how to get the page to load in a browser by default? I thought the servlet mapping and javax.faces.DEFAULT_SUFFIX would take care of that but apparently not.
You still have files and URLs confused. In order to get JSF to process the page, you have to provide a JSF URL. In other words, a URL that matches the FacesServelet URL selector as defined in servlet-mapping.
If you have a servlet-mapping that catches "*.jsf" URLs and a javax.faces.DEFAULT_SUFFIX of ".xhtml", then when a URL ending with "*.jsf" comes to the webapp server and matches the webapp context (meaning that it's aimed at THIS webapp and not some other webapp), then the URL request will be passed to the FacesServlet.
The FacesServlet will then dissassemble the URL, remove the ".jsf" and look at its DEFAULT_SUFFIX setting, where it will find the value ".xhtm". So it takes the URL, minus the "http://host:port/context" part, strips the trailing ".jsf", appends ".xhtml", then does a WAR resource lookup to find a WAR resource whose path matches the results. If one is found, then the FacesServlet will open it up and use it as the basis for the construction of a JSF view.
If you don't use the right URL (one ending in .jsf), the URL request won't get routed to the FacesServlet. In the case where it also doesn't match any servler/jsp URL mapping, the URL will go through the default processor, which will attempt to open the resource and copy it verbatim back to the client. Which is what's happening to you.
Joined: Jul 03, 2008
So to make sure I am understanding you, are you saying that the following entry will never work? I've seen this mapping listed in JSF books as valid, but it doesn't seem to be working for me.
Instead you are saying I should use:
If there is any way to get the /pages/* url-pattern servlet mapping to work, please provide a complete example of what I need to change in my web.xml file. Thanks for your help.
Yes, but the URL would be pages/xxxxx.jsp, not /pages.xhtml, at least in JSF1.
Although at that point, I'd have to go back and RTFM. Unlike JSF1, JSF2 defaults to using facelets, and I didn't pay close enough attention to the path-based dispatcher examples. I prefer the ".jsf" URLs myself.