1

I am on index.xhtml and I have this code snippet:

<h:form>
    <h:commandButton action="#{blogentryListerBean.olderBlogEntries}"
                     value="Older Blog Entries"/>
</h:form>

BlogEntryListerBean is RequestScoped. This is the code I have in olderBlogEntries

public String olderBlogEntries() {

    HttpServletRequest request
            = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();

    String id = request.getParameter("id");

    if (id == null || id.equals("")) {
        id = "0";
    }

    int pageIamOn = Integer.valueOf(id);

    String stringToBeReturned = "index.xhtml?id=" + (pageIamOn + 1) + "&faces-redirect=true";
    return stringToBeReturned;
}

So when I hit index.xhtml for the first time the URL I see is: index.xhtml as expected. The first time I click button "Older Blog Entries" I see URL: index.xhtml?id=1 Now when I hit Older Blog Entries button, I am again on index.xhtml?id=1

What is wrong here? Why am I not going to index.xhtml?id=2

?

Thanks.

Koray Tugay
  • 20,438
  • 37
  • 155
  • 276
  • but maybe you need the specify the id ant tag command button.. – ZaoTaoBao Dec 22 '13 at 09:52
  • you 're trying to recuperate a html tag with request.getParameter("id")..where is this parameter? always be null? so always be at pag 1..sorry if I don't understand correctly – ZaoTaoBao Dec 22 '13 at 09:58
  • No, you do understand correctly. It is the situation. It is always null. But I do not understand why. – Koray Tugay Dec 22 '13 at 09:59

1 Answers1

3

You're actually misunderstanding the current Http lifecycle. Your problem basically is destination page (for your case index.xhtml itself) is not catching the sent param anywhere.

Remember you're performing a redirection at first, but when you press the button next time, it's currently another different request which knows nothing about your param, so, when the action is processed, your request.getParameter("id") returns null once and again as the param is not being sent.

Your problem has an easy solution, which is based in binding the received param to your view using f:viewParam:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <f:metadata>
        <f:viewParam name="id" />
    </f:metadata>
</h:head>
<h:body>
    <h:form>
        <h:commandButton action="#{bean.olderBlogEntries(id)}"
            value="Older Blog Entries" />
    </h:form>
</h:body>
</html>

And your java code would be like this:

@ManagedBean
@RequestScoped
public class Bean {

    public String olderBlogEntries(Integer id) {

        if (id == null) {
            id = 0;
        }

        String stringToBeReturned = "index.xhtml?id=" + (id + 1)
                + "&faces-redirect=true";
        return stringToBeReturned;
    }
}

In this case you need to pass a parameter to an action method, to do like that you need to have EL 2.2 available in your classpath. If you don't have it already set up, follow that steps.

The lifecycle woud be:

  • First request, you open the browser and perform a GET request against index.xhtml. No param is sent.
  • You press the button once, submitting the form as a POST request. The action method redirects to http://localhost:8080/basic-jsf/index.xhtml?id=1, which causes a GET request to be done by the client to this url. Now JSF catches the id view param and binds it to the view with the name id.
  • When you press the button again, JSF calls the action method with the current param, valued 1. The redirection now goes to http://localhost:8080/basic-jsf/index.xhtml?id=2.

Alternatively, you could bind the view param to a bean property. In that case, there would be no need to pass it as method parameter:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <f:metadata>
        <f:viewParam name="id" value="#{bean.id}" />
    </f:metadata>
</h:head>
<h:body>
    <h:form>
        <h:commandButton action="#{bean.olderBlogEntries}"
            value="Older Blog Entries" />
    </h:form>
</h:body>
</html>

Implementing your property's get/set methods:

@ManagedBean
@RequestScoped
public class Bean {

    private Integer id = 0;

    public Integer getId() {
        return id;
    }

    public String olderBlogEntries() {
        String stringToBeReturned = "index.xhtml?id=" + (id + 1)
                + "&faces-redirect=true";
        return stringToBeReturned;
    }

    public void setId(Integer id) {
        this.id = id;
        System.out.println("id " + id + " received");
    }
}

See also:

Community
  • 1
  • 1
Xtreme Biker
  • 28,480
  • 12
  • 120
  • 195