Bootstrap3 with JSF error handling

Standard

JSF applications often get called ugly, or cookie cutter. The over use of the components and built in CSS creates the standardized look, but lacks flexibility. Using Bootstrap 3 CSS in combination with JSF attributes you can create a modern look. Take for example this salary sample salary calculator program which leverages JSF components.

Bootstrap 3 + JSF

The following code is used to create the amount input area.

<div class="form-group #{!amount.valid ? 'has-error' : 'none'}">
   <h:outputLabel value="Amount" for="amount" />
   <div class="input-group">
      <span class="input-group-addon"><i class="fa fa-dollar"></i></span>
         <h:inputText id="amount" value="#{myBean.amount}" binding="#{amount}" styleClass="form-control" required="true" requiredMessage="Enter dollar amount"/>
   </div>
</div>

This technique uses bindings to get the validation state of the inputText component. More information can about component bindings can be read on my other article “What is a JSF component binding? How can I use it?“. By intermixing both JSF + Bootstrap you can see how simple it is to give your app a modern look.

JSF detect session timeouts with web filter

Standard

When working with JSF 2.0 you will encounter a situation in which the user’s session times out and ajax requests fail. The response on a ajax request will be a viewExpiredException. However, the root cause is the session has expired. They are essentially stuck on the page and are forced to reload.

The solution:

Using a WebFilter the user can gracefully be redirected to a view expired exception page. This solution is accomplished by checking if the users session is valid, and if the context path is within our required conditions, finally if it is a ajax request it overwrites the default JSF response with our own custom xml response that tells the browser to redirect to the view expired exception page.

@WebFilter(filterName = "SessionTimeoutFilter", urlPatterns = "*.jsf")
public class SessionTimeoutFilter implements Filter {

    private final String timeoutPage = "/errors/viewExpired.xhtml";

    private final String loginPage = "/login.jsf";
    
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
    ServletException {

        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;

            if (isRequireSessionControl(httpServletRequest) && isSessionInvalid(httpServletRequest)) {

                if (isAJAXRequest(httpServletRequest)) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><partial-response><redirect url=\"")
                        .append(httpServletRequest.getContextPath() + timeoutPage).append("\"></redirect></partial-response>");
                    httpServletResponse.setHeader("Cache-Control", "no-cache");
                    httpServletResponse.setCharacterEncoding("UTF-8");
                    httpServletResponse.setContentType("text/xml");
                    PrintWriter pw = response.getWriter();
                    pw.println(sb.toString());
                    pw.flush();
                    return;
                }

                httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + timeoutPage);
                return;
            }
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    private boolean isAJAXRequest(HttpServletRequest request) {
        boolean check = false;
        String facesRequest = request.getHeader("Faces-Request");
        if (facesRequest != null && facesRequest.equals("partial/ajax")) {
            check = true;
        }
        return check;
    }

    private boolean isRequireSessionControl(HttpServletRequest httpServletRequest) {
        String requestPath = httpServletRequest.getRequestURI();
        return !requestPath.contains(timeoutPage) && !requestPath.contains(loginPage)
                        && !requestPath.contains("javax.faces.resource");
    }

    private boolean isSessionInvalid(HttpServletRequest httpServletRequest) {
        return httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid();
    }
}

Note: This fix is required due to a bug that is set to be resolved in JSF 2.3 release: https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790

Primefaces render kit html5 attributes

Standard

When using JSF 2.0 / 2.1 the need for using passthrough elements may occur. However, the passthrough element library is not compatible until JSF 2.2. The following solution uses a custom renderer so that primefaces 5.x can implement HTML5 attributes that you define.

Define your attributes

This first class is use to define which attributes we want to be able to pass through. The static string attributes is the name of these attributes.

The method above called writeAttributes does exactly what means. It writes the attribute(s) pass on the UIComponent to the current facesContext. The attributes that it is checking for are those of which you have defined.

public final class Html5DataAttributes {

    public static void writeAttributes(FacesContext context, UIComponent component) throws IOException {

        ResponseWriter writer = context.getResponseWriter();

        for (String attribute : Html5DataAttributes.attributes) {
            String value = (String) component.getAttributes().get(attribute);
            if (value != null) {
                writer.writeAttribute(attribute, value, null);
            }
        }
    }

    public static String[] attributes = {
        "placeholder", "data-toggle"
    };
}

You can add as many attributes to the array as needed. Make sure the attributes you do add are not already apart of the primefaces existing component, otherwise the values would be rendered twice.

