Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Hubert Klein Ikkink (aka Mr.Haki) - Communications Officer Dr.Bob's Kylix Kicks
 Mr.Haki's Expresso #2: InternetBeans Express
See Also: JBuilder Papers

InternetBeans Express
In the last article we have looked at the InternetBeans Express architecture. We have built our own bean and used it to display data. But displaying data is not the only thing we have to do in a web application. Most of the time our web applications will be interactive, which means the user can enter data in the web browser and send it to the server. We must be able to handle this data on the server. For example to put it in a database or make calculations.

The InternetBeans architecture lets us design our web application using the Model-View-Controller paradigm. In the last article we have seen the View part and in this article we will focus on the Model part. We will learn to build our own model for our web application.

The input
First we create a HTML page with input fields for username and password, because we want to build a simple login form. If we leave all the fancy stuff out we get the following HTML code:

  <html>
  <head><title>Login</title></head>
  <body>
  <form method="post" action="/servlet/com.drbob42.ibeans.Login">
  Username: <input type="text" name="username"><br>
  Password: <input type="password" name="password"><br>
  <input type="submit" value="Login" name="submitButton">
  </form>
  </body></html>

We simply have two input fields, username and password, and a submit button to send the contents to the server. The action parameter of the form is set to a new servlet: com.drbob42.ibeans.Login. We use the New servlet wizard from the Object gallery to create this servlet. We have to make sure we let the wizard create the doPost() method, because this method is invoked when the user submit's the form to the server. And in this method we will build code to handle the contents. We can see this process in more detail in the first article. We name the servlet com.drbob42.ibeans.Login for our example. It doesn't really matter what you name it, but make sure it is the same name as used in the action parameter of the HTML form tag.
Changed doGet() and doPost() methods:

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    loginPage.servletGet(this, request, response);
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    loginPage.servletPost(this, request, response);
    doGet(request, response);
  }
Next we couple the login page to a PageProducer component, and the associated controls to InternetBeans controls. Open the newly created servlet in Design mode and add a PageProducer component to the servlet. We rename this component to loginPage and use the htmlFile property to assign our login HTML page to the PageProducer component. We drop a IxTextField component, IxPassword component and IxSubmitButton component in the Designer. We name them respectively usernameTextField, passwordTextField and submitButton. We can set the pageProducer property of these components to our loginPage object. Then we select the correct controlName from the drop-down list to attach these components to the elements on the HTMl page. So the usernameTextField will be coupled with the input tag with the name username, passwordTextField to password and the submitButton object to the submitButton control on the HTML page.

Our template is now ready. All controls on the page are attached to InternetBeans Express objects in the servlet. Now we must make some changes in the servlet code to invoke the PageProducer object methods servletGet() and servletPost(). Remove all code in the method body from the doGet() and doPost() methods. Now add the the code loginPage.servletGet(this, request, response) in the doGet() method body and loginPage.servletPost(this, request, response) in the doPost() method body. This will make sure all requests are going through the IxPageProducer object and the necessary session management is performed.

The model
The JBuilder documentation contains an example for the InternetBeans Express components using datasets to communicate with a database. In our example we will not use this functionality (because we can read it in the documentation), but we will build our own model to handle the data. A model can be any object as long as it implements the interface com.borland.internetbeans.TupleModel. The tuple model can be assigned to the InternetBeans components using the setTupleModel() method. Now when we post the contents of the form to the server the servletPost() method of the loginPage object is invoked. This method will try to fill the model with values from the form. In our example that would be the username and password. Okay, so far for theory. Let's build a model object.

We start by creating a new class using File | New class... We name the class BasicModel to store the username and password entered by the user. We use a java.util.Hashmap to store values from the HTML form, named map. Now we can implement the interface. We select the Wizards menu and select the menu option Implement interface... JBuilder shows a dialog with all interfaces available in the class path of our project:

Implement interface

We must select the interface com.borland.internetbeans.TupleModel. We click the OK button to close the dialog. And when we return to the source code we notice a bunch of methods is added to the source. Each method body contains a dummy implementation which throws an UnsupportedOperationException. It is our task to write an implementation for these methods.

