Monday, November 25, 2013

Angular JS designs web page using client-side technology. The model-view-controller is established in client-side. JSF requires data-binding have to be on server side at minimum. Given an example like this

This is a piece of HTML supported by angular JS. The value='My Value' is generated by JSF at server-side. The issue is that default value will be discarded by angular after the template is processed since the initial value comes from model which is empty at the beginning. So how can we ask angular to initialize value from element value attribute?

This post gives a brilliant idea:add a directive to initialize the model value from input attribute. I modifies the script a little bit to accept a mode for value initialization.

Thursday, November 21, 2013

The integration issue between JSF and Spring

JSF 2.2 comes with several cool features: html5 support, resource contracts, flow scope, etc. As a JSF enthusiast, you may want to use it in your new project or update your old project. But most likely you project already has spring MVC as it is the 'glod' standard.

It is always a trouble to using Spring together with JSF. JSF is a completely MVC framework while Spring WebMVC is designed for other view technology to plugin. When it comes to JSF, you will find many function duplication between MVC and JSF. This duplication will definitely cause trouble for JSF developer. For example, are you going to use Spring view mapping or JSF navigation? To handle a JSF commandButton action, are you going to use Spring WebFlow action or JSF action Listener? In a Spring WebFLow, can you still use the whole JSF process flow?

This is just the beginning of the problem. JSF 2.2 is tightly coupled with CDI for some of its new feature. For example, it uses CDI for flowScope and new ViewScope.However, Spring does not fully support CDI in JEE. I guess it will become more and more difficult in using JSF under Spring as new JSF comes out in future.

Here I did some experiment to figure out how to use JSF 2.2 besides Spring Framework. The principle is not using Spring MVC for JSF.

Using two CDI frameworks

JSF 2.2 definitely needs CDI framework if FlowScope or ViewScope is used. Please note that ViewScope has many troubles in JSF 2.1 and it is the most used scope in JSF in my opnion. So I assume that CDI is definitely needed. Spring itself is a CDI framework, but not compliant with JEE standard(JSR 330). Besides Spring, we need a JSR 330-compliant CDI libary.

Do not use Spring MVC

Do not use any Spring MVC feature for your Facelet. This means you JSF facelet page is driven by FacesServlet, not by Spring MVC DispatchServlet.

In JSF 2.1, it is not easy add an icon for h:commandButton if Bootstrap is used. Here is the problem.
An icon is an HTML element inside a Button element in Bootstrap like this<button ><span class="glyphicon glyphicon-plus"></span></button>
But h:commandButton is rendered as <input type="button"> in JSF 2.1. No child HTML element is allowed.

Rendering approach in JSF 2.1

Before JSF 2.1, the Renderer takes over outputing html. You, as page author, only passes the attributes. Renderer will take care of your attributes when outputing html. This approach is apparently not flexible enough. For example, html5 introduces some new attributes. Other client framework like AngularJS also introduces new attributes and tag to html. Facelet renderer has no idea about these attributes and silently ignored them.

Rendering approach in JSF 2.2

In JSF 2.2, another approach is added. It is the passthrough attributes and elements. In this approach, you specify what you html looks like. The final html is exactly like the facelet file. Here I focus on Passthrough element.

In this example, the button element comes from html namespace. It should be very familiar to any web developer. The interesting part is two jsf: attributes: jsf:id and jsf:action. These two attributes asks JSF facelet subsystem to perform its tricks: data-binding or action-binding. So how can the subsystem knows the button element from html namespace is a commandButton in facelet. The html element mapping to JSF component tree is done at component tree building time. For detailed document, please consult the TagDecorator class JavaDoc. It is worthwhile to mention again you control the final HTML completely. You do not rely mysterious Renderer from JSF implementation do output HTML.