Create a inputText renderer

To utilize the class above it requires extending the InputTextRenderer class in Primefaces. By default you must override the encodeEnd method. This is where all the magic happens. The method starts by calling the Html5DataAttributes class above. That writes out our custom attributes, it then concludes by calling the classes super. That assures that the existing component attributes in Primefaces will still be rendered.

public class PfInputTextRenderer extends InputTextRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {

        Html5DataAttributes.writeAttributes(context, component);
        super.encodeEnd(context, component);
    }

}

It should be noted that this is specifically only for the p:inputText component. You can create more renderers as you need them. Ex: CommandButtonRenderer

Register the renderer class

The last step is to tell primefaces where the new render class is located. This is accomplished by places the following in your faces-config.xml.

<renderer>
    <component-family>org.primefaces.component</component-family>
    <renderer-type>org.primefaces.component.InputTextRenderer</renderer-type>
    <renderer-class>com.sixthpoint.renderers.PfInputTextRenderer</renderer-class>
</renderer>

The render-type is the base class that primefaces uses for rendering the component. The component-family is the location of all similar components. The render-class is the new class we have created to handle inputText rendering.

How do I use it?

It is pretty simple, when calling p:inputText specify your custom attribute

<p:inputText value="#{myBean.value}" placeholder="My custom attribute"/>

What is I have JSF 2.2? 

Then don’t waste your time on what was described above. You can use the built in passthrough library

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:pass="http://xmlns.jcp.org/jsf/passthrough">
<h:body>
  <h:form id="form">
    <h:inputText value="#{myBean.value}" pass:placeholder="My placeholder"/>
  </h:form>
</h:body>
</html>

Read more on javadoc

What is a JSF component binding? How can I use it?

Standard

One of the more flexible features of Java Server Faces is the ability to use bindings within a view. Most developers omit the binding attribute and rely on a component libraries magic to display errors to the end user. Using the JSF binding component it is possible to specify the binding view component name for the UIComponent in the java backing bean. This binding refers to an instance of UIComponent in the EL scope allowing you to access certain properties #{mybinding.clientId}, #{mybinding.value},  #{mybinding.valid},  #{mybinding.submittedValue}

For example, lets assume you have a selectOneMenu with a list of items. These items are U.S states, then below you have a inputText area where the end user enters his/her city. We do not want to allow them to enter a city that is not in a state.

The problem can be solved using bindings. Consider this solution that binds the selected state value to the city entered. When submitted the validator will have access to both components.

The View

<h:selectOneMenu binding="#{state}" value="#{myBean.selectedState}">
    <f:selectItems value="#{myBean.states}" />
</h:selectOneMenu>
<h:inputText value="#{myBean.city}">
    <f:attribute name="state" value="#{state.value}" />
    <f:validator validatorId="locationValidator" />
</h:inputText>

Backing validator

@FacesValidator("locationValidator")
public class LocationValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) {
        Object item = component.getAttributes().get("state");
        // Object value holds city name
    }

}

Using bindings as described provides a solution for more complex validation requirements.

Using bindings with Bootstrap 3

Arguably the most popular css library out is Boostrap 3. It provides a sleek look to web pages. Using component bindings you can easily marry JSF with Bootstrap CSS. This is because components have a isValid EL expression attached to them.

For example lets assume you have a inputText that requires a min length of 4 and a max of 6. If outside of that requirement you want the field to be marked as invalid.

To highlight invalid fields use the binding component together with a form-group. The form-group has a has-error CSS class that will highlight the field inside. Once the inputText validation fails and refreshes the screen it will call the EL expression #{name.valid} and render the has-error class.

<div class="form-group  #{!name.valid ? 'has-error' : 'none'}">
   <label for="name" class="control-label">Enter name</label>
   <h:inputText value="#{myController.name}" binding="#{name}" id="name" styleClass="form-control">
      <f:validateLength minimum="4" maximum="6" />
   </h:inputText>
</div>

Whats the difference between #{mybinding.value} and  #{mybinding.submittedValue}?

This can be answered by understanding that the order of components matters. JSF will process your components in the order they appear in the view. The backing javascript for JSF does this. So for example if I was to swap the order of my state / city example so that the selectOneMenu came after the city inputText I would need to use the bindings submittedValue as ordering would cause the binding to be empty on the validator.

How to use conditional stylesheets or javascript with JSF

Standard

