Dynamic Http Server Tutorial

This tutorial demonstrates the simplicity in creating dynamic content for a web application. This will illustrate the following:

The example used in this tutorial is the following simple dynamic page to show the current time and the listing of System properties:

DynamicHttpServer screenshot.

Download Tutorial Source

Template.html

WoOF considers the raw web page file to be a template. The below is the content of the Template.html.

<html>
	<body>
		<!-- {time} -->
		<p>Current time is ${time}</p>
		<table>
			<tr>
				<td>Name</td>
				<td>Value</td>
			</tr>
			<!-- {systemProperties} -->
			<tr>
				<td>${name}</td>
				<td>${value}</td>
			</tr>
			<!-- {endSystemProperties} -->
		</table>
	</body>
</html>

First thing to notice is that the template can be rendered in a web browser. The reason for this is to ensure that web page content can be created/edited by WYSIWYG web design tools. This is deliberate to allow web page designers to focus on presentation of the web pages rather than having to understand scripting tags and to an extent programming constructs. It also means the template can be viewed without having written any code - great for reviewing and tweeking the pages.

To provide the developer control of rendering the dynamic content, there are non-obtrusive hooks for dynamically rending of the page. The two hooks used in the above template are:

  • <!-- {section} --> : which delimits content of the template into sections. WoOF leaves the HTML to the most appropriate design tool and just focuses on segmenting it into sections to be managed by the developer's control logic. It is this focus that keeps WoOF simple and allows for the loosely coupled separation of roles between Web Page Designers and Developers.
  • ${name} : which substitutes dynamic values for rending to the page

The second hook just provides means to dynamically load bean property values from java classes into the page. The first hook however is the important aspect as it delimits the template into sections for dynamic rendering. The sections for the above template are:

  • template (default name of the first section as the template does not start with a delimiter)
  • time
  • systemProperties
  • endSystemProperties

The content of these sections is after the delimiter to the next delimiter, so for systemProperties it would be:

        <tr>
            <td>${name}</td>
            <td>${value}</td>
        </tr>

By default the sections are rendered in the order as provided in the template. There are means within the template logic class to skip sections, repeat sections and even execute the sections in completely different order. This however will be discussed in later tutorials, as the focus of this tutorial is to provide dynamic content onto the web page.

TemplateLogic Class

The TemplateLogic class is just a POJO (plain old java object) and has two methods that correspond to Template.html via naming conventions (method name is the template section name prefixed with get). These methods each return a POJO containing the property values for the particular template section's rendering. Only template sections containing a ${property} must have a corresponding getXxx() method (i.e. there is no getEndSystemProperties() method required).

To ensure integration between the Web Page Designer and Developer the bindings between the template and logic class are checked at start up so that missing section methods and properties are flagged immediately. It is these binding checks that allow the two roles to work efficiently together.

public class TemplateLogic {

	public Time getTime() {
		return new Time();
	}

	public Property[] getSystemProperties() {
		List<Property> properties = new LinkedList<Property>();
		for (String name : System.getProperties().stringPropertyNames()) {
			String value = System.getProperty(name);
			properties.add(new Property(name, value));
		}
		return properties.toArray(new Property[properties.size()]);
	}

}

The TemplateLogic class has been kept simple in this example returning static content. Other tutorials will demonstrate the use of dependency injection into methods to allow retrieving values from a HTTP session, database, etc but is beyond the scope of this tutorial.

The rendering of the template is as follows:

  1. A TemplateLogic instance is instantiated by its default constructor
  2. The template section of Template.html is rendered
  3. getTime() is reflectively invoked on the TemplateLogic instance returning the Time object
  4. The time section of Template.html is rendered replacing ${time} with the value returned from the above Time object's getTime() method
  5. getSystemProperties() is reflectively invoked on the TemplateLogic instance returning the Property array
  6. The systemProperties section content from Template.html is rendered for each Property instance within the above returned array. This repeating sections for arrays makes rendering tables simple within WoOF. The ${name}, ${value} are replaced with the corresponding bean properties from the current Property instance being rendered.
  7. The endSystemProperties section of Template.html is rendered

Each of the above steps is its own Task within OfficeFloor and are strung together and executed sequentially to render the dynamic web page. A Task is the basic functional unit within OfficeFloor. The order of Task execution can be altered along with having different threads executing each Task. This however is beyond the scope of this example which is to show dynamic content rendering through the conventions of a WoOF template.

application.woof

Now that the Template.html and TemplateLogic class are available, they need to be configured into the WoOF application. This configuration is within the application.woof file at the root of the class path (i.e. has no package prefix). Under the hood this is an XML file, however OfficeFloor has a strong focus on not hand coding XML configuration files. An Eclipse plug-ins provides the graphical configuration of an OfficeFloor web application.

The reason for using graphical configuration is two fold:

  1. XML configuration files are error prone and can become quite verbose making them difficult to manage
  2. Graphical configuration allows other less technically inclined to review the functionality of the web application

To use the graphical configuration of WoOF, please ensure you install the Eclipse plug-in. Details of installing can be found here.

Once the Eclipse plug-in is installed you will be able to use the new wizard (WoOF is typically under Other... and then OfficeFloor) to create the application.woof file. On creating and opening there should be a blank editor. Right clicking within the editor will bring up a context menu to add various items. Adding a template will bring up the following dialog box:

Dialog to add a template.

Adding the above information and clicking ok will add the template and result in the application.woof looking as follows:

application.woof configuration.

This is the only configuration necessary for this web application as the template will be made available at http://localhost:7878/example . Further tutorials will look at linking page flows and dynamic behaviour however is beyond the scope of this tutorial.

Remaining classes

The remaining classes are included below for completeness of the tutorial.

Time class

public class Time {

	public String getTime() {
		return SimpleDateFormat.getTimeInstance().format(
				new Date(System.currentTimeMillis()));
	}

}

Property class

public class Property {

	private String name;

	private String value;


	public Property(String name, String value) {
		this.name = name;
		this.value = value;
	}

	public String getName() {
		return this.name;
	}

	public String getValue() {
		return this.value;
	}

}

Unit Test

As the template logic is just a POJO, WoOF adheres to OfficeFloor's focus on simplicity in testing. The following example unit test shows the ease in which the TemplateLogic class can be unit tested.

	public void testTemplateLogic() {

		TemplateLogic logic = new TemplateLogic();

		assertEquals("Number of properties", System.getProperties()
				.size(), logic.getSystemProperties().length);

	}

Next

The next tutorial will look at an interactive page.