Welcome to the JavaRanch, William!
Let's see if I can help.
JSF is a template-oriented Model/View/Controller (MVC) framework where the Views are produced from static View Templates (more or less), Controllers are the FacesServlet and the logic inside the template tag definitions and Backing Beans are Models with a little non-MVC freight like change listeners and action methods in them. Unlike most MVC frameworks, you don't write Controller code yourself, although the NetBeans
IDE apparently incorrectly generates backing bean names as Controllers.
The normal approach in
J2EE is that when a URL comes in, it is matched against a set of URL
patterns in the WEB-INF/web.xml file. If the pattern matches a
servlet mapping, then the URL is routed to that servlet. If not, then the container bounces it down an internal chain that attempt to figure out what to do with it, and I could tell you more on that, but it doesn't matter here.
So if you set up web.xml to take URLs that end with ".jsf" and map them to the FacesServlet, then the FacesServlet is responsible for what happens next. As of JSF version 2 and later, the FacesServlet will strip down the core resource path removing the "http://", servername/port and application context paths from the front and removing the ".jsf" from the end. It then tacks on ".xhtml" to this resource path so that something like
http://saloon.javaranch.com/jsfapp/admin/usercontrol.jsf would reduce to a webapp resource pathname of "/admin/usercontrol.xhtml".
Having done that, the FacesServlet will then open this resource - which is the View Template - and compile it to produce a data structure in tree form - the Component Tree. This object is used both as the basis for rendering the page to the client and for processing incoming form data. So when the original URL request comes in, the Component Tree is built and the "render response" JSF phase uses it to produce the HTML returned to the client.
The Component Tree isn't simply discarded, however. It's compacted and saved. Depending on the web.xml file, it may actually be sent in whole or in part to the client or kept locally on the server. Which option you use depends on the amount of network resources you have versus server storage and whether you trust critical data to be sent off-server where it might get tampered with.
Now the page has been rendered as HTML on the client and your jsf <h:form> has been used to build an HTML (or xhtml) <FORM> element (HTML is case-insensitive, but convention is upper-case for HTML and lower-case tagnames for xhtml and XML). This FORM carries the usual input controls - the core HSF tagset has correspondences to the standard HTML form controls, but there is some extra freight that also gets rendered into the form.
That's because the REAL fun begins here. JSF uses a mechanism called "postback". Instead of sending forms and responses back and forth, JSF acts as though the same form was there all along and only the data has been transported (actually JSF was designed so that systems which work that way could do precisely that. HTML, alas, doesn't).
So the user enters data, submits the form and the JSF processor drags out the Component Tree that it previously saved. Form control data is validated, and if invalid the JSF lifecycle short-circuits. The Component Tree is used to render an updated version of the client HTML form with appropriate error messages and stuff and it's bounced back and forth from client to server until all fields are valid. That's an important aspect of JSF. You
cannot process a form until
all data in the form is valid. The backing bean(s) will only be updated when the data is valid and the action method (or its AJAX equivalent) will not be invoked until the backing bean(s) are updated.
OK. So the action method does its thing and indicates that JSF should navigate to a new View. The client's URL should change, right?
Well, as you have seen, no. Not right away, and that's because the URL isn't a resource
locator as it is in most frameworks so much as it is a resource
handle. The View name isn't determined from the URL once the workflow has begun, it's determined by the JSF workflow manager. The display is one step behind the actual process, but that doesn't matter because of that characteristic.
Of course, there are times when it's not desirable for that to be the case. You might have especially picky users/bosses. Or, more practically, you might be using the J2EE Container Managed Security System to control access to critical resources. CMS Security is based on checking the
incoming URL against the web.xml security patterns, so you have potential security loopholes when the URL lags the requested action. For that, there's a special navigation property: "redirect". Use of the faces-redirect option will cause an extra internal request to be made causing the client's navigation control URL to match the resource path of the View being rendered. It's extra overhead, but sometimes it cannot be avoided.