What is the difference between FacesContext and ExternalContext

vmaric picture vmaric · Apr 6, 2013 · Viewed 28.2k times · Source

What is the difference between FacesContext and ExternalContext? When can I use one or other? What has the one and what has the other?

The following sample is from the book JavaServer Faces 3rd edition:

 <h:commandButton ... actionListener="#{rushmore.handleMouseClick}" />

Backing bean:

public void handleMouseClick(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();
    String clientId = e.getComponent().getClientId(context);
    Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
    // ...
}

Why is request parameter in ExternalContext? What is clientId? Is it generated by JSF when the application is started?

Answer

BalusC picture BalusC · Apr 7, 2013

Carefully look in their javadocs to see what methods they offer and what exactly those methods all do.

If you look closer at those methods listed in the javadoc, you'll notice that the FacesContext generally offers access to JSF-specific artifacts which are further in no way related to the "underlying" Servlet or Portlet API for which JSF is been designed to run on top of. E.g. creating converters, validators, components, EL expressions, etcetera and obtaining information about view root, supported locales, etcetera and adding phase listeners, system event listeners, etcetera. Everything which is specific to JSF API.

And, ExternalContext generally offers access to Servlet or Portlet-specific artifacts which JSF is currently using "under the covers". E.g., when running on a Servlet container, the HTTP servlet request, HTTP servlet response, HTTP session and Servlet context and inherently also all of their artifacts. Click those links, you'll see that they in turn offer methods which are also been delegated by the ExternalContext, such as getRequestParameterMap(). See also the javadoc. Yes, also click that link, you'll see that it explicitly mentions the servlet request:

Servlet: This must be the set of parameters available via the javax.servlet.ServletRequest methods getParameter() and getParameterNames().

There's nothing which can be offered by the both contexts. So there would be absolutely no reason to prefer the one or the other. Just use the right one for the job you need to perform.

As to the client ID, it's indeed generated by JSF, but definitely not on server's startup. It's just generated for every single JSF component on a per-view basis. In case of input components like <h:inputText>, which generates a HTML <input> element, it also becomes the name attribute like so

<input type="text" id="formId:inputId" name="formId:inputId" ... />

The formId:inputId is exactly the JSF client ID. It becomes the request parameter name. The HTML representation of the command button has also a name which ends up as request parameter name with the button's value as parameter value.