Forward Logo (image)       WebStringTemplates
      Previous Back Back Back Next

WebStringTemplates for the Programmer

Using WebStringTemplates in a new Servlet

This section assumes you are coding a new servlet to implement the Data Interface Definition file shown here and that you have a running servlet server and database as described on the previous page.

This page covers:-

Bookstore1Servlet - a first pass

As a first pass at implementing this servlet we will just load the template and the default data and output the web page. This checks that everything is in the correct path and that the Web Page Designer has done his job. The code for this first attempt is shown here. The code is in the serverExamples/bookstore1Servlet sub-directory.

The interesting bit of the code is

  public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {

    ServletContext application = getServletContext();

    // load the template 'bookstore.st' and the data 'bookstore.data' from
    //   the 'st' sub-directory of this application.
    // cache them both in a group called bookstoreGroup.
    WebStringTemplate wst = WebStringTemplateServer.getInstanceOf(application,
                    "bookstoreGroup", application.getRealPath("/") + "st", "bookstore");

    // set content-type header before accessing the Writer
    response.setContentType("text/html");
    // set the buffersize from the default data for this template
    response.setBufferSize(wst.getOutputBufferSize());

    PrintWriter out = response.getWriter();
    // then write the data of the response
    wst.write(out);
    out.close();
  }

WebStringTemplateServer.getInstanceOf( ) creates a group called "bookstoreGroup" if that group does not already exist in this application and loads the template and default data from the /st sub-directory of this application. These are both cached in the application. "bookstore" is the root name of both the template and the data file when using this version of getInstanceOf().

Note: When deploying a template and default data file, drop the .html from the end of the file names, so that bookstore.st.html becomes bookstore.st and bookstore.data.html becomes bookstore.data. WebStringTemplates insists on the template ending in .st and the default data file is often different from the Data Interface Definition file and so should not have the same name. For internationalization, it is your responsibility to request the appropriate template and data files. Another version of getInstanceOf() allows you to specify the data file directly for these cases.

Having loaded the template and data, generating the web page is as easy as
wst.write(out);

The only other notable bit of code is
response.setBufferSize(wst.getOutputBufferSize());
This sets the response buffersize from the value of the wst.outputBufferSize attribute in the default data, if there is one. Otherwise a size of 8192 is used. This allows you to tailor the buffersize used on a per-page basis by setting this attribute in the default data. See getOutputBufferSize() for details.

Debugging WebStringTemplates

Now that you have a simple example running let's look at the debugging features of WebStringTemplates.

Data Interface Definition

The first debugging feature outputs the template's attributes in a Data Interface Definition format. This is useful, both for checking what attributes have been set by your code, by the default data or by the servlet request, session etc, and as a quick start to writing a Data Interface Definition for the Web Page Designer.

To output the attributes instead of the processing the template, just set the template attribute, WebStringTemplate.OUTPUT_DATA_DEFINITION_FLAG ("wst.outputDataDefinition"), a non-false value. If the attribute has not been defined or is "0" or "false" then it is considered to be logically false. All other values make it logically true.

The sub-directory serverExamples/bookstore2Servlet, contains a modified version of the previous example. The following line has been added.

  wst.setAttribute(WebStringTemplate.OUTPUT_DATA_DEFINITION_FLAG,"true");
  // then write the data of the response
  wst.write(out);

When you load and run this servlet, using the url
http://localhost:8080/bookstore2Servlet/
the output page looks like this. Notice that all the data from the Data Interface Definition file, including the comments, has been included in the output.

Tip: When you add comments to the Data Interface Definition file, roll them back into your default data file as well so that the next time you need to update the Data Interface Definition file due to a server change, all the previous comments are already there.

ShowAll

You may have noticed the attribute wst.outputDataDefinition is not shown in the output. WebStringTemplates uses the following three methods to control which attributes, classes and methods to display:-

