Fork me on GitHub

Session HTTP Server Tutorial

This tutorial demonstrates maintaining state within the HTTP session.

The example application for this tutorial will show a simple list of postings as follows:

SessionHttpServer screen shot.

Tutorial Source

Template.woof.html

The template for displaying the posts and adding posts is as follows:

<html>
	<body>
		<table border="1">
			<!-- ${posts -->
			<tr>
				<td>${text}</td>
			</tr>
			<!-- $} -->
		</table>
		<form action="#{post}" method="POST">
			<input name="text" type="text" />
			<input type="submit" value="Post" />
		</form>
	</body>
</html>

This is similar HTML as per previous tutorials.

@HttpSessionStateful

Session objects within WoOF are dependency injected. The following shows the @HttpSessionStateful annotation necessary to identify the dependency as a HTTP session bound object. Note HTTP session objects must also be serializable.

public class TemplateLogic {

	@HttpSessionStateful
	public static class Posts implements Serializable {
		private static final long serialVersionUID = 1L;

		private final List<Post> posts = new ArrayList<Post>();

		public void addPost(Post post) {
			this.posts.add(post);
		}

		public Post[] getPosts() {
			return this.posts.toArray(new Post[this.posts.size()]);
		}
	}

	@Data
	@HttpParameters
	public static class Post implements Serializable {
		private static final long serialVersionUID = 1L;

		private String text;
	}

	/**
	 * Provides values from the HTTP session.
	 * 
	 * @param posts {@link Posts} being the session bound object.
	 * @return {@link Posts} to contain values to render to page.
	 */
	public Posts getTemplateData(Posts posts) {
		return posts;
	}

	/**
	 * Handles the post form submission.
	 * 
	 * @param post  {@link Post} that is dependency injected with HTTP parameters
	 *              loaded onto it.
	 * @param posts {@link Posts} that is dependency injected from the HTTP session.
	 */
	public void post(Post post, Posts posts) {
		posts.addPost(post);
	}

}

WoOF will do the following:

  1. Check the HTTP Session to see if the object is previously bound. If so it uses the bound object.
  2. If not bound, the object is instantiated by its default constructor and bound to the HTTP Session. It is then used.

The dependency injection provides compile safe code without requiring to:

  • retrieve the object via a string identifier from the HTTP session
  • having to cast the object to its specific type

WoOF will provide a unique name based on the object's type to bind the object within the HTTP session. This can however be overridden by providing a name to the annotation.

Unit Test

WoOF again allows easy unit testing by it's dependency injection into methods:

	@Test
	public void testTemplateLogic() {

		Posts session = new Posts();

		TemplateLogic logic = new TemplateLogic();

		// Add post to session via template logic
		Post post = new Post();
		post.setText("Test post");
		logic.post(post, session);
		assertSame(post, session.getPosts()[0], "Ensure post added");

		// Ensure post provided from template logic
		assertSame(post, logic.getTemplateData(session).getPosts()[0], "Ensure post available");
	}

Next

The next tutorial looks at rendering generated HTML.