I've been checking around and can't find an explanation of how the FacesServlet resolves a URL to a real file in the web app file structure. Within the context of servlets, my understanding is that a URL is just a made-up name that you want clients to use. In web.xml you then map specific servlets to URL patterns, but the real name/location of the servlet is hidden from the outside world...that's for servlets in general.
Specifically for JSF 2, we deal with the FacesServlet, which leads me to my first question: is the FacesServlet the only servlet I need to provide mapping details for in my app (and the only servlet I need, period)? It seems like the answer is "yes," but if there are situations where this wouldn't be the case, please give an example.
From reading other questions on SO, I understand that not all requests need to pass through the FacesServlet, so basically requests are divided into A) requests for static content that shouldn't be processed by the FacesServlet, and B) requests for dynamic content that need to be processed by the FacesServlet. So, how is the static content obtained? Just by having an incoming request in which the URL doesn't match the URL pattern for the FacesServlet, but does match a real file location in the app file structure?
Finally, my main question: when a request comes in that matches the URL pattern for the FacesServlet, how does the FacesServlet know which view file (.xhtml) to render? Is there a convention in working with JSF 2 that I need to follow to make it work? If not, then I don't get it, because, like I mentioned above in the case of a "general" servlet, the URL could include a name that nas nothing to do with the real file name, as long as it's mapped to the correct servlet in the web.xml file. I feel like I'm missing something obvious (and important) here. The only thing I can think of is that the URL should match a real file location or that there's another mapping table or something that associates URLs with view files.
By the way, I looked at this question, which is related but doesn't have any answers.
Thanks!
The easiest way to serve static content is outlined in the servlet specification, section 10.5:
and
That is, to serve static content, it is sufficient to save the content in the appropriate directory of your web application.
Servlet mappings are in addition to this "implicit" servlet. Most JSF applications therefore only declare the FacesServlet. IIRC, in recent JSF implementations that servlet will even declare itself if its declaration is omitted, so you don't even have to declare it explicitly.
How the FacesServlet locates the definition of the view to use is defined in the JSF specification, in particular section 7.6.2:
The default implementation is specified in the following section 7.6.2.1. I spare your the full quotation. The gist is that if the Faces Servlet is mapped with a prefix mapping (e.g.
/faces/**
), the viewId is the part of the URL following the prefix, and if the Faces Servlet is mapped with a suffix mapping (e.g.*.jsf
), the viewId is the part of the URL following the context path, with replaced file extension. For instance, if the servlet is mapped to*.jsf
, a request for the URLhttp://host/context/admin/userlist.jsf
would read the view definition from the fileadmin/userlist.xhtml
in the web application directory.