[jsf] When should I use h:outputLink instead of h:commandLink?

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.

This question is related to jsf jsf-2

The answer is


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:


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