Skip to content
Oleh Astappiev edited this page Oct 16, 2023 · 1 revision

Jakarta Faces

Error handling in beans

Users must be informed about errors when you can't solve them internally. Don't just log them or even worse use e.printStackTrace(); To inform the user you can just throw the exception. He will be presented with a default error message and we get a mail. This is sufficient for unlikely errors like SQL Exceptions, just thrown them. For more likely errors that depend on external services or user parameters, you shall catch the exceptions and add individual error messages or at least use this.addErrorMessage() to show a default warning to the user.

Bean scopes

  • A @RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too).
  • A @ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect.
  • A @FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file.
  • A @SessionScoped bean lives as long as the established HTTP session. (Discuss before you use this scope)
  • An @ApplicationScoped bean lives as long as the web application runs. (Discuss before you use this scope)

What are the differences between ${} and #{}?

  • #{} are for deferred expressions (they are resolved depending on the life cycle of the page) and can be used to read or write from or to a bean or to make a method call.
  • ${} are expressions for immediate resolution, as soon as they are encountered they are resolved. They are read-only.

Read more.

What are the differences between resource_table and :resource_table in update?

All relative client IDs (the ones not starting with : (colon)) are searched relative to the parent component which implements the NamingContainer interface (usually it is <h:form> or <p:dataTable>). So, if you are linking from one component to another within same form, don't use : character.

JSF expressions

Standard JSF introduces several search expressions, basically shortcut allowing you to get rid of the ids in many cases:

  • @form is the form surrounding the button.
  • @this the the command button itself.
  • @all is the entire JSF page. Use @all only in there's no other way: it's very inefficient, because it forces every JavaScript library to reinitialize.
  • @none is an exotic special case. It doesn't update anything. You sometimes need it to trigger an action on the server, but don't want to display anything new on the client.

PrimeFaces adds a couple of very useful search expressions:

  • @previous finds the previous JSF element in the same level of the JSF tree. Note that this usually is different from the predecessor in the HMTL tree.
  • @next finds the next JSF element in the same level of the JSF tree.
  • @parent finds the parent element of the current widget in the JSF tree.
  • @child(n) yields a certain child of the currently selected JSF subtree. However, I don't recommend using this search expression. It's extremely vulnerable to changes of your JSF view.
  • @() jquery expressions. These expressions are evaluated on the client. The most useful application is @(.css-class) to find one or more elements with a given CSS class. The advantage of the jQuery expressions is that you aren't restricted to by the JSF tree. Instead, the jQuery expressions always searches the entires DOM tree. Be careful: sometimes this can result in unexpected results, such as sending multiple forms simultaneously to the server, which is forbidden by HTML. Note that the algorithm parsing the jQuery expression is very primitive. Don't add spaces to the jQuery expression. Otherwise, it is treated as two distinct jQuery expressions. Note that this search expression can only be used for the update and process. Every other attribute requires a search expression evaluated on the server-side, such as @styleClass.
  • @root is the root of the JSF tree. It's equivalent to the preceding colon.
  • @namingcontainer
  • @composite resolves the closest CompositeComponent parent
  • @row(n)
  • @widgetVar(name) resolves a component by its widgetVar

Internationalization

Moved to separate page.

Output time and date

Use f:convertDateTime so that the date is formatted depending on the interface language. Example:

<h:outputText value="#{entry.date}">
  <f:convertDateTime dateStyle="default" type="date" timeZone="#{userBean.timeZone}" />
</h:outputText>

Passing get parameters to a page

<ui:define name="metadata">
  <f:metadata>
    <f:viewParam name="resource_id" value="#{surveyBean.surveyResourceId}" required="true" requiredMessage="Missing resource parameter" />
    <f:viewParam name="user_id" value="#{surveyBean.surveyUserId}" />
    <f:viewAction action="#{surveyBean.onLoad}" />
  </f:metadata>
</ui:define>

Often preRenderView or postConstruct are used, but the viewAction is preferable in most use cases. The names of bean action methods that are called by a template should start with "on" like onLoad() or onSubmit().

Confirm dialog

Instead of the JS confirm dialog use the primefaces dialog. Users seam to ignore the default confirm dialog and it may cause errors if the error message contains ' or ".

<p:commandLink action="xxxx">
  <p:confirm message="${utilBean.getLocaleMessage('leave_group_question', group.title)}" />
</p:commandLink>

(Doesn't work if you set ajax=false)

Don't use absolute paths

Never use an absolute path in HTML or CSS Like /folder/file.dat. This link will only work if the application is deployed in the ROOT context but this will not always be the case.

HTML

The main template defines the base path through <base href="{context-path}/lw/" /> therefore you have to link relative to this path e.g. href="./myhome/comments.jsf"

CSS

In CSS you can use relative path too or let JSF do the work: url("#{resource['main-template/img/learnweb_hq.png']}");

JSF

The problem doesn't hold for JSF beans. It will automatically handle navigational responses like

public String login() {
    return "/lw/any_page.jsf";
}

Validation

For advanced Bean validation JSF supports validationGroups. Example (in German)

Name convention

  • Use snake_case for ids.
  • Use kebab-case for classes.
  • You must NOT use id for styles.
  • p:dialog's widgetVar should use camelCase and ends with Dialog, e.g. copyResourceDialog.
Clone this wiki locally