JEE Series: JavaServer Pages + JavaBeans and no web.xml

In this very first post of the JEE Series we create a simple web app based on JSP and JavaBeans. Bring an IDE of your choice and give it a swing.

Let's generate a new project using the maven web archetype:
 mvn archetype:generate -DgroupId=com.example \
      -DartifactId=simple-web-jsp \
      -DarchetypeArtifactId=maven-archetype-webapp \
      -Dpackage=com.example \
      -Dversion=1.0-SNAPSHOT  
Next, we are going to adjust the project layout and dependencies. If you are pressed for time or simply don't want to follow every subtle detail, here is the final version of the pom.xml file.

The properties below go to the pom.xml and provide elementary configuration, such as encoding, Java version and more importantly an optional deployment descriptor:
   <properties>  
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>  
     <maven.compiler.source>1.8</maven.compiler.source>  
     <maven.compiler.target>1.8</maven.compiler.target>  
     <failOnMissingWebXml>false</failOnMissingWebXml>      
   </properties>  
Next, we update project dependencies with the latest version of the Servlet API, since the app will run on Tomcat 8:
 <dependencies>  
     <dependency>  
       <groupId>javax.servlet</groupId>  
       <artifactId>javax.servlet-api</artifactId>  
       <version>3.1.0</version>  
       <scope>provided</scope>  
     </dependency>  
 </dependencies>  

The app showcases a simple form submission and works in the exact same way as the project described in the Netbean's tutorial:

The front-page provides a simple form.


The result page shows the submitted data (user name).
Before we delve into implementation details, please go and remove the WEB-INF directory. It contains a deployment descriptor (web.xml) which has no use in this project.

As you might expect there isn't much code to write. The data model follows the JavaBeans spec:
 public class NameHandler {  
   private String yourName;  
   public String getYourName() {  
     return yourName;  
   }  
   public void setYourName(String yourName) {  
     this.yourName = yourName;  
   }      
 }  
Simple as it looks, there is one gotcha worth mentioning. In sync with the spec, mutators (get / set) are mandatory. Skipping them would result into a failure even if the field was made directly accessible:
Apart from the Java class we obviously need the presentation layer. Let's create a new file called index.jsp and place it into the webapp folder:
 <%@page contentType="text/html" pageEncoding="UTF-8"%>  
 <!DOCTYPE html>  
 <html>  
   <head>  
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
     <title>Home Page</title>  
   </head>  
   <body>  
     <h1>Entry Form</h1>          
     <form name="SubmitYourName" action="response.jsp">  
        Enter your name:<input type="text" name="yourName">  
       <input type="submit" value="OK">  
     </form>  
   </body>  
 </html>  
Next, let's create the result page. Looking at the form's action, it comes as no surprise that the file is called response.jsp and resides in the same directory as the previous JSP file. This time however, we get to play with the useBean tag in order to connect the page to our JavaBean:
 <%@page contentType="text/html" pageEncoding="UTF-8"%>  
 <!DOCTYPE html>  
 <html>  
   <head>  
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
     <title>Response Page</title>  
   </head>  
   <body>  
     <jsp:useBean id="nameHandler"   
            scope="session"   
            class="org.zezutom.blog.series.jee.webjsp.NameHandler" />  
     <jsp:setProperty name="nameHandler" property="yourName" />      
     <h1>Hello <jsp:getProperty name="nameHandler" property="yourName" />!</h1>  
     <a href="index.jsp">Reset</a>  
   </body>  
 </html>  
Note that the bean is kept in the current session. I recommend reading this post, if you are curious about what other scopes can be used and how do they differ from each other.

Once we get hold of the bean, we have to initialise its properties. In our particular case we only deal with a single field called yourName. Now, I suggest you get back to the HTML form on the front page and check the input field. See the name of it? Yeah, it matches the bean's property, hence the minimal effort when using the setProperty tag: 
 <!-- Don't bother with specifying which request param to use -->  
 <jsp:setProperty name="nameHandler" property="yourName" />  
Now, suppose we submit the captured name as myName instead of yourName:
 <form name="SubmitYourName" action="response.jsp">  
    Enter your name:<input type="text" name="myName">  
    <input type="submit" value="OK">  
 </form>  
Then, on the result page, if we apply no changes we are bound to get a mismatch:
To solve the problem we HAVE to provide the request parameter name:
 <!-- Ehm.. In fact, yourName is myName you know? -->   
 <jsp:setProperty name="nameHandler" property="yourName" param="myName" />  
Okay, hope it's not too confusing. The getProperty tag is, on the other hand, very straightforward. It merely pulls the respective property value from the underlying Java bean.

That's it for today. We have a fully working application at this stage. Next time, we wrap it up by adding some test automation, so that we don't have to click around ourselves whenever a code change is made.

Feel free to check out the complete example from GitHub.