Home   Development   Download   Resources   FAQ   Tabkit  
Web Framework

Single-Page Application (SPA) is emerging as the preferred way to build modern web applications. SPAs are based on fragments. Trap is a framework that provides a set of features for encapsulating fragments. It enables you to develop a fragment as you would a regular page.

Trap complements server-side and client-side (e.g. Angular JS) technologies. Developers use the same programming style they are used to.


There are only two core components: Trap and Latch.


A Trap is a fragment in a page. It has a begin and end tag. Examples in this page (the blue boxes) are traps. Click View Code to see the JSP.

Hello World! This is a trap.

Traps can be placed within another trap. This page is itself a trap. View Code for this page.

Fill and Drain

The heart of the Trap framework is a mechanism we call Fill and Drain.

Concept 1
Fill and drain is to fragments as request and response is to pages.

Fill and drain are wrappers around AJAX calls (you do not make AJAX calls directly). It will be explained further later.



Traps have Latches. Latches initiates fill and drain. It is an action and a listener.

Show content ↓ ← Latch (submits the request)

In addition to inserting content into a fragment, there are two other patterns: Chain and ScriptService.



You can chain fill and drain calls together. In this example one fragment makes a fill request to another.

Concept 2
Chaining is to fragments as redirecting is to pages.


ScriptService is a Trap whose content is Javascript (instead of HTML). They perform the same function as web services.

Four ways to fetch data (from a server) and update the view. View the source to see the difference.
  1.     A server-side approach (redraw this line).
  2.     A traditional web service.
  3.   .


We described Trap as a fragment framework. However, fragments resides within containers. You can also think of Trap as a container framework. In fact, the main reason for choosing the Trap framework is its ability to build containers.

We call containers in Trap Bolt Templates (this will be explained later).

Bolt Templates

Embedding a fragment is straightforward — you just include it. However, as you will see from the following examples, you will often need to decorate the fragment with HTML and Javascript. Bolt Templates help you do this.

A bolt template is a combination of:

The concept will become clearer after a few examples.

  1. STEP AND LADDER — A bolt template to place a fragment multiple time in a collection.
    • All the update code is in the line fragment. Each line is a JSP.
    • Each line has a pop-up. You can embed bolt templates within bolt templates.
    user1   Edit
    user2   Edit
    user3   Edit
    user4   Edit
    user5   Edit
  2. Tabkit — A bolt template for loading fragments (tab body pages) based on patterns in the URL. This is typically referred to as a Router. It is our most advanced bolt template.

What are Bolt Templates?

Bolt templates are containers embedded in the page. Why use a container to mount a fragment when you can manually "glue" the fragments to the page? The reason you want to use a bolt templates is because they are reusable. They also hide complexity. The fragment developer does not have to know how they work to use them.

We call them bolt because they help you "bolt" a fragment to the page. We call them templates because they will often have a JSP template component.

How Containers Simplify Development

Developers use the Trap framework in two distinct ways: to build containers or to build fragments. Container developers have to understand how Trap works. However, fragment developers do not.

You only need a few members of your team to understand how to build containers. Furthermore, there are prebuilt ones.

Case Study — KeyHole: A Container for a Pop-up

Pop-ups are common in web applications. They will typically have two views: an open view and a closed view. For example, a closed view is an address and the open view has inputs to update the address.

Pop-ups will typically have a lot of glue code. For example, the two views have to communicate with each other through a shared parameters (e.g. 'postal_code').

Ideally, we would like to have the bottom view and the top view together on one page. The combination would be an if/else page. Example: if (isOpen()){...}else if (isClose()){...}.

We have a container for this. The if/else page is called a KeyPage. The bolt template is called Keyhole. The developer on the main page embed keyholes. The pop-up developer can use client-side or server-side technologies to communicate between the sections. They bolt templates enables you to treat it as an if/else page.

Bolt Summary

See resources for more bolt templates.

Part 1: How Trap Works

Fill and Drain — Under the Hood

Request  →  Respond with page  →  Trim to fragment  →  Insert
Concept 3
The Trap framework processes the entire page to build the fragment. Every trap in this page is processed this way.


Embedding a fragment is simple — you just include it. Fill and drain works seamlessly in the background.

Server-side + Client-side Containers

Concept 4
Fill and drain enables you to use both server-side and client-side containers.

Bolt Template — Under the Hood

Fragments are just includes. For example, a pop-up fragment is just an included JSP. Of course the pop-up would not look correct if you just included it. We have to add a border and put it in a new layer. Bolt templates help you do this. They decorate the fragment to create the illusion of a pop-up.

Request  →  Respond with page  →  Trim to fragment  →  Add decoration  →  Insert