A annoying part of JSF is that it will strip out all of your conditional statements. These conditional references are needed for IE bug fixes 99% of the time. The solution is a simple hack using the outputText component. This will treat the html entities as strings and convert them.

For example this outputText will render the html5shiv cdn.

<h:outputText
value="&lt;!--[if lte IE 8]&gt;
&lt;script src=&quot;//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js&quot;&gt;&lt;/script&gt;
&lt;![endif]--&gt;"
escape="false" />

Results

<!--[if lte IE 8]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
<![endif]-->

Now once rendered the browser will be able to correctly interpret your conditional statements.

Primefaces bootstap styling loading modal

Standard

Building enterprise level application often requires loading large amount of data. This process can take some time. To provide a quality experience end users expect loading screens. This informs the user that they are interacting with the application.

Using Primefaces and Bootstrap 3 javascript you can easily alert end users when the server is working on processing data.

Consider the case of an end user is searching a database for collection of cars. The database may contain N amount of cars. Therefore, we must assume the process could take up to several hundred milliseconds. This is perfect situation for a loading bar.

The modal

The modal is a standard Bootstrap 3 Modal and has a simple progress bar. In the footer there is a reloading link in case the ajax call fails to return a response from the server.

<div class="modal fade" id="pleaseWaitDailog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">Processing</h4>
      </div>
      <div class="modal-body">
        <div class="progress">
           <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="99" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
              <span class="sr-only">99% Complete</span>
           </div>
        </div>
      </div>
      <div class="modal-footer">
        Stuck? <a href="javascript: window.location.reload()">try reloading...</a>
      </div>
    </div>
  </div>
</div>

Primefaces events

The commandLink component of primefaces offers many great features. The most useful for this senario is the onstart and onsucess event. Onstart executes a javascript method when the ajax request begins to the server, the oncomplete executes a method when the response of returned from the server. There is no guarantee that the response will come back, this is why the modal has the reloading link.

<p:commandLink id="search" action"#{myBean.doSearch}" update="searchResults" styleClass="btn btn-primary" onstart="$('#pleaseWaitDailog').modal('show');" onsuccess="$('#pleaseWaitDailog').modal('hide');">
   <i class="fa fa-search"></i> Search
</p:commandLink>

Using this commandLink, it will call the bootstrap modal library to show, then hide the processing modal defined above. This will give the end user a better interaction with the server.

Creating user accounts with grants in MYSQL

Standard

After you have installed a mysql database, setup root permissions, and added a few schemas it is time to start adding users. When adding users it is likely that different users call for different databases. This can be handled by using GRANTS in mysql.

To begin we will assume that there are two databases; PROD and DEVEL. We also have two users; Sarah, and Jessie. Sarah is assigned to the PROD database, while Jessie can only work on the DEVEL.

Create a new user

Start first by creating both users, the % signifies they can login from any location.

CREATE USER 'sarah'@'%' IDENTIFIED BY 'myPassword';
CREATE USER 'jessie'@'%' IDENTIFIED BY 'myPassword';

Grant permissions

Next they need to be granted permissions to access his/her working database.

# Sarah gets prod database
GRANT ALL PRIVILEGES ON PROD.* TO 'sarah'@'%' WITH GRANT OPTION;

# Jessie gets devel database
GRANT ALL PRIVILEGES ON DEVEL.* TO 'jessie'@'%' WITH GRANT OPTION;

At this point, if sarah logged in she would only see the PROD database. As expected if Jessie logged in he would only see the DEVEL database. They now only have permissions to there own separate databases.

Reset a password

Lets say you forget sarah’s assigned password. It can easily be reset with the following command.

SET PASSWORD FOR ‘sarah’@'%’ = PASSWORD(‘myNewPassword’);

Other useful commands

# Show all users; identification
select user,host from mysql.user;

# Show a users grants
SHOW GRANTS FOR 'sarah'@'%';

 

 

BackboneJS utilizing a event aggregator

Standard

When creating dynamic single page applications (SPA) a project can become rather large containing multiple views. These views may need to share or be alerted if the other view changes. BackboneJS can alert views if models data changes using the listenTo method.

this.listenTo(this.model, 'change', this.render);

However, lets assume you do not wish to pass a reference to a model in each of the views. It would be nice to have a way to pass data between the views another way; hence an event aggregator.

To demonstrate this consider this simple wine application. A user has the ability to modify the wine name or year. When the user data is submitted a dispatcher event is triggered alerting the wineView to rerender the set contents.

