Netbeans Visual JSF Web Application is a strict Java EE Application and follows the Java Server Faces standards. In order to support rich JSF application development, Visual Web introduces few extension libraries.
When Visual JSF framework is added to a Netbeans Web project, under the hood it creates all the code required for a basic Java Server Faces Application
What happens when you drag and drop a component?
<webuijsf:button binding="#{Page1.button1}" id="button1" text="Button"/>
private Button button1 = new Button();
public Button getButton1() {
return button1;
}
public void setButton1(Button b) {
this.button1 = b;
}
Note: As of NB 6.1, this no longer happens. If
needed, click on the component and select "Create Binding".What happens you drag and drop database table on to a component?
private void _init() throws Exception {
customerDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet)
getValue("#{SessionBean1.customerRowSet}"));
}
private CachedRowSetDataProvider customerDataProvider =
new CachedRowSetDataProvider();
public CachedRowSetDataProvider getCustomerDataProvider() {
return customerDataProvider;
}
public void setCustomerDataProvider(CachedRowSetDataProvider crsdp) {
this.customerDataProvider = crsdp;
}
private CachedRowSetXImpl customerRowSet = new CachedRowSetXImpl();
public CachedRowSetXImpl getCustomerRowSet() {
return customerRowSet;
}
public void setCustomerRowSet(CachedRowSetXImpl crsxi) {
this.customerRowSet = crsxi;
}
private void _init() throws Exception {
customerRowSet.setDataSourceName("java:comp/env/jdbc/APP_ApacheDerby");
customerRowSet.setCommand("SELECT * FROM APP.CUSTOMER");
customerRowSet.setTableName("CUSTOMER");
}
<webuijsf:button binding="#{Page1.button1}" id="button1"
text="#{Page1.customerDataProvider.value['CUSTOMER.NAME']}"/>
How does the application works at runtime?
When the browser sends request to webserver or appserver, the "Initial Page" information specified in the web.xml is accessed. Since the initial page has "faces" as prefix, the page is routed via the Faces Servlet specified in the web.xml, which invokes the Faces Application to process the web page and the Application Life Cycle occurs.
How does the Visual Web Application Model hooks in to the JSF Application Life Cycle?
Java Server faces allows to configure the Faces Application via Application Configuration files. When Faces Application Context gets initialized, it finds all the faces-config.xml files (Ex. specified in META-INF of jar files, WEB-INF/faces-config.xml or specified in the context-param of web.xml) to configuare the Faces Application. Visual Web Application Model takes advantage of this and creates a Custom PhaseListener and registers it to the JSF application via META-INF/faces-config.xml file of the library jar.
The PhaseListener registered by Visual Web Application model will be notified at the beginning and ending of processing for each standard phase of the request processing lifecycle, which in turn invokes the methods such as init(), preprocess(), prerender() and destroy() of the Page Bean.
Unfortunately, in order to find the page bean (Page1.java) corresponding to the page (Page1.jsp), the Application Model relies on
Understanding the life of Managed beans
It is important to understand the life of a Managed Bean in order to design a better scalable application. The life of Managed Beans depend on the scope of Managed Bean as specified in the managed-bean element of the faces-config file.
As I mentioned above, when a database table is bound to a component, information is stored in Page1.jsp, page1.java and SessionBean1.java. When Page1.jsp is processed, the following happens
text="#{Page1.customerDataProvider.value['CUSTOMER.NAME']}"
This ends up
instantiating the class Page1.java and invoking the method
getCustomerDataProvider(). customerDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet)
getValue("#{SessionBean1.customerRowSet}"));
When
#{SessionBean1.customerRowSet}
is resolved SessionBean is instantiated and the method
getCustomerCachedRowset() is invoked. The necessary parameter of
the CustomerCachedRowset is set when init() -> _init() of the SessionBean
is invoked by the Application Model.Even though, both Page1.java & SessionBean1.java are instantiated, since Page1.java is a request scope managed bean, the instance of Page1.java will be garbage collected after the faces application completes the browser's request for Page1.jsp. However, SessionBean1.java is a Session scope bean and it will survive garbage collection until the user's session ends (times out). So data in the Session Bean should be carefully managed, to avoid unnecessary overloading of the Server that hosts the application.
If there are data which will not change and can shared by all users visiting the web site, then they should be kept in the Application scope Managed Bean (ApplicationBean1.java). For example, list of countries or states in a country.