Bolt templates can be very complex (see Tabkit). However, the mechanism is always the same. They inject Javascript around a fragment.


  1. FILL AND DRAIN — Fragments are trimmed from a full page.
  2. BOLT TEMPLATE — Fragment are decorated with Javascript and embedded into the page.

Server-side Container Security

One benefit of having server-side containers is that you do not have to need additional security mechanism.

Take pop-up as an example. A typical scenario would be to redirect the user to a login screen if the user is not logged in. You may have to build a mechanism to do this for an AJAX call. However, you do not need do this with Trap because the pop-up is actually an include. Because the page is secure, Any action in the pop-up will send the user to the login screen (because Trap processes the entire page). After signing in, it will open the pop-up automatically.

Concept 5
Fragments use the same security model as the page.

Because Trap processes the entire page, the security model is determined by the position of containers in the page.

Deep Linking

Most single-page application framework have problems with search engines because content is inserted instead with script. One solution is to generate a separate site for crawlers. Example: prerender.io

Trap can generate a static site on the fly. How? Remember that Trap is a server-side framework. It can serve regular pages. Bolt templates creates the illusion it is a single-page application. Trap is able to turn off bolt templates when the request is from a crawler.

See Tabkit for an example. Tabkit inserts the tab body with AJAX for users. However, it uses regular includes when the request is from a search engine.

Making single-page applications searchable is a challenge. Trap automatically implements Google's recommendation for making AJAX applications crawlable.

Web Service

Web service in this section refers to calls made within your application. It does not refer to public APIs.

No JSON. No Endpoints.

Typical SPA Development will comprise of making web service calls to fetch JSON. You can do this in a Trap application. However, you will most likely not need to.

Trap enables you to treat a fragment as a virtual page. Fill reloads the fragment as submit reloads the page. You did not need to use web service or JSON in old multi-page web development. For example, instead of using a JSON of a user's account, you just use the account itself.

Page Variables

Trap manages state with Page Variables. Page variables keep their values for the life of the page. There are five page variables. They all start with the letter M:   NInteger NBoolean NString NLong

Page variables behave differently depending on how you create them. There are a three ways:

* Trap converts Page variables to PageTransient variables if HTML 5 local storage is not available.

For the most part, you use page variables as you would regular Java variables. View the code in the following example.

Page Seed and Managed Objects

Traps, latches, and page variables are Managed objects. All managed objects have unique names. Each trap JSP is contained within a TrapPage container. Each TrapPage has a unique seed. Managed object names are generated by appending a counter to this seed.

Seed Prefix

As mentioned before seed must be unique for each JSP. However, you may need to include the same page more than once. To ensure that the seed is unique. Include the page with a Seed Prefix.

One example is Tabkit. Each tab sets a seed prefix when it loads the tab body. You can insert the same fragment on two different tabs and they will each retain their state. The pop-up and repeater bolt template will also set a seed prefix.

You need to know the reason behind seed prefix, however, you will almost never have to set seed prefix yourself. It is almost always set by a bolt template when it includes your page.

Note that Trap will throw an error if it detects a duplicate page seed.


Trap pages (JSP) are portable. You can embed the fragment page elsewhere and they will usually work. This means that you can build and test fragments in isolation. You then assemble your main application with tested fragments.


Part 2: The API


A large part of the API is for building containers. Fragment developers will rarely use them. Developers need to know the core concept. However, they will spend most of their time learning how to use specific containers. The best way to learn how to use a container is to modify the JSP examples.

Key Pieces

TrapPage TrapPage is the main context of the container. It construct trap objects with unique names. Each JSP will typically get one. Containers will often extends this interface (e.g. KeyPage and TabPage).
Trap Trap is a fragment of a page.
Latch Latch is an event in a fragment. Latches are created from a Trap. It updates the trap it belongs to.
Fill Fill is the mechanism for calling a latch (i.e. invoking an event). Fill belongs to a Latch.

Trap.begin()   Trap.end()

These methods define the fragment. They return a div (default) or a span tag with a unique id.


You handle events within the doFill() block of a Latch. See any examples for details.



Fill is the event mechaism of a Trap framework. It is a wrapper around a jQuery AJAX call.

Fill is to a fragment as Submit is to a page.

Typical usage:

<a href="javascript:void(0);" onclick="<%=latch.fill()%>">redraw</a>

In this example, the implicit toString() method of the Fill object returns Javascript to make the request.

The FillJs Javascript object enables you to use Fill in Javascript. You create it with fillJs().

Typical usage:

See AngularJs for a fillJs() example.

Configuring Fill

You can configure fill on the server and on the client.

Server (Java):

latch.fill().param("key", "value").vr(new String[]{"var1", "var2"})

Client (Javascript):

fillJs .param('key','value') .vr(['var1', 'var2'])

