Acciente Company Logo

Using Views in Induction

  1. Using Views in Induction
    1. Writing our first view - HelloWorld
    2. The types of views supported
    3. Notes on Best Practices
    4. Conclusion

This tutorial discusses the use of views in Induction. A view is an abstraction that simplifies handling responses that require non-trivial content generation at runtime. This tutorial assumes familiarity with the Getting Started Tuturial.

Following are some features of views in Induction:

Writing our first view - HelloWorld

Let's use a simple example to illustrate some of the above features. We will write a simple HelloWorld application that uses an Induction view to display a string to the browser. We will write two different versions of our HelloWorld application to illustrate two different view types.

The first version will use the Text view interface. The Text view interface is designed to be used to send a string to the browser. The view class is shown below:

package demoapp.helloworld2_app;

import com.acciente.induction.view.Text;

public class HelloWorld2View implements Text
{
   public String getText()
   {
      return "Hello World, using a Text view";
   }

   public String getMimeType()
   {
      return "text/plain";
   }
}

If you deployed this example similar to the example in the Getting Started Tuturial then pointing your browser at the URL http://localhost:8080/induction-demo/helloworld2 should print Hello World, using a Text view to the browser.

Our HelloWorld2View class above implements the com.acciente.view.Text interface. When Induction encounters an implementation of this interface it calls the getText() method of the interface to retrieve the string that should be returned to the browser, and the getMimeType() method to determine the mime type that should be returned for the text content. If getMimeType() return null then text/plain is assumed.

Next let's look at how a controller can use our HelloWorld2View class:

package demoapp.helloworld2_app;

import com.acciente.induction.controller.Controller;

/**
 * A simple controller that uses a Text view to display hello world
 */
public class HelloWorld2Controller implements Controller
{
   public Class handler()
   {
      return HelloWorld2View.class;
   }
}

If you deployed this controller then pointing your browser at the URL:
http://localhost:8080/induction-demo/helloworld2.action, should print the string Hello World, using a Text view to your browser.

Next let's write a HelloWorld application that uses the Freemarker templating engine to display our "Hello World" string. We'll again start with the view class:

package demoapp.helloworld3_app;

import com.acciente.induction.view.Template;

/**
 * A HelloWorld view using a freemarker tenplate
 */
public class HelloWorld3View implements Template
{
   public String getTemplateName()
   {
      return "HelloWorld3.ftl";
   }

   public String getMimeType()
   {
      return "text/plain";
   }
}

In the HelloWorld3View class above the getTemplateName() method is expected to return the name of a template file. Induction attempts to find a template with the returned by getTemplateName() in the template path configured. If a template is found Induction process the template using the configured template engine (in our example we use the Freemarker templating engine).

Induction treats the view class as a Java bean and make all the views bean properties available in the template. For example, if our HelloWorld3View class had a getUserName() method, then it would be valid to reference ${userName} in our Freemarker template.

Shown below is the simple HelloWorld3.ftl Freemarker template referenced by the HelloWorld3View view class:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
</HEAD>

<BODY>

Hello World, using a Freemarker template

</BODY>

</HTML>

You should put the HelloWorld3.ftl in a folder in your file system and ensure that the Induction configuration XML points to the location of your templates. For example if your HelloWorld3.ftl is in the folder
c:/project/demoapp/helloworld3_app/templates, then the template path section of Induction XML would be as shown below:

	<templating>
		<template-path>
			<directory>c:/project/demoapp/helloworld3_app/templates</directory>
		</template-path>
	</templating>

If you choose to put the HelloWorld3.ftl template in inside your .war file, in say /WEB-INF/templates, then the Induction XML would be as shown below:

	<templating>
		<template-path>
			<web-app-path>/WEB-INF/templates</web-app-path>
		</template-path>
	</templating>

It is recommended that you keep the templates on the file system during development. Placing the templates inside the .war file is not recommended during development, since this would require a rejar/redeploy every time the template changes.

Again after you deploy this example, pointing your browser at the URL:
http://localhost:8080/induction-demo/helloworld3, should print the string Hello World, using a Freemarker template to your browser.

The types of views supported

The following table shows the types of views currently supported in Induction:

Inducton view type Purpose of the view type
com.acciente.view.Template Used to create a view that returns text generated by a templating engine
com.acciente.view.Image Used to create a view that returns image data. The Image data is returned to Induction as a byte array
com.acciente.view.ImageStream Used to create a view that returns image data. The Image data is returned to Induction using an input stream
com.acciente.view.Text Used to create a view that returns text data. The text data is returned to Induction as a string

Notes on Best Practices

It is best that a view class expose (via its public accessors) the minimum amount of data needed by the view's associated template. However from a controller point of view it may be convenient to pass, to the view constructor, more data than the view needs to expose to the template. For example a view may only need a few attributes from a model, but it may be convenient to pass the entire model object to the view constructor.

In such cases, the view class may internally store (in instance variables) more data than is required by the template but expose only the minimum required set of data via its accessor methods. In this case the view class serves as data filter reducing the coupling of the template to models and other data in an application.

Conclusion

This concludes our tutorial about using views in Induction. Models are introduced in the Models Tutorial.