views:

1836

answers:

2

I've recently started doing some JSF work - before that I've always used PHP or Python for web development.

I was somewhat surprised to find that JSF uses HTTP POSTs to navigate when the h:commandLink tag is used.

I have been using the commandLink as this is apparently the correct way to build JSF apps. Why does JSF use POST for navigation? What's wrong with GET? I can only assume that the Javascript that is automatically generated by JSF for the onclick events could exceed the maximum length for a GET request.

I already have a number of pages that are navigated using h:commandLink. This works wells until I use the browser's back button. How should I go about handling the back button in JSF?

I'm struggling to understand why JSF was build around the POST. It breaks bookmarking, back-paging and the ability to have your page indexed in search engines.

+1  A: 

Yup. JSF is built around POST and it's one of the biggest sticking points about JSF. Take a look at the JAX-RS/Seam or Spring for bookmarkable GETable pages.

Drew
+2  A: 

It isn't going to help you build a link on the client, but be aware of outputLink.

There is a redirect element for navigation rules which can help for some refresh issues.

<navigation-rule>
  <display-name>navBack</display-name>
  <from-view-id>/navBack.jsp</from-view-id>
  <navigation-case>
    <from-outcome>navTo</from-outcome>
    <to-view-id>/navTo.jsp</to-view-id>
    <redirect />
  </navigation-case>
</navigation-rule>

If all else fails, you can do the redirect URL yourself, as in this action:

public String doAction() {
  System.out.println("Did some non-idempotent operation");
  FacesContext context = FacesContext.getCurrentInstance();
  ExternalContext extContext = context.getExternalContext();
  Application app = context.getApplication();
  ViewHandler viewHandler = app.getViewHandler();
  String url = viewHandler.getActionURL(context, "/navTo.jsp");
  url = url + (url.indexOf('?') < 0 ? '?' : '+') + "foo=bar";
  url = extContext.encodeResourceURL(url);
  try {
    extContext.redirect(url);
  } catch (IOException e) {
    throw new FacesException(e);
  }
  return null;
}

Caveats: I can't remember if I'm encoding the URL correctly.

Various 3rd party libraries add differing gluts of features. I'm not sure if anything has been done in JSF 2.0 in this area, but it might be worth a look.

McDowell
Seems that JSF 2.X has much better support for GET and REST
Steve Claridge