The takeaway is that you can build fill with a combination of server-side and client-side calls.

Fill parameters can only be read by the latch that created the request.


You respond to the fill request with Drain. Possible actions:

  1. Do nothing. The default action is to redraw the fragment (with any updates).
  2. Inject Javascript before/after redraw. For example: update a tab and scroll right.
  3. Chain another fill call. The fragment is redrawn and another fill is triggered. This is analogous to a redirect.
  4. Return Javascript only. The Javascript will get executed. The fragment is not redrawn.
  5. Return text (e.g. JSON). The fragment is not redrawn.
Drain for a fragment is equivalent to Response for a page.

Injecting Javascript

Injecting Javascript is at the heart of the container mechanism. You can inject (decorate) fill and drain call with Javascript.

  Before After
Fill Script is executed before submitting the fill request.

This is fairly common scenario.
You may add functions to .done() and .always(). Rarely used.
Drain Script is executed before releasing the content. An example would be to fade away content before you remove it (by inserting nothing). Javascript is executed within the 'always' function of a jQuery deferred object. An example would be to update content and scroll.

This is the most common scenario.

Other Script Injection Points


Use trap.next() to create unique repeatable names. Note: the order you use this call must be consistent over the page load and fill cycles. Treat .next() as you would a managed object.

The value from .next() is valid for a Javascript variable or function name. We use this feature extensively when building bolt templates.


Developer will use Trap: to build fragments or to build containers. To provide developers with a comfortable experience, we organize methods that we feel developers should not use when building fragments into a WholePage object.

An approach we have used is to use WholePage anywhere initially. We would then refactor it out into a bolt template.

Hash Path

You can set one string with a friendly name in the hash part of the URL. This is the Hash Path. Example:


The hash path is /tab_1/tab_2.

Hash path must start with /. Regular anchors such as <a name="#section2"/> must not start with /.

Trap adds an exclamation mark to the hash path: http://example.com/#!/tab-1?abc=123. This indicates that search engines should index the URL. It will not add an exclamation mark to hash URLs with parameters only: http://example.com/#?abc=123.

You will probably use a container such as Tabkit to deal with hash path.

Note that parameters on the URL are separate from parameters on the hash. Example:

History Redraw Area

Browser history — especially the back button — is the bane of web developers. Trap detects hash URL changes and pushes redraw code onto the browser's history stack. On popstate (i.e. going back or forth) it restores the state; sets the scroll position; and updates the URL.

The redraw code redraws the History Redraw Area with AJAX. This area is typically the root trap for the entire page (i.e. a full page redraw). However, you can redefine it to be something smaller. For example, you can place an upload progress bar outside the history region. Back and forth on the page will not affect the upload progress.

Managing browser history can be complicated. Trap does it automatically.

Note that Trap redraws with the area with the latest state.

History Redraw Area is our implementation of handling browser history. You may use another implementation.


Page Load Errors

We implemented an error handler to embed errors in the page (but let the rest of the page proceed). You can turn this off or use your own implementation. Errors during the fill cycle should be handled within the fragment JSP.


Use redirectTo(url) to go to another page. This call works in PageLoad and Fill.

Calling redirect will tell Trap to skip all further page includes. You may write return; after if you like. We strongly recommend that you do not abort with return; anywhere else.

Best Practices

  1. Split development into containers and fragments. Create reusable containers.
  2. Do not place code that changes state (e.g. database calls) in the open. Only place them:
    • On page load — Inside a TrapPage.isPageLoad() block.
    • In response to specific action — Inside a Latch.doFill() block.
  3. Avoid using hash variables. Hash variables have global scope because they are in the URL (i.e. all fragments have access to them).
  4. Define the start and end of your trap first. A common error is to start a trap but not end it.
  5. Don't escape in the page with return;.
  6. Do not use the prefix _trap_ for Javascript and HTML names.


Most of the examples in this page handles fill requests with a series of if/else statements. You can also register a FillHandler. See latch for a comparison.

Show content ↓ ← Latch (submits the request)


fill.callServer(false) enables you to abort submitting to the server. For example, you can pass in a script that returns false if something else is still working.

Important. Aborting the call to the server does not halt injected scripts. This feature is important because it allows you to wrap Javascript inside a non-submitting fill object. Example:

Fill fillObject = fill.runBefore ("doSomething();") .callServer(false);

The code above is equivalent to doSomething();. You are only wrapping it in a Fill object.

The reason you want to do this is to implement an interface. For example, a shopping cart interface may have.

public Fill addAndGoToCart(Item item);

Implementation of the cart may or may not make a request to the server.

Think of Fill as a request to update a fragment. The mechanism may be server-side or client-side.

Use interfaces for team communication amongst fragment developers. See the shopping cart interface in Tabkit for an example.


