Doing Post-Redirect-Get Pattern in JSF 2

JSF 2.0 introduces the ability to send GET requests. This makes it possible to make bookmarkable pages. It also makes it possible to implement the Post-Redirect-Get (PRG) pattern. What is the PRG pattern? It is nothing new and we have been using it from day one of web application. It goes as follows:

  1. User submits a form. A POST request is sent.
  2. The server changes something in the database. For example, create a new customer.
  3. The server sends a redirect reply (302 or 301) to the browser. A POST request should never return HTML markup for too many reasons to get into here. The Location header of the reply contains a URI to the next page. Any necessary data, such as the ID of the newly created customer, needs to be added to the URI as parameters. For example,  display_customer.xhtml?customerId=10.
  4. Browser sends a GET request for the next page as set in the Location header of the previous reply. The server sends back HTML markup for that page. This page is also inherently bookmarkable, since all the URL parameters are there.

This essential pattern was not possible prior to JSF 2.0. Unfortunately, many badly written books and tutorials have made it difficult to understand how GET request works. That’s because they never explained it in the context of PRG pattern.

Let’s learn how to implement PRG pattern using a real example. Here, we will create a new customer.

First, the Customer class.

public class Customer {
    private String name;
    private String email;
    private int id;
//Getter and setter methods omitted for brevity

Next, the managed bean class. Pay attention to how the addCustomer() method returns the outcome. We will discuss it more later.

public class Controller {
    Customer customer = new Customer();

    public Customer getCustomer() {
        return customer;
    public void setCustomer(Customer customer) {
        this.customer = customer;

    public String addCustomer() {
        //Add customer to database
        System.out.println("Adding customer: " + customer.getName());
        //In real life, we will get a unique ID set

        return "display_customer?faces-redirect=true&includeViewParams=true";

    public void loadCustomer() {
        //Look up customer from database
        System.out.println("Loading customer by ID: " + customer.getId());
        customer = lookupCustomer(customer.getId());
    public Customer lookupCustomer(int id) {
        //Use DAO to retrieve customer data

Of course, in real life, addCustomer() will use a DAO class to add the customer to the database. Here we fake a unique ID of 10. Note the two extra parameters we are supplying to the “display_customer” outcome:

  1. faces-redirect – This causes a 302 redirect reply to be sent back.
  2. includeViewParams – This causes JSF to add all necessary URL parameters to the redirected URI in the Location header. How does JSF know what URL parameters to add? There is the trick. JSF will inspect the meta data of the target view – display_customer.xhtml – and find out the required view parameters. It will automatically add those to the redirected URI. So, let’s see how these views are defined.

First, let’s have a look at the view that contains the form – add_customer_form.xhtml. There is nothing special here.

Name: <h:inputText value="#{}" /><br/>
E-mail: <h:inputText value="#{}" /><br/>
<h:commandButton action="#{controller.addCustomer()}" value="Submit" />

Next the display_customer.xhtml file. This is where the magic happens. We add the metadata to the root.

    <f:viewParam name="customerId" value="#{}" />
    <f:event listener="#{controller.loadCustomer()}" type="preRenderView"/>
<h1>Customer Details</h1>
ID: #{} <br/>
Name: #{}<br/>

The <f:viewParam> metadata clearly says that the view needs the “customerId” URL parameter. This URL parameter is bound to the property of the managed bean. This has two effects:

  1. When constructing the Location URL of the 302 reply, JSF copies the value of to the customerId URL parameter.  In our case, the URI will look something like display_customer.xhtml?customerId=10.
  2. When a GET request arrives for display_customer.xhtml, JSF copies the customerId URL parameter to

Also, as a part of the GET request processing, JSF calls the pre-render listener loadCustomer(). This method initializes the customer property of the managed bean.

Now, not only have you implemented the PRG pattern, you also got a bookmarkable page that shows customer details.

PRG is nothing new. We have followed it religiously in Servlet/JSP and Struts days. The possibility to implement it is new in JSF. Frankly speaking, I like the way JSF automatically adds the required URL parameter to generate the redirected URL. This is better than way things are done in Struts. So, what are you waiting for. Get started with PRG in your JSF apps!

5 thoughts on “Doing Post-Redirect-Get Pattern in JSF 2

    • The line “” is mapping the customerId parameter to the property. You can use any other URL parameter name. For example, to use a URL parameter called myCustomerId, do: “”.

    • The line “f:viewParam name=”customerId” value=”#{}”” is mapping the customerId parameter to the property. You can use any other URL parameter name. For example, to use a URL parameter called myCustomerId, do: “f:viewParam name=”myCustomerId” value=”#{}””.

  1. Hi, thank you for the post; but what if i have a file.xhtml in my domain that submits a request to a compute.jsp outside my domain, and the compute.jsp performs some actions and returns a POST data to my outcome.xhtml, please how do i get the values returned from the compute.jsp displayed in my outcome.xhtml page.

    Thank you.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s