The Application

The first step is to create each view and pass in the event aggregator.

var aggregator = _.extend({}, Backbone.Events);

var formView = new FormView({ag: aggregator, model: new WineModel()});
var wineView = new WineView({ag: aggregator});

The formView binds to the click of the setData event which will update our wine model data. It then uses the event aggregators trigger method to alert all other views listening (the wineView) of the new data. The wine data model is passed in the trigger so a reference to the wine model is not needed in the wineView.

var FormView = Backbone.View.extend({
    el: '#input',
    aggregator: null,
    initialize: function (options) {
        this.aggregator = options.ag;
        this.render();
    },
    events: {
        "click #setData": "setData",
        "click .reset": "reset"
    },
    render: function () {
        this.$el.html(formTemplate);
        return this;
    },
    setData: function () {
        if ($("#name").val() !== "") {
            this.model.set({name: $("#name").val()});
        }
        if ($("#year").val() !== "") {
            this.model.set({year: $("#year").val()});
        }
        this.aggregator.trigger("aggregateEvent", this.model);

        return false;
    },
    reset: function () {
        this.model.clear().set(this.model.defaults);
        this.aggregator.trigger("aggregateEvent", this.model);

        return false;
    }
});

The wineView binds to the event “aggregateEvent” and when it is fired rerenders the view using the model data passed from the formView.

var WineView = Backbone.View.extend({
    el: '#output',
    initialize: function (options) {
        _.bindAll(this, "render");
        options.ag.bind("aggregateEvent", this.render);
    },
    render: function (model) {
        var compiledTemplate = _.template(WineTemplate)(model.toJSON());
        this.$el.html(compiledTemplate);
        return this;
    }
});

To see this event aggregator in action checkout my Github page and checkout a working example.

Bootstrap 3 + Primefaces 5 datatable styling

Standard

Using the default theme libraries supplied by Primefaces can make developing a custom look difficult. Having to override / make your own entire primefaces theme becomes painful; bootstrap 3 is the solution. Marrying Primefaces 5 component library and Bootstrap 3 renders a uniform design.

The following is a typical look of the Primefaces “boostrap” theme. Notice the headers on the columns as they have a background image. This design also lacks some functionality with different sized browsers.

Primefaces boostrap theme

Typical primefaces look

Utilizing the bootstrap 3 libraries the table can become responsive, have better design, and require little coding. Notice the difference in various design elements.

Disabled the default theme

Boostrap 3 with Primefaces 5 themes disabled

To marry primefaces and boostrap 3 it requires 3 steps; modifying the web.xml, setting class properties on the datatable, and overriding some default Primefaces css.

Web.xml

The Primefaces community supplies roughly 40 themes to choose from. We however, are not going to use any of them. Place the following code in your web.xml

<context-param>
   <param-name>primefaces.THEME</param-name>
   <param-value>none</param-value>
</context-param>

Setting the property above assures only the base styling will be rendered.

XHTML Page

On the desired page output a dataTable and attach the tableStyleClass attribute to it. The “table” and “table-striped” are Bootstrap css classes. Surround the entire dataTable with a div tag class “table-responsive”. The dataTabe is now responsive utilizing bootstrap css.

<div class="table-responsive">
   <p:dataTable tableStyleClass="table table-striped" value="#{myBean.itms}" var="itm">
      <p:column headerText="Column Name">
         <h:outputText value="#{itm.title}"/>
      </p:column>
   </p:dataTable>
</div>

Extra CSS

The default Primefaces css may still interact with the above dataTable rendering unwanted borders. The solution is to reset the css ui-datatable class generated by Primefaces like so:

.ui-datatable thead th, .ui-datatable tbody td, .ui-datatable tfoot td {
    border-style: none;
}

Using tmpwatch to free resources

Standard

Tmpwatch is a service that can recursively remove files that haven’t been accessed for a given period of time. In the case of CentOS it comes standard. If not enabled to run periodically, the tmp folder will expand until either the server is restarted, or it hits its disk resource limit. If the tmp folder does become to large, all programs that rely on temporary files will fail.

Ex: A apache webserver runs a php script which logs information for referencing. These log files are unwritable due to a lack of disk resources.

It will appear to be a permissions read / write error. However, a simple execution of the following tmpwatch command will free up space and delete all files older than 12 hours.

tmpwatch 12 /tmp

Note: Never delete all files in the tmp folder as they may be utilized for semaphore locking by various applications (mysql).