Rational Application Development certification prep, Part 3: Web development

The Rational® Application Developer for WebSphere® Software Web development tutorial is the third tutorial in a series of seven tutorials created to help you prepare for the IBM Certification Test 255, Developing with IBM Rational Application Developer for WebSphere Software V6. Learn how to create a J2EE 1.4 Web application using Rational Application Developer 6. The application you create is in the form of Model-View-Controller (MVC). Step through how to create a controller servlet and a model servlet, which includes your business logic. Then take a look at using JavaServer Pages (JSPs) for the View, including both an HTML input form and the HTML output from the server. Next you can experiment with using a JavaBean to help with the business logic. Pick up techniques for forwarding between server-side components, creating server-side dynamic data that returns to the user's browser, configuring the XML files that are required by J2EE, and testing with WebSphere Application Server 6.

Gregory L. Scott (glscott1@us.ibm.com), Senior Learning Specialist, IBM

Greg is an instructor in private and public national settings, internal and external to IBM, primarily related to Java client-side and server-side (J2EE) programming. Specializations include servlets, JSPs, EnterpriseJavaBeans, portlets, XML, and Web Services.



14 March 2006

Before you start

About this series

Rational Application Developer for WebSphere Software is the IBM Software Development Platform that allows you to quickly design, develop, analyze, test, profile and deploy Web, Web services, Java, J2EE, and portal applications. This series of seven tutorials helps you prepare to take the IBM certification Test 255, Developing with IBM Rational Application Developer for WebSphere Software V6 to become an IBM Certified Associate Developer. This certification targets entry level developers and is intended for new adopters of IBM Rational Web Developer or IBM Rational Application Developer for WebSphere Software V6.0, specifically professionals and students entering into Web development using IBM products.

About this tutorial

Learn you how to create two servlets and two JSPs and integrate them into a unified Web application. It then explores issues related to aliasing (URL mapping), passing JavaBeans from one part of the Web application to another, using Javascript and Model-View-Controller (MVC). It also examines some of the problems with creating multiple Web applications and sharing classes with respect to classpaths and JAR dependencies.

Objectives

In this tutorial you create a first vertical slice (a basic version of the application that runs from start to finish) of a potentially much larger Web application. The slice includes all the major fundamental components of a J2EE 1.4 Model-View-Controller application. After you complete this tutorial, you should understand how those components -- servlets, JSPs, JavaBeans, and deployment descriptors -- fit together and how Application Developer can facilitate the whole process.

Prerequisites

This tutorial assumes intermediate Java™ skills, at least with respect to J2SE. J2EE understanding is helpful, but not essential. Moreover, it assumes you have gone through the two previous tutorials in this series or have equivalent knowledge with Rational Application Developer.

System requirements

To run the examples in this tutorial, you need to install Rational Application Developer for WebSphere Software or Rational Web Developer for WebSphere Software. You can download a free trial version of Rational Application Developer for WebSphere Software if you don't already have a copy of it.

The hardware and software requirements for this software can be located at IBM Rational Application Developer System Requirements.


Creating and testing ControllerServlet

The first step is to create a servlet and then to test it.

Step 1: Starting the tool

Before beginning, ensure that the -showlocation flag is included with the Rational Application Developer (hereafter Application Developer) startup command. This causes Rational Application Developer to display on the title bar the location on your hard drive in which the files are being saved. In other words, it shows the location of the workspace.

  1. To add the flag:
    1. Right-click the Application Developer icon if you have it on your desktop. (Otherwise, create the shortcut icon by using Windows Explorer, locate the rationalsdp.exe file -- in my setup it is C:\Program Files\IBM\Rational\SDP\6.0\rationalsdp.exe -- and right-click the file.)
    2. Choose Properties and add -showlocation after the Target path, as follows, then click OK:
      Figure 1. Properties
      Properties
  2. Double-click the icon and in the Workspace Launcher window, change the workspace manually to C:\WebTutorial (this assumes the directory does not exist, otherwise it is advisable to use Browse to select the directory), and click OK.
  3. Once Application Developer is open, notice C:\WebTutorial is now showing at the top bar.
  4. If the Welcome pane is showing, click the X to close it.

Step 2: Creating the Enterprise and Web applications

Using Application Developer for the development of Web applications allows you to take advantage of the full J2EE programming and assembly model. The top-level component (what developers write) of a J2EE-compliant application is the enterprise application. Enterprise applications physically exist (or get exported from Application Developer) as EAR files in the file system. EAR files are used to deploy and install applications on application servers. Within Application Developer, an enterprise application is an enterprise application project.

Once you have your enterprise application project, create a Web module that contains your servlets and JSPs (along with any related JavaBeans and HTML files, including resources like gifs). The Web module is stored physically as a WAR file, and within Application Developer is represented by a Web module project. The Web module is associated with an enterprise application (which may have zero to many Web modules), and any WAR file gets included as part of an EAR when deploying an enterprise application.

  1. Select File > New > Enterprise Application Project (or under Project Explorer, right-click Enterprise Application > New > Enterprise Application Project).
  2. Type in First as the name of the project and click Show Advanced to look at the default options: notice the project will be published to WebSphere Application Server 6. Click Next.
  3. In the EAR Module Projects box, click New Module. Uncheck the boxes for the three other kinds of projects that you can create under an EAR (because leaving one checked but unimplemented may cause the server not to start when you start testing), and leave the default name for the Web module, as follows:
    Figure 2. New module project
    New Module Project
  4. Click Finish two times. You can now examine what WebSphere Application Server created. If you are in a perspective (such as J2EE) other than Web (as indicated by the top bar, top left), click the Open Perspective icon (top right), and choose Web. Under Project Explorer, expand Enterprise Applications and Dynamic Web Projects. Yours should look like this:
    Figure 3. Web perspective and Project Explorer view
    Web perspective and Project Explorer view
  5. Notice that Enterprise Application First has a Deployment Descriptor (saved as application.xml); likewise, FirstWeb has a Deployment Descriptor (which points to the web.xml under WEB-INF). Double-click each in turn to open and examine them. Close both.

