HierarchicalMap Tutorial - Advanced Level
HierarchicalMap is an interface. So anyone can implement it. This tutorial is based on BasicHierarchicalmap, a reference implementation of HierarchicalMap.
Following subjects are covered in this tutorial:
Advanced Level14. Writing Application
Now, let us mix everything up. In this chapter, we will create a web application based on Tomcat (could be any other Servlet Container).
We assume that there is model like below, presented at "Accessing Data Base" tutorial, implemented on your data base server.
First, create a web project using your prefered IDE.
or Using Netbeans:
Then, start creating an html form as shown:
To do so, create a file like below, name it "BookForm.html" and place it under WebContent/template on your project.
Remember to use same charset all over your project. On the example above, we are using UTF-8, but it could be any other charset like ISO-8559-1.
Now, create a Servlet named BookForm and add the following code:
Note that ScriptCollection and Script are both from org.dhmp.util.stylesheet.
The content of WebContent/WEB-INF/web.xml should be like following:
Finally, make sure that dhmp.jar (containing HierarchicalMap classes) and xercesImpl.jar are visible to Tomcat.
Place them under WebContent/WEB-INF/lib, or $CATALINA_HOME/lib,
or some other directory and reference the latter directory using shared.loader
entry on $CATALINA_HOME/conf/catalina.properties.
Launch Tomcat under debug option, or standalone after deploying the war file, and check the result, calling http://localhost:8080/Application/BookForm.
Now, add a method, which is shown next, to convert parametetr to a HierarchicalMap and check the value returned when the BookForm is submitted.
Before proceeding, the application must check the input parameter provided by user. Put in mind that the form's parameter will be used to insert records into database table. Therefore, we will define all the constraints using xml schema as follows: (review the Runtime Schema Validation tutorial)
Create the insert_book.xsd with above content and place it under WebContent/xsd. Note that the elements are presented in exactly same order and type as defined in stored procedure's parameters.
Now, change the servlet code as follows. Run it and see the returning HierarchicalMap value (sqlparam).
First, add two more static attrributes. One is SchemaCollection schemas, and the other is Schema schema. Then, alter init() method as code shown next:
Also change the doPost() method as follows:
Try several combination of input parameter for the form, submit them and see the content of sqlparam HierarchicalMap. Note the difference when form content attend all the requirement defined in schema document, and when it does not fullfill the constraints.
The rule behind this functionality is: when an element does not meet the constraint, an error node "_error" with the error message is appended at the node that contains the element. And "_focus" leaf with key associated to the first element, which does not satisfy the constraint, is added to the root. Ok, it is bit confusing, but we could not find an easier solution at the moment. We are looking forward to receive your suggestion to make this simpler.
Presenting Error Message
Next step is to present the validation error message on the form.
Alter the BookForm.html adding some substitution elements. Basically, we are adding a place to present error message and also defining a value for elements.
One more thing, there is also a tip to handle focus setting. Unfortunately, html's id can not have "/", so it should be a simple name and must be identical to the last portion of element's name.
To present the error message after validation, modify the code on doPost() method as below:
So far, the Servlet is producing a ordinal html file. We will improve its functionality to insert new record on database when fillout the form and submit it.
Make sure that stored procedure insert_book, of Accessing Data Base tutorial has created on your database. Then, configure your Tomcat to recognize the database. In this example, we are using c3p0 as connection pool and Postgres as database Place the c3p0's jar file and Postgres's jdbc jar file on the same directory where xercesImpl.jar is placed. Then, create a WebContent/META-INF/context.xml with following content:
Then, alter the WebContent/WEB-INF/web.xml adding resource-ref as follow:
At last, change the doPost() method as described below:
For this part, we will use the list_book stored procedure mentioned at "Acessing DataBase" tutorial.
Prepare an html template as below and put it at WebContent/template/BookListFrom.html.
Create a new Servlet named BookListForm, with following methods:
Now, call http://localhost:8080/Application/BookListForm and see the result.
Everything is working fine, though we want to remove all the stored procedure's specific treatment out of our java code. For that, we will introduce a new class: SQLSchema.
Prepare a new XML Schema as follows:
Note that there is a new element "ext:sql". This is an extension for defining SQL specific information.
Placed at the top level, right under schema element, we can define the SQL statement, which can be retrieved using SQLSchema class.
Placed at the element, we can define the direction of the parameter, that can be "out", "inout" or "in" ("in" is default and can be omitted). And also the SQL type of the "out" parameter. The type must be defined using the integer value as defined in java.sql.Types (1111 of above XML schema corresponds to java.sql.Types.OTHER).
The BookListForm servlet, can be changed as below:
Well, see next the brief explanation of what is happening with the code above.
In the init() method, we are loading the XML schema document into list_book_schema. Note that this time, we are instantiating SQLSchema passing the retrieved Schema to its constructor. Also observe that we are not calling setAddErrorMessage method. This is because the stored procedure does not have input parameters, thus we are no longer interested in validating the input parameter.
Look at doPost() method. Now, we are retrieving SQL Statement defined in XML schema and passing it to MapSQLStatement, and just calling schema's transform() method to create a HierarchicalMap containing the output parameter as specified by schema document.
Most of things presented here are ordinal servlet programming under Tomcat.
In essence, following steps should be taken for writing application using HierarchicalMap: