Java Server Faces (JSF) is a web user interface technology that can be used to supplement the user interface technology native to NetUI (the <netui> tag library).
To install the default JSF implementation, add the JSF facet to your web project. (Project > Properties > Project Facets > Add/Remove Project Facets > place check next to JSF).
Adding the JSF facet will install JSF Reference Implementation 1.1.
NetUI and JSF can be fully integrated in a web application. Below are described the most typical ways to make the two frameworks communicate.
To forward from a NetUI action to a JSF page, refer to the JSF page with the .faces file extension, even though Workshop creates JSF pages on disk with the .jsp file extension.
Suppose you have a JSF page named myJSFPage.jsp. To forward to this page from an action, use the following syntax:
@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "myJSFPage.faces") } ) public Forward navigate() { return new Forward("success"); }
For example, assume you have the following action in a NetUI controller file.
@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "myJSFPage.faces") } ) public Forward navigate() { return new Forward("success"); }You can invoke this action from a JSF by referencing navigate in an action attribute:
<h:form> ... <h:commandButton action="navigate" value="Go"/> </h:form>
Suppose you have an action navigate in a Controller class. To invoke navigate from within a JSF backing bean, use a command handler decorated with the annotation set @Jpf.CommandHandler/@Jpf.RaiseAction:
@Jpf.CommandHandler( raiseActions={ @Jpf.RaiseAction(action="navigate") } ) public String invokeNavigate() { return "navigate"; }
You bind to the command handler from the JSF page in the usual way:
<h:commandButton action="#{backing.invokeNavigate}" value="Go"/>
You call a control from a backing bean just as you would call a control from any Java class.
First you declare the control on the client Java class.
import org.apache.beehive.controls.api.bean.Control; ... @Control private CustomerControl customerControl;
Then you invoke methods on that control.
public Customer[] getCustomers() { return customerControl.someMethod(); }
<%@ page language="java" contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%> <netui-data:declarePageInput required="true" type="java.util.ArrayList<businessObjects.Customer>" name="getCustomersResult" /> ... <h:dataTable value="#{pageInput.getCustomersResult}" var="item0" border="1"> ... </h:dataTable>
References are not limited to the pageInput implicit object; you can reference any implicit object using JSF-style expressions. For example, the following expression references the foo field on the controller class:
<h:outputText value="#{pageInput.foo}"/>
You can also submit data (as a form bean) from a JSF page to a NetUI Controller class.
Suppose you have an action that has a form bean parameter:
@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "confirm.faces") } ) public Forward getCustomers(Customer form) { // do something with the submitted form data... return new Forward("success"); }
A form bean is a Java representation of an HTML form, where the bean properties correspond to the fields in the HTML form.
public class Customer implements Serializable { private String first = ""; private String last = ""; public Customer() { } public Customer(String first, String last) { this.first = first; this.last = last; } public void setFirst(String value) { first = value; } public String getFirst() { return first; } public String getLast() { return last; } public void setLast(String value) { last = value; } }
To submit this form bean to the action from a JSF page, reference the bean with a JSF style expression:
<h:form> <h:outputLabel value="First:" for="field1" /> <h:inputText value="#{backing.custFormBean.first}" id="field1" /> <h:outputLabel value="Last:" for="field2" /> <h:inputText value="#{backing.custFormBean.last}" id="field2" /> <h:commandButton action="getCustomers" value="Submit"> <f:attribute name="submitFormBean" value="backing.custFormBean" /> </h:commandButton> </h:form>
Note that the form bean is referenced via the backing bean. See the italic expressions above: #{backing.custFormBean.first}, #{backing.custFormBean.last}, and backing.custFormBean.
For these expressions to work, the backing bean must include the form bean as a field, with appropriate setters and getters on that field:
@Jpf.FacesBacking() public class index extends FacesBackingBean { private Customer custFormBean = new Customer(); public Customer getCustFormBean() { return custFormBean; } public void setCustFormBean(Customer bean) { this.custFormBean = bean; } }
Other integration scenarios are described in the document Integrating JavaServer Faces with Beehive Page Flow.
Mixing NetUI tags, or any JSP tags, with JSF tags can lead to surprising
results. You should have a good understanding of the particular tags you are
using before you mix the different tag libraries.
An exception you do not need to worry about is the use of the NetUI
<netui-data:declarePageInput> tag. This tag can be used freely with JSF
tags because it only sets up a contract with the NetUI controller class but
not affect the view in any other way.
NetUI defines implicit objects for use in databinding (e.g., 'backing', 'bundle', 'pageFlow', 'sharedFlow' and 'pageInput'). If a JSF managed bean is created and the name used in the faces-config.xml for that managed bean is the same as the NetUI implicit object names, a runtime FacesException for a bean property could occur. The following is an example that will cause this FacesException:
<managed-bean> <managed-bean-name>backing</managed-bean-name> <managed-bean-class>com.bea.example.MyBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>minimum</property-name> <property-class>int</property-class> </managed-property> </managed-bean>
This issue will only occur when you are using JSF in conjunction with Page Flows and NetUI.
Make sure you do not use any NetUI implicit object names for the <managed-bean-name> element of the faces-config.xml.
Workshop offers development support for may common JSF coding tasks, including:
To activate JSF development support you must be in the Page Flow perspective (Window > Open Perspective > Page Flow).
In the Page Flow perspective, the Design Palette supports JSF tags and JSF style expressions when composing JSF pages.
Note: the Design Palette recognizes JSF pages by the
presence of the JSF tag <f:view>
on the page. If the following
tag (and its associated library declaration) is present on the page, then
the Design Palette will generate code in JSF mode:
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> ... <f:view>
Note that any prefix value is acceptable; the prefix value 'f' is shown only because it is the default value.
For example, suppose you have a JSF page with a page input declaration:
<netui-data:declarePageInput type="java.util.ArrayList<businessObjects.Customer>" name="getCustomersResult" />
The presence of a page input declaration will activate the Design Palette with a corresponding node.
When this node is dragged and dropped onto the JSF page, JSF tags are used to construct the data display structures. For example:
<h:dataTable value="#{pageInput.getCustomersResult}" var="item0" border="1"> <h:column> <f:facet name="header"> <h:outputLabel value="Name" /> </f:facet> <h:outputText value="#{item0.name}" /> </h:column> </h:dataTable>
Workshop will create outputText fields for simple properties and launch the Data Display Wizard for complex and/or repeating type properties.
Similar support is provided for composing JSF forms through the Design Palette.
When a page contains a declaration for the core JSF core library (<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%>), the Design Palette will be in 'JSF mode'. Forms and data grids created from the Design Palette will use JSF tags and JSF expressions.
You can easily add command handlers to a JSF backing bean by right-clicking the Command Handler node and selecting New Command Handler. (You must be in the Page Flow perspective to see the Command Handler node.)
The wizard allows you to setup command handler method that can raise actions in the controller class. The wizard also lets you specify a form bean that can be passed along to the raised action. For details on passing form bean data from a JSF page to a controller action, see Passing Data Between JSF Pages and NetUI Actions above.
You can also add control references to a backing bean in a similar manner:
dev2dev documentation: Integrating JavaServer Faces with Beehive Page Flow