Step 3: Creating the servlet using the wizard

  1. Create a package to hold the Java servlet. Under FirstWeb > Java Resources, right-click JavaSource, and choose New > Package. Use the name ourservlets and click Finish.
  2. Right-click ourservlets and choose New > Other. Expand Web and select Servlet. Click Next, and give the name ControllerServlet. Notice the URL Mapping gets the same name automatically. Click Next.
  3. In the next box, click Browse next to Java Package (some of the other wizards in Application Developer will have the package filled in automatically if it had been selected beforehand), and choose ourservlets. It should look like this:
    Figure 4. Create servlet
    Create Servlet
  4. Click either Next to see the final options for the servlet creation (but leave defaults) or Finish.
  5. Double-click ControllerServlet (under ourservlets) to open the source code in the editor. Notice the two primary methods that you should implement: doGet(req, resp) and doPost(req, resp). You can click the triangles in the left margin, to fold the text if you wish it hidden.
  6. The doPost(req, resp) is called if an HTTP POST method had been invoked (which is standard with an HTML form); the doGet(req, resp) if a GET method (which is the HTTP default). You'll create an HTML form later. Let's handle the possibility that a user submits the request with a GET no matter whether a form is used or not. (Rather than using a form, which invokes the doPost method in the servlet, a browser user could add the corresponding query string onto a URL, for example, http://mysite.com/index.html?lastname=Jones, which would cause the doGet method to get invoked instead.) Thus, we'll simply transfer control to the doPost(req, resp) and have our implementation there.
  7. In doGet(req, resp) type the following: doPost(arg0, arg1);
  8. In doPost(req, resp), type the following or copy and paste from the solution that you can get from the Download section at the end of this tutorial. Of course, the HTML code is not very complete for a true business application but is sufficient for testing purpose.
    PrintWriter out = arg1.getWriter();
    out.print("<html><h1>Hello World, from DeveloperWorks!</h1></html>");
  9. If needed, add the import statement "import java.io.PrintWriter.". Save the code (CTRL-s is probably the fastest way) and test it by running it on the server, as described here: Depending on what you have done beforehand, there are a few ways of running a Web application or a servlet. For the sake of familiarity, follow option (iii) below, but read (i) and (ii) first:
    1. Right-click the servlet itself (in this case ControllerServlet), and choose Run > Run on Server if that is an option (make sure you right-click the servlet with a J next to it, not the one underneath the expanded servlet with the same name that has a C to the left of it). If Run on Server is not a choice, go to the bytecode version of the source (that Application Developer has created and managed for you), click Web Content > WEB-INF > classes > ourservlets > ControllerServlet.class, right-click the servlet and choose Run > Run on Server.
    2. Alternatively, you can right-click the Web project and choose Run > Run on Server and you will be asked for the server. Accept the default and check the box Set server as project default, as follows in Figure 5 (again, there is no need for you to do this now because you will start the server using a different procedure). Examine the other settings for setting up the server with Next or Finish. Your project is published, and the first file in its Welcome list, index.html (under Pages of the Deployment Descriptor, as shown in Figure 6 below) is run. If you did not create that index.html file, you get an error. However, the server is started and you can follow the instructions in (i) above to start the servlet itself.
      Figure 5. Server selection
      Server Selection
      Figure 6. Pages of the Web Deployment Descriptor
      Web Deployment Descriptor
    3. The third way of running your Web application is to right-click Application Server 6 (probably now stopped), and choose Add and Remove Projects in the Servers view in the bottom right pane. Add the available project to the Configured Projects as follows, and click Finish.
      Figure 7. Add and remove projects
      Add and Remove Projects
      Immediately the server status shows Starting. When it finally starts, right-click the servlet as in the first option (i) above.
  10. You should see the results of your ControllerServlet, as follows (in a moment, the tutorial explains why the screen shot shows Control in the URL rather than ControllerServlet, which you should have):
    Figure 8. Output in Web browser
    Output in Web Browser
    What happened precisely when you chose Run on Server?
    1. Application Developer not only published the servlet as part of an .ear to WebSphere Application Server 6, but opened up a Web browser (in your case, an instance of Internet Explorer with some of the controls of a full browser), typed in the URL for you, and simulated pressing Enter.
    2. The GET HTTP request was sent to the application server on port 9080, the default for the Application Developer installation with WebSphere Application Server 6 (you can change it to port 80 in the server's admin console). WebSphere Application Server itself converted the HTTP request into a Java request object (along with a Java response object that has, for instance, the address back to the browser), and -- through a service() method that you did not have to touch -- the two Java objects got passed into the doGet(req, resp) method of your servlet.
  11. You might not like the fact that the URL shows the real name of the class file, giving potential hackers undue information. Let's create an alias, then, for the servlet:
    1. Open the Deployment Descriptor (hereafter, dd) under FirstWeb by double-clicking it. You can make the change under the Servlets tab > URL Mapping section, or under Source, as in the following screen shot.
    2. Change the URL Mapping to Control and save and close the dd (which, again, is identical to the web.xml file).
    3. Retest by right-clicking on the servlet and choose Run > Run on Server. Notice how the URL changed.
      Figure 9. The Alias in the Deployment Descriptor
      Alias in the Deployment Descriptor

Congratulations! You have just written and tested your first J2EE servlet (which functions as a Controller and also, for good or bad, as the View, the presentation that the end-user sees for input or output).


Creating a model servlet manually

Normally, you would not want business logic in your first controller servlet. Eventually, you would have that logic in your Model, which could be comprised of other servlets, JavaBeans (or other Java classes) or Enterprise JavaBeans. Let's create a second servlet without using the wizard to see other options using Application Developer, and to practice forwarding from one servlet to another.

Step 1: Creating and testing ModelServlet

  1. Right-click ControllerServlet and choose Copy. In the same package, right-click and choose Paste. A NameConflict box appears as the tool tries to create a duplicate servlet. Change the name to ModelServlet, then open up that servlet and notice how the class name was changed, along with the constructor.
  2. Edit the doPost(req, resp) of ModelServlet so that the HTML is slightly different, to prove that our response when you test is not merely a cached Web page. For instance, the print statement might be:
    out.print("<html><h1>Hello World, from ModelServlet!</h1></html>");

    Make sure to save the file.
  3. Revise ControllerServlet to forward to ModelServlet: replace the code in ControllerServlet's doPost(req, resp) to:
    getServletContext().getRequestDispatcher("ModelServlet").forward(arg0,arg1);

    Notice a warning now that the import java.io.PrintWriter is not used. Expand the import section, if necessary, and delete the offending import statement. Save the file.
  4. Test the ControllerServlet as in Step 1 above. What happens? You get a 404 error, like this:
    Figure 10. 404 error
    404 Error
  5. Can you guess why? Click the Console tab in the bottom right pane to see what other error messages you might see. Notice below that the program got into the ControllerServlet but then the console output stops -- the application server never entered the ModelServlet.
    Figure 11. Console view
    Console View
    The answer? Not using the wizard to create the ModelServlet means the servlet never got listed in the web.xml file (and servlets must be noted in that deployment descriptor to be recognized and used by the Web container). Let's add the servlet manually to web.xml.

Step 2: Editing the deployment descriptor

  1. Open the FirstWeb deployment descriptor, and click the Servlets tab. Under Servlets and JSPs, click Add. Type the name ModelServlet, check Use an existing servlet and click Browse. Now, start entering Model, by which time the tool will have selected the ModelServlet for you. Click Finish. Save the file, and the ModelServlet is now added to the web.xml. (Confirm that the URL-Mapping was filled in for you, because if it is blank, you need to manually add it.)
  2. Re-run ControllerServlet and the correct display should return (and the console will show that ModelServlet was initialized successfully).
  3. You now have two (extremely thin) servlets working: your Controller and your servlet for business logic. Before you implement any business logic itself, however, let's take care of a problem: the servlet is also pushing out HMTL (part of the View) to the browser, which is not good for two reasons:
    1. In a more realistic project, there would be many tedious statements of the form: out.print("<someHTMLtag></someHTMLtag>");
    2. The Java editor cannot check your HTML syntax at compile time, if the syntax is a String argument.
  4. JSPs offer an easier approach in terms of development because you can dispense with the out.print("<SomeHtmlTag>text</SomeHtmlTag>"); code and because Page Designer can check HTML syntax at compile time. (Because JSPs are just a subclass of servlets, strictly speaking, there is typically no significant performance difference between the two).
  5. Before going on to JSPs, you might wish to explore other views in the deployment descriptor that is probably still open, but be careful about making changes. Please close it when finished.

Creating Output.jsp: The view

To create Output.jsp:

  1. In the Project Explorer view, under FirstWeb > Web Content > WEB-INF, create a folder called jsp. By putting the folder under WEB-INF (for Web Infrastructure) you are protecting it: only our server-side resources, like servlets, can access it, not external browsers. (If you want to allow external users access, as you will later for the input form, create the folder or file directly under Web Content.)
  2. Right-click WEB-INF and choose New > Folder. Name the folder jsp and click Finish.
  3. Using the icon as shown below in Figure 12, or File > New > JSP File, or right-clicking on the jsp folder and choosing New > Other > JSP file, start creating the JSP.
    Figure 12. JSP icon
    JSP icon
    Name the JSP file InitialOutput. Either click Finish or check Configure Advanced Options to examine the other possibilities (but leave the defaults) and click Finish.
  4. You should see the JSP open automatically in the Page Designer, probably in Design view. Click the Source and Preview tabs to see the other views. Also notice the Palette on the right, showing different JSP tags you can drag and drop (along with the menu options at the top pertaining to JSPs).
    Figure 13. JSP editor
    JSP editor
  5. Notice also in the lower left pane the Outline view (if need be, click the chevron to make Outline appear in the list).
    Figure 14. Outline view
    Outline view
  6. You can work in different modes in the editor. Let's work in Design mode. Replace the text "Place content here." with something like Customer Information, leaving the cursor on the same line. Click on the Properties view in the bottom-right pane. The Paragraph option should be showing. Change the Type to H1 and the alignment to Center. Your text gets modified according, as shown below.
    Figure 15. Properties view
    Properties view
  7. Perhaps surprisingly, the text is blue. Why? If you re-examine the JSP code you will see: <LINK href="../../theme/Master.css" rel="stylesheet" type="text/css"> and if you open the Master.css file (under Web Content > theme) you will see the Cascading StyleSheet settings for H1. You can change them if you want a different color, font, or style in general.
  8. Now move the HTML code from the ModelServlet to the JSP, and forward control from ModelServlet to the JSP: In ModelServlet's doPost(req, resp), cut the existing <H1>Hello World, from ModelServlet!</H1> and paste it into the JSP, below the Customer Information text. (Pasting like this is best if you use Source mode. If you paste while in Design mode, you get a so-called entity in lieu of the opening tag, which is easily corrected.) Change the text in the JSP to something more logical, like Hello World, from the JSP.
    Save the file. Back in the doPost(req, resp) of ModelServlet, replace any remaining code with the following:
    System.out.println("In the doPost() of ModelServlet, 
        before forwarding to the JSP");
    getServletContext().getRequestDispatcher("/WEB-INF/jsp/InitialOutput.jsp").forward
        (arg0, arg1);
  9. The new code in doPost(req, resp) needs some explanation. First, notice you are printing to the server's console in the System.out statement (this will show in the Console view when you run the application). Second, notice that the argument indicating the path (in the getRequestDispatcher method) ignores (and must ignore) the Web Content folder. Why? Because only the files under the Web Content folder itself ultimately become part of the .war file that gets exported to the production server. Therefore, also because the jsp file was not included in the web.xml, you have no alias for it and must forward to it using a legitimate path name: the slash (/) means go to the root (in this case the Web application root, namely, FirstWeb).
  10. Save all files if need be, make sure no Problems exist, and test again, starting with ControllerServlet. The output should be as shown:
    Figure 16. Web browser output from JSP
    browser output from JSP
  11. At this point, your vertical slice is almost completely implemented, with MVC: one servlet for the controller, one for some business logic (the model), and the JSP for the view. In the next part, you will add more to the View by creating a page that allows the user to fill in an HTML form, which our ModelServlet can then process (with the business logic that you will subsequently add).

Adding to the View: Creating Input.jsp

To accept data from the user, use an HTML page or a JSP. One advantage of using HTML is that it is static and can be served from a Web server rather than an application server (although the latter typically provides more security against hacking attempts to deface it because it usually sits behind an additional firewall). One advantage of using a JSP is that you can include dynamic messages in case of a problem, so that you can reuse the same JSP if, for example, the user forgot to enter a required field. Javascript on the client side is typically used to validate fields before the HTTP request is allowed to continue to the Web/application server, but sometimes federal or company guidelines do not allow the use of Javascript and other times end users turn it off. Servlet filters on the application server provide another option for validating data before an incomplete (Java) request object reaches the servlet, but this is an advanced feature beyond the scope of this tutorial. We will handle the problem of incomplete, required information in our servlet.

Create an input JSP to reuse with a dynamic message in case a required field is empty. To insure syntax gets checked at compile time, double-check under Window > Preferences > Validation that your HTML and JSP validators are turned on (they may be off in a default installation of Application Developer), as such:

Figure 17. Window > Preferences > Validation screen
winprefs validation screen
  1. Because the input form must be reachable to external browsers, do not put it under the WEB-INF directory. Rather, right-click the Web Content folder under FirstWeb and choose New > Folder. Name it externaljsp.
  2. Right-click the externaljsp folder and select New > JSP File. Name it Input and click Finish.
  3. As you did before, replace Put contents here. with a more logical heading, such as Determine Your Status (because the application you now develop, for the sake of simplicity, tells the users what their status is, be it Gold or Platinum). Use Properties if you wish to center the heading and make it larger, as follows:
    Figure 18. Input.jsp title -- Properties
    Input.jsp title -- Properties
  4. Create three text fields, one each for a lastname, account number, and age.
  5. Under the Palette column on the right-hand side of the editor, click the HTML Tags option, as shown:
    Figure 19. HTML tags options
    HTML tags options
  6. Click the Table sub-option, place the cursor in the editor pane where you want the table code to be (presumably under your heading and at your left margin) and click again. The Insert Table box appears. Change the number of rows to 4 and leave the columns at 2. Change any of the other properties if you want, or edit them later in the Properties view, in the right-lower pane. Your editor should look something like this:
    Figure 20. Properties -- Table cell selected
    Table cell selected

    Notice that you were placed by default in the first cell (TD in Properties). To edit the various part of the table, put the cursor in different parts of the source code, for example, on the Table tag to show the Table settings rather than the TD settings. You can play with these if you want.
  7. Leave the default DATA selected. You do not need a table header, therefore, do not click the radio button HEADER for "Cell Type". That changes <TD> to <TH>. Fill in the cells so that your screen matches what's shown here:
    Top left cell:  Please enter your lastname:
    Second left cell from top: Your account number:

    (and click the Color rectangle in Properties, at the far right of the view, and choose Red or whatever color you want so the middle left cell gets a color)
    Third left cell from top: Your age:
  8. At this point, you realize you hastily created the table without first creating the form that should contain it (an HTML form has a submit button and so forth). No problem. Simply add the correct tags now. Either click Form Tags in the Palette view and drop the Form element onto the page above the table (in which case you would go into Source view and move the </FORM> tag below the end-table tag) or type manually in the Source view. On the latter option, type <FORM> in front of the table, but rather than type the corresponding end tag after the end-table, press CRTL-spacebar. Notice </FORM> is the first option, so click Enter and your end-tag gets written for you! Isn't Page Designer nice?
  9. Now that the table is in the form, create three text (input) fields. Create the first as follows, then simply repeat in the other cells. Go into Design mode. Under the Palette pane section called Form Tags, click Text Field and click inside the top right cell to generate the Insert Text Field box. Type in lastname as the name, and change the number of columns from 20 to 50.
    Click OK.
    Repeat for the next two cells, using the following values:
    Second right cell from top --
    name: acctnum; columns: 9; max length: 9
    Third right cell from top -- name: age; columns: 3; Initial value: 99
  10. In a bottom cell, create the Submit button by first clicking Submit Button under Form Tags, and clicking again in the bottom cell. Type in submit as the name (which is a convention) and give it the value Get your status! Your form should look like this:
    Figure 21. Table
    Table
    and the source code like this:
    Figure 22. Table source code
    Table source code
  11. Change the code, if required, in the Source or use your Properties boxes. You still need some values (namely, ACTION and METHOD) for the FORM tags. Click anywhere within the FORM tag in Source mode, and notice the relevant Properties, as displayed in the following screenshot:
    Figure 23. Properties for Form tag (assumes cursor is within Form tag)
    Properties for Form tag
  12. Click the radio button for method POST and notice how the source code is written for you. Click the folder icon next to the Action text field and select Servlet from the popup menu. From the Select Servlet box, select ControllerServlet. Notice again how the tool writes the HTML code for you, and knows to use the alias for ControllerServlet (that is, the URL mapping from web.xml).
  13. To anticipate reusing the jsp, in case the user ignores the required field and your servlet needs to return the jsp to the user with a message (preferably in good taste!), insert the following code immediately before the <FORM> tag. You will understand it better when you use setAttribute() in a servlet later. It uses a scriptlet tag and an expression tag.
    <%
    String msg = (String)request.getAttribute("yourPoliteMessage");
    if (msg == null) { msg = ";}
    %>
    <H3 align="center"><FONT color="purple"><%= msg %></FONT></H3>
  14. Save the file and test it by right-clicking Input.jsp under externaljsp, and choosing Run > Run on Server (if your server was stopped it will be automatically started). You have not implemented any code in your servlets yet to handle either the polite message or the HTML parameters. In this context, a parameter means a key-value pair coming from the HTML form: the key comes from the name of the input element and the value from the user input, so name=lastname in your HTML form means lastname is the key and whatever surname the user types into the text field will be the value. Thus, for the moment, you are only testing to see if the action tag works correctly: without filling in any text field, click the submit button. The output should be exactly as it was before when you tested the InitialOutput.jsp.

Now a razor-thin vertical slice of your first Web application works, starting from the input jsp to the two servlets to the output jsp.


Implementing the business logic in ModelServlet and refining the View

In a more sophisticated Web application, the input form would probably have a group of options that the user could select from: get status, update information, get a balance and so forth. The ControllerServlet would check to see what parameter on this group had been selected, and then (perhaps with if-else statements) forward to a particular servlet or Java class that took care of the business logic. With many options in an HTML form, the design issues can begin getting quite cumbersome, and hence the Struts framework was developed (to be described more later). At this stage, though, just let the ControllerServlet pass control to the ModelServlet and have it determine the status of the user (typically, through a query to a database).

Step 1: Implementing the business logic

  1. In the doPost(req, resp) of ModelServlet, replace the System.out.print() line with the following, which confirms that the user entered an account number and, if not, returns the Input.jsp page a second time, which itself will now have your polite error message (although if you wish to be impolite for once no one will care!).
    String acctnum = arg0.getParameter("acctnum");
    if (acctnum != null) {  // insure HTML name of textfield is correct
      if (acctnum.length() == 0) {  //insure user entered value
      String message = "The account number is required.";
                    
      arg0.setAttribute("yourPoliteMessage", message);
                                                    
      getServletContext().getRequestDispatcher("/externaljsp/Input.jsp").forward
         (arg0, arg1);
      return;
     }
  2. Save the file, and test the Input.jsp by entering an account number and then retest by omitting it (if you reach InitialOutput.jsp, use the Back button on the internal browser to return to the Input.jsp rather than invoking Run on Server from the popup menu). Both options, inputting a number or not, should work properly.
  3. Notice that you just used getParameter() to retrieve information from the HTML form. On the other hand, you use setAttribute() on the Java request object (namely, arg0) to fatten up that same request object with your own Java objects -- not primitives! -- created on the server side. Forward that ever-so-popular request object to the JSP, which can then extract object data with, in this case, getAttribute("yourPoliteMessage").
  4. In a real-life project, you might write JDBC code to extract the relevant information for the account number, and in the next tutorial in this series, which pertains to the Data perspective(#4), you are shown those steps using these servlets and JSPs. For simplicity here, pretend to get the information from a database.

    At the end of doPost(req, resp) in ModelServlet, immediately before the line getServletContext.getRequestDispatcher().forward(arg0, arg1);" insert the following comments and code:

    // If you reach here, the acctnum field had a value.
    // Simulate going to database, retrieving information based on account number:
    // Normally, JDBC code or a call to the database layer would be here.
    // For simplicity, mimic the database call, returning status and balance.
                
                String status;
                if ((acctnum.length()) % 2 == 0 ) {status = "Gold";}
                else {status = "Platinum";}
                double balance = (10000)*Math.random();

    The code in your method should look like this:

    Figure 24. ModelServlet doPost method
    ModelServlet doPost
  5. Now that you have simulated retrieving information from a database, you stuff that information into a Customer Java Bean, which you create in the next section. Java Beans can be used for any number of reasons in a web application: for providing modular logic, for layering, or for providing a convenient bucket to hold data that is easily passed along to another component, like a jsp.

Step 2: Creating a Customer bean

  1. Under FirstWeb > Java Resources, select JavaSource and then right-click. Choose New > Package. Name it pojobeans (for Plain Old Java Object beans).
  2. Select pojobeans, right-click and choose New > Class. Name it Customer and then click Add next to Interfaces. You will want the Customer class to implement Serializable, but you only need to start typing ser to encourage the tool to find your interface for you. Your screen should look like this:
    Figure 25. Implemented Interfaces screen
    Implemented Interfaces screen

    Make sure the default package (java.io) is the one you want (it is in this case), and click OK. The Customer class gets created and opened in the editor.

  3. You will now create the properties of the bean (which are attributes that have either public getters or setters or both). Define two instance variables in the bean as follows:
    private String status;
    private double balance;
  4. Right-click anywhere in the Java class source, and choose Source > Generate getters and setters. Click Select All, and all the accessor methods for status and balance get checked. Click OK, and save your Customer bean. Naturally, you could add properties in the bean corresponding to the parameters from the HTML page (lastname, acctnum, and age). Then you could use your request.getParameter("lastname") to get the value for the lastname and, as you see in the next section, to set it into the Customer bean. However, to shorten this tutorial, use the two properties status and balance. Close the Customer bean.

Step 3: Using the Customer bean in ModelServlet

  1. You can now stuff data into the Customer bean. After the line double balance = (10000)*Math.random(); insert the following code:
    Customer cust = new Customer();

    Notice the red error icon in the editor's left margin, overlapping the light bulb that offers suggestions. The class cannot be resolved (because there is no import statement). Simply right-click the light bulb (or the error message itself under the bottom right view called Problems) and choose QuickFix. Choose the first choice to import the class. Save your file and the error indicators disappear.
  2. On the next lines, add the following code:
    cust.setStatus(status);
    cust.setBalance(balance);
    arg0.setAttribute("customer", cust);

    Then format your code with CTRL-SHIFT-f or right-click the source code and choose Source > Format. It should look like this:

    Figure 26. Source code
    Source code
  3. Save the file. You should have no errors.

Step 4: Refining the InitialOutput.jsp to send back the status and balance

Modify the InitialOutput JSP to display the results to the user.

  1. Open the file (under WEB-INF/jsp) if it is not already displaying the source code.
  2. Change the text between the <TITLE>...</TITLE> tags to something more logical (than InitialOutput.jsp), for example, Status and Balance.
  3. Either delete the Hello World line of code, or simply add the following code after it.
  4. As you have seen already, you can type code directly in Source mode (which is sometimes faster) or use the JSP Tags buttons while in Design mode. In Source mode, type <% and notice how the tool finishes the %> for you. Add the following to the scriptlet, and then complete the rest of the HTML code, including the JSP expression:
    <%
    String lname = request.getParameter("lastname");
     %>
    <P>Following are the results for:  <%= lname %><BR>
    </P>
  5. This will echo back the user's lastname. Save the file, and then run Input.jsp, typing in a lastname before submitting. (Note that you can go back and forth from the JSP source code to the browser, using the back button; there is no need to right-click on the jsp and choose Run on Server. Nor is there a need to restart the server when making changes to the JSP.) You should see the lastname returned properly.
  6. Now extract data from the Customer bean. In Design mode while in the InitialOutput.jsp, click JSP Tags > Bean, and click below the code you just entered in the previous two paragraphs.
  7. In the Insert JSP Bean box, type customer for the ID, choose request for Scope and for Type > Browse > from Project. In the Class Selection box that appears, start typing custom at which point the pojobeans.Customer shows. Accept it and click OK.
  8. On the next line, type Your balance is : .
  9. Click JSP Tags > Get Property and click in the editor next to the line you just typed.
  10. In the Insert JSP Get Property box, scroll down to customer, expand it and select balance. Notice all the fields get filled in.
  11. Click OK, and your source code view should be similar to this:
    Figure 27. JSP useBean code
    JSP useBean code
  12. Make sure to save the file. Test the Input.jsp again. You should see a result with many decimal places for the balance, as follows:
    Figure 28. One possible result from testing Input.jsp
    One possible result
  13. To show another option for outputting dynamic information, format the balance for dollar currency. Type import="java.text.*"in the JSP directive (the tag at the top of the page beginning <%@), right before "%>." This import will allow your code completion key (Ctrl-spacebar) to work as you are typing in long method names. Now, insert the following after the useBean and getProperty tags you wrote a minute ago.
    Your tidier balance is:
    <%
    String balanceString = ";
    double balance = customer.getBalance();
    NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
    balanceString = currencyFormatter.format(balance);
    out.print(balanceString);
    %>
    <BR>
  14. Save and test Input.jsp again. You should see the formatted version with the dollar sign in front. (Those wanting currencies from other countries can modify the NumberFormat code slightly to use the Locale option, as explained in the Java API reference.)

Step 5: Using the J2EE 1.4 Expression Language (EL)

  1. In this section, you will use an easy example of the new Expression Language, which is supported by J2EE 1.4. It enables quick access to data in beans, with additional advantages such as empty strings being returned rather than NullPointerExceptions if users do not add data. Below the code you just wrote, add:
    <%-- The following uses the Expression Language, which is a new feature of J2EE 
    1.4) --%>
    <BR>Your status is: ${customer.status}
    </P>
  2. Because you had used useBean to create the customer object in your JSP, you won't really appreciate what the new EL does if you have not worked with it before: when working solely with EL syntax, you do not need to type the useBean tag. The EL searches the page, request, session, and application objects in order for (in our example) a key called customer and, if finds it, returns it. No import statement or useBean statement required! Then, in the case at hand -- ${customer.status} -- it looks for the getStatus() of the customer object to return the property called status.
  3. Save and test Input.jsp again, inputting values for lastname and acctnum (again, we do not use the age parameter in this tutorial). You should see a result similar to this:
    Figure 29. Formatted result
    Formatted result

Step 6: Validating a required text field with Javascript in Input.jsp

  1. You might be thinking now, "If the user forgets to type in a required account number, the server will have done some unnecessary processing." You will probably wish, then, to insure that for browsers with Javascript enabled, the accountnum field has a value. We often call this validating a field. Verification of the value against the database must be done, of course, on the server side. Browsers that disabled Javascript will have the error caught by our servlets, as before. Use Javascript to validate the input form.
  2. In Input.jsp, between the <head></head> tags that occur before <body>, type in or copy from the solution these two functions:
    <script language="javascript" type="text/javascript" >
     
    function validate_required(field,alerttxt)
    {
    if ((field.value == ") || (field == null))
    {
    alert(alerttxt);
    return false
    }
    else {return true}
    }
     
    function validate_form(thisform)
    {
    if (validate_required(thisform.acctnum,"Your account number must be filled 
    out!")== false)
    {
    thisform.acctnum.focus();
    return false
    }
    else 
    {
    return true
    }  
    }
    </script>
  3. In the beginning form tag (<FORM>), add:
    onSubmit="return validate_form(this)"

    Your code should look like this:
    <FORM action="/FirstWeb/Control" method="post" onSubmit="return 
    validate_form(this)">
  4. Try testing the page with and without an account number, and notice the alert box that pops up in the latter case because of the line {alert(alerttxt);return false}, as follows:
    Figure 30. Javascript alert
    Javascript alert

Using tags: JavaServer Pages Standard Tag Library (JSTL)

One potential problem with JSPs is that, especially in a large project involving HTML specialists who help create and maintain the HTML and JSPs, too much Java code will obscure the JSP. Also, the modularity of MVC may be diminished. Hence, tags were developed to move functionality into libraries that are easier to reuse. You will use some of the JSTL tags in this section to format the tidier currency you implemented above and to provide a date.

Step 1: Formatting the balance as currency

  1. Recall the code to format the currency output:
    <BR>Your tidier balance is:
    <%
    String balanceString = ";
    double balance = customer.getBalance();
    NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
    balanceString = currencyFormatter.format(balance);
    out.print(balanceString);
    %>
    <BR>
  2. Simplify this by first deleting the whole scriptlet (but keep <BR>Your tidier balance is:). Then, with your cursor after the one line you kept, click the menu item JSP > Insert Custom. The following window opens:
    Figure 31. Insert custom tag
    Insert custom tag
  3. Click Add and choose the tag library ending with jsp/jstl/fmt (not the one only ending com/jstl/fmt).
    Figure 32. Select tag library options
    Select tag library options
  4. Click OK and select the formatNumber tag, as below:
    Figure 33. Insert custom tag: formatNumber
    Insert custom tag
  5. Click Insert and Close. You should now see in your JSP source code:
    <BR>Your tidier balance is:
    <fmt:formatNumber></fmt:formatNumber>
    <BR>

    If you look at the top of the JSP, a taglib directive with the correct fmt prefix.
  6. Within the opening <fmt:formatNumber> start typing va then press Ctrl-spacebar and choose value. Fill in with your EL statement to get the customer's balance and add the type as currency, as follows:
    <fmt:formatNumber value="${customer.balance}" type="currency">
  7. Save the document and then test it (by running Input.jsp). You should see the same tidy output as before. The one simple tag (and two attributes) is much shorter and clearer to read than the five lines of scriptlet Java code that it replaced.

Step 2: Using a date tag

  1. Because you have already imported the JSTL formatting library, you can quickly add a date. Other possible tag libraries in JSTL deal with core structures like iteration or looping, database calls, and so forth, for which one can get a superficial understanding by looking at JSP > Insert Custom and examining the related descriptions.
  2. Place your cursor in the InitialOutput.jsp right before </BODY>, and type Today is:<BR>.
  3. Create a date object by typing: <jsp:useBean id="now" class="java.util.Date""/>
  4. Click from the menu JSP > Insert Custom and select formatDate, then Insert. You should see the following in your source code of the JSP:
    <fmt:formatDate value="></fmt:formatDate>
  5. Fill in the value as ${now}, and add a dateStyle attribute of full, as such: <fmt:formatDate value="${now}"dateStyle="full"></fmt:formatDate>
  6. You could, naturally, have simply printed the date object now in an expression, as <%= now %>, but the JSTL tag gives you easier options to control the type of formatting.
  7. Save the file, which should look like this:
    Figure 34. Source code: formatDate tag
    Source code: formatDate tag
  8. Test the page again. You should see something like:
    Figure 35. Results using JSTL tags
    Results using JSTL tags

Congratulations again! You have now finished a basic MVC application; seen ways to create servlets and modify the deployment descriptor properties in the web.xml; determined how to create JSPs and to display information using scriptlets, expressions, <jsp:useBean> tags, and the Expression Language, and how to allow information to be passed easily around the whole application with a JavaBean. You have also employed some Javascript and a couple of JSTL tags.


Some issues pertaining to classpath dependencies

You have proceeded in a natural fashion to develop incrementally a Web application. Nevertheless, there are some other issues that you might wish to be aware of before proceeding with significantly more complex projects.

Step 1: Creating a second Web application and classpath dependencies

Create another Web application, SecondWeb, that works with the one created earlier in the tutorial (FirstWeb). The second application also uses the pojobeans.Customer class. Now examine how both Web applications can use the Customer class.

  1. While in the Web perspective, right-click Dynamic Web Projects in the Project Explorer, and choose New > Project > Web > Dynamic Web Project. Click Next.
  2. In the New Dynamic Web box, type SecondWeb as the Name, making sure to change the EAR project to First, and shorten the Context Root to Second, as follows:
    Figure 36. New Dynamic Web project
    New Dynamic Web project
  3. Click Next to see the following two screens (but please leave the defaults) or immediately click Finish.
  4. Right-click in the Project Explorer on SecondWeb > Java Resources > JavaSource and choose New > Package. Name it common.
  5. Right-click common and choose New > Other > Servlet.
  6. In the next box, name the servlet Subsidiary, and click Next. Browse for the package common. Click Next to look at final options (but please leave the defaults) or click Finish.
  7. In the doGet(req, resp) of Subsidiary, replace the line of code:
    "// TODO Auto-generated method stub"

    with the following:
    Customer cust = new Customer();

    You will see an error that Customer cannot be resolved. Why? Because the class exists in another Web application, which, like a compartment in a submarine, is kept separate from the current Web application and which, accordingly, can fail in that other application without causing the current application to fail.

  8. You might think that you need to put the classpath of FirstWeb in your project. That is a prudent thought. Thus, select SecondWeb in the Project Explorer, and right-click. Choose Properties > Java Build Path > Projects.
  9. Check FirstWeb and click OK.
  10. If the error is not automatically fixed, click the light bulb in the Java code editor, and select Import. . .Customer. The import statement is written for you, as such:
    Figure 37. Subsidiary servlet
    Subsidiary servlet
  11. In the Subsidiary.java class, add the next two lines of code below the Customer constructor:
    PrintWriter out = arg1.getWriter();
    out.print("<html>" + cust + " is the memory address of the custobj</html>");
  12. Test the servlet by right-clicking under SecondWeb > WebContent > WEB-INF > classes > common > Subsidiary and choosing Run on Server. What happens? You get this error:
    Figure 38. 500 error
    500 error

    Why? If you look at the Console, you get a hint:


    Figure 39. Console error message
    Console error message

    The runtime cannot find the Customer class (the Java Build Path you set only helped the compiler). You'll correct this problem in the next section.

Step 2: Creating a shared JAR the application level

You have two choices now: copy the Customer class (and package) into SecondWeb, and re-do the import statement, or move the Customer class into a Java project and use a utility module at the application level to make it available to both Web applications as a JAR file. There are advantages and disadvantages to both: sometimes JAR files, if changed in all Web applications, have adverse effects on existing code in one of the applications, whereas, if possible, it is nice to have all the code for the Customer class in one, and only one, location, for the sake of maintainability. Because you already know how to create packages or to copy files, and because it is trivial to put a JAR into the lib directory under WEB-INF (where JARs for a Web application belong) create a utility module.

  1. Click File > Project > Java Project.
  2. Click Next. Name the Java Project SharedLibraries as follows:
    Figure 40. New Java project
    New Java project
  3. Click Next to see the next screen (accept all the defaults) or simply Finish.
  4. If you get prompted to switch to the Java perspective, click Yes. Otherwise, open your Java perspective by going to the icon for opening perspectives in the upper right corner.
  5. In the Java perspective, expand the FirstWeb project in Project Explorer. Select the pojobeans package, then right-click and select Refactor > Move, as shown here:
    Figure 41. Refactoring
    Refactoring
  6. Choose SharedLibraries in the list and click OK. You should now have about six errors and warnings because the classes in FirstWeb can no longer find pojobeans.Customer.
  7. Return to your Web perspective. In the Project Explorer, expand Enterprise Applications, then expand First.
  8. Double-click Deployment Descriptor to open the application.xml file (it will say Application Deployment Descriptor).
  9. Click the Module tab and scroll down if necessary: click the Add button under Project Utility JARs. Select SharedLibraries and then click Finish. You should see this:
    Figure 42. Creating a project utility JAR
    Creating a project utility
  10. Save the Deployment Descriptor (dd). You can view the other tabs/views. Notice under Source that only the two WAR files are listed. The Project Utility is NOT listed (nor should it be). Close the dd.
  11. Make the SharedLibraries.jar available to FirstWeb. Select FirstWeb, right-click and choose Properties > Java JAR Dependencies, then check SharedLibraries.jar as below:
    Figure 43. Properties: Java JAR dependencies
    Properties: Java JAR dependencies
  12. Click OK. Notice that, after a few seconds, the problems all disappear. If you test Input.jsp immediately you may get a 500 error, in which case, you would restart the server in Start mode (not Profile or Debug) by right-clicking on Servers and using the popup menu, or by using the stop and start icon of the Servers view (as shown in the screenshot below).
    Figure 44. Stopping and restarting the server
    Stopping and restarting the server
  13. When the server is running, test Input.jsp and FirstWeb should work correctly.
  14. Make SharedLibraries.jar available to SecondWeb in the same way: select it in Project Explorer, right-click. Choose Properties > Java JAR Dependencies and check SharedLibraries, then OK.
  15. Test the Subsidiary servlet now by going to SecondWeb > WebContent > WEB-INF > classes > common > Subsidiary, right-click it and choose Run on Server. You should get output similar to the following.
    Figure 45. Test of Subsidiary servlet
    Test of Subsidiary servlet
  16. To see one of the advantages of the Project Utility, go to the SharedLibraries project (not JAR) and double-click pojobeans.Customer. In the editor, add the following instance variable:
    private String newString = 
                                     "This was added after Java JAR dependency set"; 
  17. Right-click anywhere in the editor and choose Source > Generate Getters and Setters, as such:
    Figure 46. Generate Getters and Setters
    Generate Getters and Setters
  18. Click Select All, as below, then OK:
    Figure 47. Select all
    Select all

    Notice the new accessor methods in your code. Now test to see that both Web applications can employ the new methods (and new instance variable newString) by adding the following bit of code.

  19. Add the following immediately before the </BODY> of InitialOutput.jsp in FirstWeb:
    <BR>
    Your new string is: ${customer.newString}
  20. Save the file and test FirstWeb by running Input.jsp on server. You should see something like:
    Figure 48. Testing Input.jsp of FirstWeb
    Testing Input.jsp of FirstWeb

    The jsp picked up the new change in the JAR file that was made in the Customer class (note you did not have to manually update the Project Utility jar!). Isn't Application Developer accommodating?

  21. Do a similar test in SecondWeb: In the Subsidiary servlet, replace the out.print(. . .) of doGet(req, resp) with:
    out.print("<html>" + cust.getNewString() + " : is your new string </html>");
  22. Run Subsidiary on the server. You should see the following:
    Figure 49. Testing Subsidiary servlet of SecondWeb
    Testing Subsidiary servlet of SecondWeb

    Your second Web application also picked up the change to the Customer class. You could continue modifying Customer (without deleting required functionality in the Web applications) and let Application Developer automatically update the JAR, and both Web applications would be able to avail themselves of the changes.


Conclusion

At this point, you have explored various issues with classpaths, the Enterprise Application's deployment descriptor, and utility JAR files and dependencies. You are now ready for more advanced tutorials, such as working with session objects or with servlet filters. You are also ready for an examination of Struts and JSF, if they interest you.

Struts is a way of, among other things, helping you build a complex Web site, that might involve dozens of pages, with complicated rules for navigating. Find links to more information and tutorials in Resources.

JSF offers a rich user interface experience in a Web application setting, more in line with Swing GUIs. For a tutorial and more information see the Resources section.

You are now finished with Tutorial 3, and deserve a refreshing beverage along with a backstretch. Please consider trying Tutorial 4, on the Data perspective, which continues with the artifacts you created here. It adds JDBC code to connect to tables in the Cloudscape database that comes with Application Developer. You set up the database and create the tables.


Download

DescriptionNameSize
Solution code for this tutorialFirst.ear13KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Rational software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational, DevOps
ArticleID=105583
ArticleTitle=Rational Application Development certification prep, Part 3: Web development
publish-date=03142006