135

When should I use an <h:outputLink> instead of an <h:commandLink>?

I understand that a commandLink generates an HTTP post; I'm guessing that outputLink will generate HTTP gets. That said, most of the JSF tutorial material I've read uses commandLink (almost?) exclusively.

Context: I am implementing a wee little demo project that shows a header link to a user page, much like Stack Overflow's...

needs more jquery

...and I am not sure if commandLink (perhaps using ?faces-redirect=true for bookmarkability) or outputLink is the right choice.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Matt Ball
  • 354,903
  • 100
  • 647
  • 710

2 Answers2

199

The <h:outputLink> renders a fullworthy HTML <a> element with the proper URL in the href attribute which fires a bookmarkable GET request. It cannot directly invoke a managed bean action method.

<h:outputLink value="destination.xhtml">link text</h:outputLink>

The <h:commandLink> renders a HTML <a> element with an onclick script which submits a (hidden) POST form and can invoke a managed bean action method. It's also required to be placed inside a <h:form>.

<h:form>
    <h:commandLink value="link text" action="destination" />
</h:form>

The ?faces-redirect=true parameter on the <h:commandLink>, which triggers a redirect after the POST (as per the Post-Redirect-Get pattern), only improves bookmarkability of the target page when the link is actually clicked (the URL won't be "one behind" anymore), but it doesn't change the href of the <a> element to be a fullworthy URL. It still remains #.

<h:form>
    <h:commandLink value="link text" action="destination?faces-redirect=true" />
</h:form>

Since JSF 2.0, there's also the <h:link> which can take a view ID (a navigation case outcome) instead of an URL. It will generate a HTML <a> element as well with the proper URL in href.

<h:link value="link text" outcome="destination" />

So, if it's for pure and bookmarkable page-to-page navigation like the SO username link, then use <h:outputLink> or <h:link>. That's also better for SEO since bots usually doesn't cipher POST forms nor JS code. Also, UX will be improved as the pages are now bookmarkable and the URL is not "one behind" anymore.

When necessary, you can do the preprocessing job in the constructor or @PostConstruct of a @RequestScoped or @ViewScoped @ManagedBean which is attached to the destination page in question. You can make use of @ManagedProperty or <f:viewParam> to set GET parameters as bean properties.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I assume that it also doesn't matter if the `` is in an `` - e.g. it can be, but it doesn't have to be, right? – Matt Ball Nov 30 '10 at 19:40
  • 2
    No, doesn't have to be. Only [`UICommand`](http://download.oracle.com/javaee/6/api/javax/faces/component/UICommand.html) components needs to go in an [`UIForm`](http://download.oracle.com/javaee/6/api/javax/faces/component/UIForm.html) component. – BalusC Nov 30 '10 at 19:42
  • Got it. So - is there any other compelling case to use an `` other than pure page-to-page navigation? – Matt Ball Nov 30 '10 at 19:55
  • 3
    None, actually. Generally, when you can, stick to `h:outputLink` or `h:link` for links. SEO should not be underestimated. By the way, for nice REST-like URL's like here on SO, have a look at [PrettyFaces](http://ocpsoft.com/prettyfaces/). – BalusC Nov 30 '10 at 20:02
  • Okay, many thanks for the clarification. Is the difference between `h:link` and `h:outputLink` just in the URL encoding (like the difference between `#{...}` and ``)? – Matt Ball Nov 30 '10 at 20:06
  • 1
    No, the difference is that `h:link` takes JSF view ID (e.g. `page`) as value and `h:outputLink` takes a real URL (e.g. `/page.xhtml` or `/page.jsf`, or other depending on your `FacesServlet` mapping) as value. URL encoding happens anyway in both cases. There's by the way no difference between render behaviour of EL in template text `#{...}` and `h:outputText`. Both escapes predefined XML entities (no, that's not the same as URL encoding). The `h:outputText` only offers more attribtues like `id`, `styleClass`, etc to control the component and/or markup. – BalusC Nov 30 '10 at 20:11
  • 1
    @BalusC What exactly you mean by "fullworthy HTML" in the first line of your answer ? – Geek Oct 25 '12 at 13:54
  • 1
  • 1
    @ethanjyx: that it produces exactly the same result when the current URL in browser's address bar is bookmarked/copypasted/shared/re-executed. I.e. it's idempotent. See further also http://stackoverflow.com/questions/15521451/how-to-make-url-reflect-the-current-page-and-not-the-previous-one/ – BalusC Jun 27 '13 at 17:16
  • hey @BalusC, can you please suggest the usages of h:commandLink and h:outputLink in terms of garbage collection? Which should be used so that the memory won't be affected? – Asgar Apr 12 '23 at 11:00
  • @Asgar: there's no difference at all on that. You should just be using the right tool for the job. See also https://stackoverflow.com/questions/15521451 – BalusC Apr 12 '23 at 11:20
  • @BalusC, I am using primefaces, suppose there are two pages with two different ManagedBeans with ViewScoped, If I use h:outputLink and navigate between them then the PreDestroy method is not called, but if I use h:commandLink then the PreDestroy is called. Does that not mean using commandLink and navigating or going to different views, the bean is destroyed immediately and is eligible for Garbage Collection? Is it not good in terms of performance? – Asgar Apr 12 '23 at 13:21
  • @Asgar: outputLink is better wrt performance. In your specific case commandLink is better wrt memory consumption. If you wish these beans to be garbage collected on outputLink as well, use OmniFaces `@ViewScoped` instead of standard JSF one. See also https://stackoverflow.com/q/40569971 – BalusC Apr 12 '23 at 13:53
3

I also see that the page loading (performance) takes a long time on using h:commandLink than h:link. h:link is faster compared to h:commandLink

Ashok
  • 47
  • 1
  • 1
  • 1
    I find that hard to believe. Aside from hearsay/your own anecdotal evidence, do you have anything to support that? – Matt Ball Jun 20 '11 at 18:58
  • 5
    @Matt: I can imagine that it's slower when you have a this POST navigation link inside a "God" form in a page with for example a datatable with >1000 rows containing 3 input fields per row. But such a page has other serious problems anyway :) – BalusC Jun 20 '11 at 19:27