Chapter 3. Write Your First Web Application

The Red Hat Developer Studio provides sophisticated tools for enterprise applications. With the Red Hat Developer Studio, you can get started very quickly with a web prototype, and then scale up your application to include enterprise features (e.g., business processes, web services, etc.) using the same developer tools. It is a "scalable" RAD (Rapid Application Development) tool.

A core element that makes the Red Hat Developer Studio "scalable" is the JBoss Seam framework. Seam is a fully featured application framework on top of Java EE 5. It is also one of the most popular enterprise Java frameworks today. Seam deeply integrates many other standard-based or open source frameworks (e.g., JSF, EJB3, JMS, Web Services, jBPM, JBoss Rules, Ajax4jsf, RichFaces, Facelets, Spring, iText, Quartz, TestNG etc.), and provides a single programming model for developers to "drive" those underlying frameworks via simple annotated POJOs (Plain Old Java Objects). It makes life easier for developers to tackle complex enterprise applications with many component frameworks.

In this chapter, we will cover how to build a simple Seam web application in minutes with the Red Hat Developer Studio.

3.1. Create a Seam Project

To create a new web application in Seam, select "New > Project ... > Seam > Seam Project". You will be prompted to enter a name and a location directory for your new project. You will also be asked to choose a JBoss AS server to deploy the project. You must choose the JBoss AS 4.2.0 instance we had defined in the JBoss AS Server manager view.

Create a Seam project

Figure 3.1. Create a Seam project

Next, you will be asked to select the "features" you want to use in your project. This allows Red Hat Developer Studio to setup the appropriate tooling for your project. Since JBoss Seam integrates all popular Java EE frameworks, you can select any combination of technologies from the list. Here, for this project, we will select Dynamic Web Module, Java, Java Persistence (JPA), JavaServer Faces (JSF), and Seam Facet for a typical database-driven web application.

Select toolings for the project

Figure 3.2. Select toolings for the project

A dynamic web application contains both web pages and Java code. The wizard will ask you where you want to put those files. You can just leave the default values.

Select directory names for web pages and Java files

Figure 3.3. Select directory names for web pages and Java files

Since you selected JPA and JSF tooling support, the project needs to incorporate the JAR files for those frameworks on its classpath. In the next two screens, you will be able to select where those library JARs come from. The easiest is just to select the JARs provided by the JBoss AS runtime associated with this project. That is why it is important to chose the right JBoss AS 4.2 runtime in the project setup window.

Ignore the database selection for now since we do not use an external database in this simple application. We can still use the embedded HSQL DB inside JBoss AS for development / testing purposes, as we will see soon.

Select provider for JPA JARs

Figure 3.4. Select provider for JPA JARs

Select provider for JSF JARs

Figure 3.5. Select provider for JSF JARs

The project setup wizard also asks you to configure how Seam generates code for the project. The Seam Home Folder should point to a valid Seam distribution. By default, it is set to the Seam distribution bundled in your Red Hat Developer Studio tool. For the deployment format, choose WAR deployment if you want to use POJOs for UI event handling and business logic; choose EAR deployment if you want to EJB3 beans for added features. In most web applications, the WAR deployment option would suffice. You should also enter Java packages for the entity beans (for database mapping) and session beans (for action handlers). All generated code will be placed in those packages.

Enter Java packages for generated code

Figure 3.6. Enter Java packages for generated code

Click on Finish to generate the application. The generated project contains all the necessary library JARs, XML configuration files, the ANT build script, as well as simple XHTML web pages and Java classes for the skeleton web application.

The generated Seam web application

Figure 3.7. The generated Seam web application

3.2. Build and Deploy the Seam Application

Once the application is generated, you can use the "Run on server" menu to build and deploy it into the JBoss AS runtime associated with the project. All you need is to start JBoss AS in the server manager, and load the browser at URL http://127.0.0.1:8080/MySeamProj/. You should see the following web page.

The generated application in action

Figure 3.8. The generated application in action

To make simple changes to the page, you just need to double click on the view/index.xhtml file and edit it in the visual editor. Notice that the visual editor lets you both the XHTML code and the rendered page. The rendered view is designed to make it easy to find stuff in a complex XHTML page.

Making changes in the visual editor

Figure 3.9. Making changes in the visual editor

Once you finished editing, save the file (File > Save), re-deploy the application, and reload the browser to see the changes.

The front page is changed

Figure 3.10. The front page is changed

3.3. Add a Web Page and an Action

To add a new page and related UI action to the project, use the "New > Other ... > Seam > Seam Form" wizard. You are prompted to enter the name of the web page, the name for the Seam component that handles UI actions from the page, and UI action method name.

New form for the application

Figure 3.11. New form for the application

The wizard generate a web page with a single text input field and an action button. Notice that the generated page uses layout/template.xhtml as a template. The template page provides the page header, footer, side menu, and CSS styles (see the template.xhtml for more details). The Simplepage.xhtml is assembled into the template when the Simplepage.seam URL is loaded.



<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

                xmlns:s="http://jboss.com/products/seam/taglib"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                template="layout/template.xhtml">

<ui:define name="body">

    <h1>Simplepage</h1>
    <p>Generated form page</p>

    <h:messages globalOnly="true" styleClass="message"/>

    <h:form id="simpleAction">
        <div class="dialog">
        <s:validateAll>
            <div class="prop">
                <span class="name">Value</span>
                <span class="value">
                    <s:decorate>
                        <h:inputText id="value" required="true"
                            value="#{simpleAction.value}"/>
                    </s:decorate>
                </span>
            </div>
        </s:validateAll>
        </div>
        <div class="actionButtons">
            <h:commandButton id="hello" value="hello" 
                action="#{simpleAction.hello}"/>                   
        </div>
    </h:form>

</ui:define>

</ui:composition>

The #{simpleAction.value} notation on the web page maps to the "value" property in the backend component named "simpleAction", and the #{simpleAction.hello} notation indicates that the hello() method is called when the button is clicked on. Here is the "simpleAction" named backend Seam component generated by the wizard.


@Name("simpleAction")
public class SimpleAction {

   
@Logger private Log log;

   
@In
   
FacesMessages facesMessages;

   
private String value;

   
//seam-gen method
   
public String hello()
    {
       
//implement your business logic here
       
log.info("simpleAction.echo() action called with: #{simpleAction.value}");
        facesMessages.add
("echo #{simpleAction.value}");
       
return "success";
   
}

   
//add additional action methods

   
@Length(max=10)
   
public String getValue()
    {
       
return value;
   
}

   
public void setValue(String value)
    {
       
this.value = value;
   
}

}

Load the Simplepage.seam in the web browser. Type something in the text field and click on the "hello" button. A JSF message containing the input string is created by the SimpleAction.hello() method. The message is displayed on the page via the h:messages tag.

3.4. Input Validation

Notice that in the generated SimpleAction class, there is a @Length annotation to validate the input when the input string is bound to #{simpleAction.value}. To see how this works, enter a text string longer than 10 chars and click on the button. This is what you should see.

The input validation in action

Figure 3.12. The input validation in action

Seam supports many different input validation annotations. To see an example, you can replace the @Length(max=10) annotation with the following. It would require the input string to have a first name and last name separated by a space. If the validation fails, the web page would print the customized error message.


@NotNull
@Pattern
(regex="^[a-zA-Z.-]+ [a-zA-Z.-]+",
      message=
"Need a firstname and a lastname")
public String getValue()
{
       
return value;
}     

Save the Java file, deploy the application, and reload the browser to see the new validation scheme in action.

More input validation

Figure 3.13. More input validation

3.5. Add a new UI Component

Now, let's add a little more logic to the application. We will add a new boolean property to the action component. If it is set to true, the action would capitalize the input string and display it on the web page. The following code in the SimpleAction class implements the logic.


@Name("simpleAction")
public class SimpleAction {

   
private boolean convertToCap;
   
   
public boolean getConvertToCap () { return convertToCap; }
   
public void setConvertToCap (boolean b) { convertToCap = b; }
   
   
public String hello()
    {
       
if (convertToCap) {
         
value = value.toUpperCase ();
       
}
       
return null;
   
}  
   
... ...
}   

Next, on the web page, add the following line to display the value property on the simpleAction component. Notice that code completion is supported for the JSF EL expression.



<p><b>Hello, #{simpleAction.value}</b></p> 

Finally, on the web page, we add a boolean selection box component. It is bound to the XXXX property on the backend component.



<h:selectBooleanCheckbox title="convertToCap"
  value="#{simpleAction.convertToCap}" /> 
Capitalize the input?

Deploy the application and see it in action now.

Add UI components and business logic

Figure 3.14. Add UI components and business logic

3.6. Add Security to the Application

You have probably noticed that the web page template has a login link at the top of the page. You can use the Seam security framework to secure access to any web page or web action. You can implement the login logic in the XXXX method. In the following example, we just use hardcoded username and password. But you can easily change it to use database, LDAP or any other means.

Then, on the action method, you can use the XXXX annotation to specify that it is only invoked by authenticated users.

Now, re-deploy the application and try the XXXX button. The application redirects to the XXXX page asking for login credentials. The method is invoked after you successfully logged in.

Access control for action methods

Figure 3.15. Access control for action methods

We can also secure web pages. You can edit the XXXX file to put an access constraint on the XXXXX page.



You can try to load the XXXX URL in the browser and it will redirect to ask for login.

3.7. Other relevant resources on the topic

Seam on JBoss: Seam Framework

Ten Good Reasons to use Seam: Why Seam

Getting Started: Getting Started with JBoss Seam

Wiki: JBoss Wiki

FAQ: JBoss Seam FAQ

Downloads: JBoss Seam Downloads

Jira: Jira issue tracker

Rules Framework: JBoss Rules