skipThisAttibute() - skips any invalid attribute names and any names which include '.', except comments which are output.
skipThisClass() - skips any class from javax.servlet, org.apache except org.apache.taglibs.standard.tag.common.sql.ResultImpl which is output.
skipThisMethod() - skips getOutputStream(), getInputStream(), getReader(), getWriter() and getClass()

You may need to modify the skipThisClass() method if you are using a servlet server not based on the Apache code. You can over-ride the effect of skipThisAttribute() and skipThisClass() by setting the attribute WebStringTemplate.OUTPUT_SHOW_ALL_FLAG to true.

Bookstore3Sevlet.java sets WebStringTemplates.OUTPUT_SHOW_ALL_FLAG to true and also adds the request object to the template under the key "servletRequest". When you call this servlet using http://localhost:8080/bookstore3Servlet/bookstore?item=3
you get an output page like this one. In this page as well as having all the default data, you can now see the settings for wst.outputDataDefinition and wst.outputDataDefinition.showAll (at the bottom of the output page). You can also see a lot of information about the HttpServletRequest object.

Since this object is not a String, Map or List, it is treated like a bean and introspection is used to find the available get*() and is*() methods and they are called to get an object which is then processed again recursively. The depth of this recursion is limited by the WebStringTemplate.OUTPUT_MAX_DEPTH attribute which defaults to 3 if it is not defined. When the level of recursion is reached the object.toString() is just returned.

At each level, when a 'bean' object is being processed, if .toString() returns something other then the default Object.toString() result, then this is shown as the overall string for this object. As shown for the book object is the output. If the Data Interface Definition file specifies an overall string, then you must ensure that a suitable string is returned by the object's .toString() method.

Handling Data Exceptions

If you scan down the output page, near the bottom you will find the servletRequest.session data. This is the result of calling the request.getSession() method. This method throw an exception. The exception was caught and returned as the result of this method. This is the string data the template would receive if it tried to access the data path $[servletRequest.session]$

Data Filters

To assist in debugging data filters, you can set the attribute WebStringTemplate.OUTPUT_SHOW_FILTERS_FLAG to true to see what filter was applied to each data item before it was returned. Uncommenting
wst.setAttribute(WebStringTemplate.OUTPUT_SHOW_FILTERS_FLAG,"true");
Bookstore3Servlet.java gives this output. Each attribute data is preceded by the class name of the WSTFilter that was applied to it. At the bottom this page you can see a table of the filter extension mappings for this template group.

Filter Output

This shows that the wst. attributes are being filtered using the default filter WSTXmlFilter, since no filter was specified.

Error Return for Missing Attributes

By default when deployed, WebStringTemplates will return an empty string if the attribute requested by the template is not in the map. For debugging you can call setMissingDataErrorPathReturn(true) to return the requested data path when an attribute is not found. This is the default setting in RunWST, which the Web Page Designer uses.

The Completed Servlet

The completed servlet is Bookstore4Servlet.java. Its url is http://localhost:8080/bookstore4Servlet/

This is only one page not a complete web site so the links don't go anywhere. It uses a support bean Book.java to hold the book details. In this simple example the database connection code has been included in the servlet, however in general you would have a separate class to handle the connection to the data base and lookup and initialization of the book details.

Note that the default data is used to supply the bookId of the featured book. This is an additional data attribute not used in previous examples.

String bookId = ""+wst.get("FeaturedBookId");

The default data is also to supply the urls for the links on the front page. These urls are extracted from the default data, rewritten to add any session details and stored back in the template data for inclusion in the output page.

wst.put("bookcatalogUrl",response.encodeURL(""+wst.get("bookcatalogUrl")));
wst.put("bookdetailsUrl",response.encodeURL(""+wst.get("bookdetailsUrl")));


Forward Logo (image)       WebStringTemplates
      Previous Back Back Back Next

Contact Forward Computing and Control by
©Copyright 2004 Forward Computing and Control Pty. Ltd. ACN 003 669 994