Archive for March, 2012

Sample CRUD application with JSF and RichFaces

30 March 2012

During my thesis project I will be using JavaServer Faces. Therefore it is important I get familiar with the framework. To get familiar I made a small CRUD (Create Read Update Delete) application. It is a simple application that makes it possible to keep track of users. It consists of a user list, a page to add/edit users and a page to delete a user.

The code

The research project will focus on when it is beneficial to use client-side scripting instead of/complementary to server side programming. To get up to speed a small CRUD application has been made without the use of client-side scripting and the same CRUD application was adapted to use client-side scripting by using RichFaces. The client-side scripting was added to the editing form to allow validating the form, without the need of making requests to the server.

The structure of the source project is as follows:

  • backing
    • Index.java – Backing for index.xhtml
    • UserDelete.java – Backing for UserDelete.xhtml
    • UserEdit.java – Backing for UserEdit.xhtml
  • constraints
    • Email.java –  Validation annotation for fields. Fields with this annotation are validated to be a proper email address.
    • EmailConstraintValidator.java – Performs the validation for email addresses.
  • ejb
    • UserDAO.java – Data Access Object for users.
  • entities
    • User.java – Bean object for a user. The fields of this object are annotated with validators.
    • UserConvertor.java – Converts a userId to a user.
  • util
    • Messages.java – Utility object that helps with sending messages between pages.

The following JSF pages are in the project:

  • index.xhtml – Page with a list with all users
  • user_delete.xhtml – Page used to confirm whether a user should be validated
  • user_edit.xhtml – Page used for adding and editing users

While creating this application, I tried as much as possible to adhere to best practices. For examples, to go from the master (list) view to the detail (edit) view a GET request is used with the user id as parameter. The user is modified via POST and there’s a redirect and GET back to the master view (PRG pattern).

Both applications make use of Enterprise Java Beans, Bean Validation and Java Persistence API. EJB is used to inject persistence in the managed beans. Bean validation is used to ensure the data is consistent with the business rules.

In the RichFaces version user_edit.xhtml is updated to have client-side validations. Only the email address cannot be validated on the client. For that field is Ajax used.

The code of the project has been uploaded to Google Code so it can viewed by everyone. The code without the use of client-side scripting is put in the default branch and the code with client-side scripting is put in the RichFaces branch.

Demo

The compiled applications have been uploaded to OpenShift. It makes showing your work to the public very easy. This is a free cloud platform which runs a JBoss server. The projects can be directly uploaded from Eclipse to the OpenShift server. The live demo can be viewed here.

To upload your project yourself to OpenShift it is first required to make an account at OpenShift. Then register your public key at OpenShift. When you have the OpenShift plug-in installed in Eclipse you can add the OpenShift server to the server view in Eclipse. From there you can get the default project from OpenShift. This project is only used to send the war files to server, not to hold the code. By adding the JSF project to the OpenShift server it automatically places the war file in the OpenShift project during a publish. By pushing the OpenShift project to the server using GIT, the application is put in the cloud and is ready to use. The detailed process to upload to OpenShift from Eclipse is available here.

So wrapping up, I’ve made a small project to get familiar with the code, I have uploaded the code to Google Code and I’ve put the application OpenShift.

Mark van der Tol

Automatically setting the label of a component in JSF 2

22 March 2012

In JSF input components have a label attribute that is typically used in (error) messages to let the user know about which component a message is. E.g.

Name: a value is required here.

If the label attribute isn’t used, JSF will show a generated Id instead that is nearly always completely incomprehensible to users. So, this label is something you definitely want to use.

Of course, if the label is going to be used in the error message to identify said component, it should also be rendered on screen somewhere so the user knows which component has that label. For this JSF has the separate <h:outputLabel> component, which is typically but not necessarily placed right before the input component it labels.

The problem

The thing is though that this label component should nearly always have the exact same value as the label attribute of the component it labels, e.g.

<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{myBean.username}" label="Username" required="true" />

There’s a duplication here that feels rather unnecessary (it feels even worse when the label comes from a somewhat longer expression, which is typical for I18N). My co-worker Bauke identified this problem quite some time ago.

Finding a solution

It appears though that an implementation that automatically sets the label attribute of the target “for” component to the value of the outputLabel isn’t that difficult, although there are a couple of things to keep in mind.

For starters, a component in JSF doesn’t directly have something akin to an @PostConstruct method in which you can set up things. There are tag handlers and meta rules in which you can set up attributes, but when they execute not all components have to exist yet.

Luckily, we always have the plain old constructor and since JSF 2 components can register themselves for system events. This gets us into a method where we can setup things.

Additionally, we have to be aware of state. System event listeners are luckily not stateful, so perfectly suited for tasks that need to be setup once (Phase listeners are stateful though, and will ‘come back’ after every postback). Attributes of a component are by default stateful, so we only need to set those once, not at every postback. Finally, the API distinguishes between deferred expressions (value expressions) and literals. If we want to support dynamic labels and only want to setup the wiring once, it’s important to take this distinction into account.

Finally, when searching for the target “for” component we can take advantage of the fact that typically this component will be close by. Compared to the regular search on the view root, the well-known “relative-up/down” search algorithm is probably more efficient here. This algorithm will start the search in the first naming container that is the parent of the component from where we start our search in the component tree. This will work its way up until there are no more parents, and if the component then still isn’t found (practically this is rare if the component indeed exists), then a downward sweep will be done starting from the root.

So, this all comes down to the following piece of code then (slightly abbreviated):

@FacesComponent(OutputLabel.COMPONENT_TYPE)
public class OutputLabel extends HtmlOutputLabel implements SystemEventListener {
 
    public OutputLabel() {
        if (!isPostback()) {
            getViewRoot().subscribeToViewEvent(PreRenderViewEvent.class, this);
        }
    }
 
    @Override
    public void processEvent(SystemEvent event) throws AbortProcessingException {
 
        String forValue = (String) getAttributes().get("for");
        if (!isEmpty(forValue)) {
            UIComponent forComponent = findComponentRelatively(this, forValue);
 
            if (getOptionalLabel(forComponent) == null) {
                ValueExpression valueExpression = getValueExpression("value");
                if (valueExpression != null) {
                    forComponent.setValueExpression("label", valueExpression);
                } else {                    
                    forComponent.getAttributes().put("label", getValue());
                }
            }
        }
    }
}

After creating a tag for this component, the following can now be used on a Facelet:

<o:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{myBean.username}" required="true" />

If a form is posted with this in it and no value is entered, JSF will respond with something like:

Username: Validation Error: Value is required.

An implementation of this is readily available in the new OmniFaces library, from where you can find the documentation and the full source code. There’s also a live demo available.

Arjan Tijms

css.php best counter