TOTD #42: Hello JavaServer Faces World with NetBeans and GlassFish
Posted by arungupta on August 20, 2008 at 9:18 AM EDT
This TOTD (Tip Of The Day) shows how to create a simple Java Server Faces application using NetBeans IDE 6.1. This is my first ever Java Server Faces application :) Much more comprehensive applications are already available in NetBeans and GlassFish tutorials.
The application is really simple - it allows you to create a database of cities/country that you like. You enter the city & country name on a page and click on Submit. This stores the data entered in the backend database and displays all the stored values in a new page. This application demonstrates simple JSF concepts:
- How to create a JSF application using NetBeans IDE ?
- How to populate a JSF widget with a Managed Bean ?
- How to use a Persistence Unit with JSF widgets ?
- How to setup navigation rules between multiple pages ?
- How to print simple error validation messages ?
- How to inject a bean into another class ?
- In NetBeans IDE, create a new project
- Create a new NetBeans Web project and enter the values
("Cities") as shown:

and click on "Next". - Choose GlassFish v2 as the deployment server and click on "Next".
- Select "JavaServer Faces" framework as shown below:

take defaults and click on "Finish". - Create a Persistence Unit as explained in TOTD #38. The values required for this TOTD are slightly different and given below.
- Use the following table definition:
create table cities(id integer AUTO_INCREMENT,
city_name varchar(20),
country_name varchar(20),
PRIMARY KEY(id)); - There is no need to populate the table.
- Use "jndi/cities" as Data Source name.
- There is no need to create a Servlet.
- Add the following NamedQuery:
@NamedQuery(name = "Cities.findAll", query = "SELECT c FROM Cities c"),
right after the highlighted parentheses shown below:

- Create a new bean which will perform all the database operations
- Right-click on "Source Packages", select "New", "Java
Class..." and specify the values as shown below:

and click on "Finish". - Create a new class instance variable for "Cities" entity
class by adding a new variable and accessor methods as shown below:
private Cities cities;
public void setCities(Cities cities) {
this.cities = cities;
}
and then injecting in "faces-config.xml" as shown by the fragment below:
<managed-bean>
<managed-bean-name>cities</managed-bean-name>
<managed-bean-class>server.Cities</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>dbUtil</managed-bean-name>
<managed-bean-class>server.DatabaseUtil</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>cities</property-name>
<value>#{cities}</value>
</managed-property>
</managed-bean> - Inject EntityManager and UserTransaction as
shown:
@PersistenceContext(unitName="CitiesPU")
private EntityManager entityManager;
@Resource
UserTransaction utx; - Add a method that returns a Collection of all entries in
the database table as shown below:
public Collection<Cities> getAllCities() {
Collection<Cities> allCities = new ArrayList<Cities>();
List list = entityManager.createNamedQuery("Cities.findAll").getResultList();
for (int i = 0; i < list.size(); i++) {
allCities.add((Cities)list.get(i));
}
return allCities;
} - Add a method that will save a new entry in the database
by using values from the injected "Cities" entity class as
shown below:
public String saveCity() throws NotSupportedException, SystemException, RollbackException, HeuristicMixedException, HeuristicRollbackException {
utx.begin();
entityManager.persist(cities);
utx.commit();
return "submit";
} - Finally, right-click in the editor pane and select "Fix
Imports":

and click on "OK". Make sure to pick the right package name for "NotSupportedException" and "RollbackException". - Add Java Server Faces widgets in the main entry page
- In "welcomeJSF.jsp", drag/drop "JSF Form" widget on line
22 as shown below:

- Select "Form Generated from Entity Class" and specify
"server.Cities" entity class in the text box as shown:

- The generated code fragment looks like:
<h2>Detail</h2>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Id:"/>
<h:outputText value="#{anInstanceOfserver.Cities.id}" title="Id" />
<h:outputText value="CityName:"/>
<h:outputText value="#{anInstanceOfserver.Cities.cityName}" title="CityName" />
<h:outputText value="CountryName:"/>
<h:outputText value="#{anInstanceOfserver.Cities.countryName}" title="CountryName" />
</h:panelGrid>
</h:form>
It generates a 2-column table based upon fields from the entity class. We will use this form for accepting inputs by making the following changes:
- Remove first two "h:outputText" entries because "id" is auto generated.
- Change "h:outputText" that uses value expression to "h:inputText" to accept the input.
- Use "cities" managed bean instead of the default generated expression.
- Add required="true" to inputText fields. This will ensure that the form can not be submitted if text fields are empty.
- Add "id" attributes to inputText fields. This will be used to display the error message if fields are empty.
- Add a button to submit the results:
<h:commandButton action="#{dbUtil.saveCity}" value="submit"/>
This must be added between </h:panelGrid> and </h:form> tags. - Add a placeholder for displaying error messages:
<br><br>
<h:message for="cityName" showSummary="true" showDetail="false" style="color: red"/><br>
<h:message for="countryName" showSummary="true" showDetail="false" style="color: red"/>
right after <h:commandButton> tag. The official docs specify the default value of "false" for both "showSummary" and "showDetail" attribute. But TLD says "false" for "showSummary" and "true" for "showDetail". Issue# 773 will fix that. - Add a new page that displays result of all the entries added so far
- Right-click on the main project, select "New", "JSP..." and specify the name as "result".
- Add the following namespace declarations at top of the
page:
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%> - Drag/Drop a "JSF Data Table" widget in the main HTML body
and enter the values as shown:

The generated code fragment looks like:
<f:view>
<h:form>
<h1><h:outputText value="List"/></h1>
<h:dataTable value="#{arrayOrCollectionOfserver.Cities}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value=" #{item.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="CityName"/>
</f:facet>
<h:outputText value=" #{item.cityName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="CountryName"/>
</f:facet>
<h:outputText value=" #{item.countryName}"/>
</h:column>
</h:dataTable>
</h:form>
</f:view>
Change the <h:dataTable> tag as shown below (changes highlighted in bold):
<h:dataTable value="#{dbUtil.allCities}" var="item"> - This page will be used to show the results after an entry
is added to the database. Add a new button to go back to the entry page
by adding the following fragment:
<h:form>
<h:commandButton action="back" value="back"/>
</h:form>
between </h:form> and </f:view> tags. - Add the navigation rules to "faces-config.xml" as shown
below:

The corresponding XML fragment is:
<navigation-rule>
<from-view-id>/welcomeJSF.jsp</from-view-id>
<navigation-case>
<from-outcome>submit</from-outcome>
<to-view-id>/result.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/result.jsp</from-view-id>
<navigation-case>
<from-outcome>back</from-outcome>
<to-view-id>/welcomeJSF.jsp</to-view-id>
</navigation-case>
</navigation-rule>
The updated code fragment (with changes highlighted in bold) looks like:
| <h2>Detail</h2> <h:form> <h:panelGrid columns="2"> <h:outputText value="CityName:"/> <h:inputText value="#{cities.cityName}" title="CityName" id="cityName" required="true"/> <h:outputText value="CountryName:"/> <h:inputText value="#{cities.countryName}" title="CountryName" id="countryName" required="true"/> </h:panelGrid> </h:form> |
Issue# 144217 will ensure to pick a pre-declared managed-bean or declare a new one if it does not exist already. After issue# 144499 is fixed then "id" attributes will be generated by default.
Issue #144218 will ensure these namespaces are declared by the IDE.
Let's run the application by right-clicking on the project and selecting "Deploy and Undeploy". The welcome page shows up and looks like as shown below:

Clicking on "Submit" without entering any values shows the default error messages as shown below:

Enter your favorite city/country and click on "Submit" to see the result page as:

Click on "Back" and enter few more cities. The updated result page looks like:

Here are some useful pointers for you:
- JSF Tag Library & API docs
- javaserverfaces.dev.java.net - the community website
- Java EE 5 JSF Tutorial and many more on the community website right navbar.
- Java Server Faces on SDN
- GlassFish Webtier Aggregated Feed
- Feedback
Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all tips is available here.
Technorati: totd mysql javaserverfaces netbeans glassfish
Related Topics >>
Blog Links >>
- Login or register to post comments
- Printer-friendly version
- arungupta's blog
- 717 reads