But where to start, because the TupleModel interface contains a lot of methods. We start by implementing the setString() and getString() methods. These methods are called to set the value from the input text fields in the model. And to get the value from the model again. We have two setString() methods: setString(int ordinal, String value) and setString(String columnName, String value). We must implement the method with the oridinal argument if we want to identify the data in the model by an ordinal number. If we want to identify the data by the name of a column we must implement the other method. We can of course also implement both methods. For now we write an implementation for the setString(String columnName, String value) method, and the getString() counterpart:

  public void setString(String columnName, String value) {
    map.put(columnName, value);
  }

  public String getString(String columnName) {
    return (String) map.get(columnName);
  }
Before we can test our model we need to implement one more method: replicate(). The replicate() is invoked by the servletPost() in the IxPageProdcucer class. The model is replicated to be put in a session, so different users don't get into each other's models. The replicate() method should make a copy of the model. For our example we keep things simple and only clone the object by invoking the clone() method on the model. We need to add the Cloneable interface to our implements statement at the top of the class. In the body of the replicate() method we add the following code:
    try {
      return (TupleModel) this.clone();
    } catch (CloneNotSupportedException cnse) {
      return null;
    }
We delete the method body of the other methods from the interface or return null if a return value other than void is required.

When we post the HTML form the IxPageProducer will invoke the setString() method to fill the data in the model. And when we build the page with doGet() the IxPageProducer component uses the getString() method to get the value. But not before we have included the BasicModel in our servlet. We create an instance of the object in the init() method and assign it to loginPage, usernameTextField and passwordTextField using the setTupleModel() method. Then we set the column names for usernameTextField and passwordTextField. We cannot use the JBuilder Designer for this, so we must add the following code in the jbInit() method:

    basicModel = new BasicModel();

    loginPage.setTupleModel(basicModel);

    passwordTextField.setTupleModel(basicModel);
    passwordTextField.setColumnName("password");

    usernameTextField.setTupleModel(basicModel);
    usernameTextField.setColumnName("username");
The model is now coupled to the elements in the HTML template file. After the servletPost() method we invoke doGet(), which will re-display the page again. And because the model is now coupled with the elements the values we have entered should be displayed on the screen. Run the application by right-clicking on the login.html file and select Web Run. Fill in a value for username and password and click the Submit button. The page is submitted to the server and returns with the values already filled in the form. It might seems nothing happened but when we take a look at the Web View Source tab we see the values are actually there.

Model Java source

Actions
Of course we want to do more than let the user enter data and return to the same page with the data filled in. We want to do something more. For example we want to check if the input fields are filled in before we can continue. To achieve this we are going to write a event handler for the submit button.

We open the Designer and select the submitButton object. We select the Events tab page in the Object Inspector. Here we see one event method: submitPerformed(). This method is invoked when the user presses the button and the data is posted to the server. A SubmitEvent object is passed to the method. This object contains get() method for the HttpServletRequest, HttpServletResponse and HttpSession objects, which are created by the servlet. We can use this object to get to the data entered in the form, set a response and of course the session, which contains are model.
First we validate the data entered from the form and check to see if it contains a value. If one of the fields is empty the user must return to the page, so the field can be filled in. If both fields are filled and contain the same value (of course in real-life we would check against a database) and the user goes to a next page. The submitPerformed() method will now look something like this:

  void submitButton_submitPerformed(SubmitEvent e) {
    BasicModel user = (BasicModel) loginPage.getSessionTupleModel(e.getSession());
    String username = user.getString("username").trim();
    String password = user.getString("password").trim();

    if ((!username.equals(""))
          && (!password.equals(""))
          && (username.equals(password))) {
      try {
          IxPageProducer nextPage = new IxPageProducer();
          nextPage.setHtmlFile("nextpage.html");
          nextPage.servletGet(this, e.getRequest(), e.getResponse());
        } catch (Exception ex) {
          ex.printStackTrace();
        }
    } else {
      try {
        doGet(e.getRequest(), e.getResponse());
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
  }
In this article we have take a look at how we can create our own models to work with InternetBeansExpress. Next time we will look at the JSP 1.1 custom tag library support with InternetBeansExpress.


This webpage © 1997-2010 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.