Annotations in Trap are for documentation only. They are optional.

Because Trap generates unique ids for you, the order you declare managed objects must be consistent over the life cycles. It is an error to declare an object only on one (i.e. on Page Load but not on Fill). If you do so, managed variables will have different ids between the cycles.

You should declare managed objects as final.

In practice, these errors are rare. We only use these methods in fragments that have a long list of managed object declarations.

Special Cases

Be aware of a few special cases. However, you will rarely have to deal with them.

A good framework should align with the development philosophy of the team. Trap gives teams with Java skills the option of using server-side technologies to build single-page application. However, it also works well with client-side technologies.


Getting Started

Download Demo App (trap.war)
Version 0.820    3.5MB

Configuration: All-In-One

Trap is self-contained in a single-page (main.jsp). All configurations are on this page.

Trap requires jQuery. There are no other dependencies.

This demo includes two external libraries: guava-18.0.jar andowasp-java-html-sanitizer-r239.jsp These libraries are used by a single class Sanitizer to sanitize HTML. You can safely remove this class and the two jar files.


Link Descdription
JavaDoc Documentation for the Trap Framework.
FillJs FillJs enables you to use the Fill object in Javascript.

Example Index

Each example was designed to demonstrate a different feature in Trap.

Template Feature
Tabkit Implementation of a router. You can use this as a template for your app.
Web Service Sampler Various ways to fetch data and update the UI.
Latch Basic fill and drain.
Chain Calling another fill after drain.
Angular JS Load an Angular JS application.
FillHandler Using FillHandlers instead of if/else statements
Ladder Working with repeaters. Setting a context property to a fragment (e.g. the line ID).

Other Services

Contact us to learn more.
  1. How does it compare to other Java single-page application (SPA) frameworks?
    Most Java SPA frameworks are component-based (e.g. GWT). With component-based framework, you build the view with Java classes. Trap is page-based. You build fragments by editing HTML. Unlike most Java SPA frameworks, Trap is designed to complement Javascript frameworks.
  2. How is a page-based framework more flexible?
    There is a lot work being done on client-side web development. A page-based architecture makes it easier to use client-side frameworks (e.g. Angular JS).
  3. How does it differ from other server-side web frameworks?
    • Most web frameworks are page-based. They are built around returning content.
    • Trap is fragment-based. It is built around inserting content.
    Trap is specifically designed for single-page applications. Embedding a fragment is simple — you just include it.
  4. How does it differ from other frameworks?
    Trap is one of the only framework that supports both server-side and client-side containers.
  5. The trend is to use client-side technology to build SPAs. Is Trap risky?
    The big picture is not to focus on the server-side aspect of Trap but on the encapsulation aspect. Trap enables you to build containers for fragments. You develop fragments with server-side or client-side technologies.
  6. How is it easy to develop?
    Trap is easy to develop because it uses regular JSPs. Furrthermore, related code are placed close together within a fragment. You will spend less time searching. Finally, you can divide development into fragments and containers.
  7. How is it maintainable?
    A good framework should align itself with your team's development process. Trap works well for teams with Java skills. However, it also supports client-side technologies. The hard part of software is not writing it but maintaining it. With Trap, you get the benefit of Java (and its tools) and a container framework;
  8. How does it help developers?
    Trap makes it easy to build containers. Developers benefit because containers makes assembling fragments easier.
  9. How is it easy to learn?
    You can get productive with Trap in about a day. A large part of the API is designed for developers building containers. Fragment developers will rarely use them. Developers spend more time learning about a container (e.g. Tabkit).
  10. Do I need it if I already have a component framework?
    Trap is a container framework for fragments. It is for gluing fragments together. You use your preferred component framework within fragments. They complement each other.
  11. Where is the AJAX?
    Developers will use AJAX extensively to build single-page applications. Trap hides AJAX details within a fill object.
  12. Is it worth it to build a single-page application?
    We believe that building a single-page application with Trap and Tabkit is easier than building a regular multi-page application.
  13. How is it scalable?
    Trap runs stateless. You can cluster a Trap application.
  14. How does it save me time and money?
    Architecting a web application takes a lot of time and money. Trap and Tabkit gives you a pre-packaged server-side and client-side solution out of the box. However, it is flexible enough that you can use other server-side or client-side frameworks with it.
  15. How do I get started?
    • Install and run the demo. You can do this in about a minute. The demo is this site.
    • Study the fragment examples. They are just regular JSPs. Modify them and reload the page
    • Take a tour of Tabkit. Use it as an template for your application.
    Trap is easy to get started because fragments are virtual pages. Place your code in a JSP and embed it in the page.
  16. Do you offer professional services?
    Contact us to learn more about using Trap to build single-page applications. We are based in Vancouver, Canada.