Getting started with Orkwan

This tutorial will describe how to build web applications using the Orkwan framework. A basic familiarity with developing Java web applications is required.

  1. Request Processing
  2. MyServlet (inherits from OrkwanServlet)
  3. MyController (inherits from OrkwanController)
  4. orkwan.xml
  5. Hello World!
  6. Hello World using JSP and request parameters



Request Processing

The following figure describes the http request processing in a web application based on the Orkwan framework. The required application components, here named MyServlet, MyController, and the standard orkwan configuration file orkwan.xml, are explained in the following chapters.

Orkwan request processing

  1. An incoming http request is dispatched to the class MyServlet. The class MyServlet inherits from the abstract base class OrkwanServlet in the Orkwan framework. MyServlet is defined in the standard java web.xml file as the receiver of the incoming http request.
  2. Based on the URL of the http request MyServlet will create a new instance of a controller and execute the controller. The mapping between the URL and the controller class is defined in the orkwan configuration file orkwan.xml. The MyController class inherits from the abstract base class OrkwanController.
  3. MyController is responsible for executing the request. It validates the request, operates on the business model, and creates a view.
  4. After execution of MyController the framework calls a view target, either a JSP (Java Server Page) or a servlet, to create a view. The definition of the view target for a controller is made in the file orkwan.xml.
  5. The controller can also directly generate the view output as html source or an xml document. The controller can even write directly on the fly to the http response if the view is defined as custom in orkwan.xml.
  6. At the end of the request processing a http response is sent back to the user.



MyServlet (inherits from OrkwanServlet)

MyServlet is the main control servlet in the web application. It inherits from the abstract base class OrkwanServlet in the Orkwan framework. A default implementation of MyServlet without any customization (empty methods) is shown below:

package demo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.orkwan.OrkwanController;
import com.orkwan.OrkwanServlet;

/**
 * MyServlet is the main control servlet in the demo application. It inherits from
 * OrkwanServlet in the Orkwan framework.
 */
public class MyServlet extends OrkwanServlet
{
    /* 
     * handleError during processing of request (Orkwan framework override)
     */
     protected void handleError(HttpServletRequest request, HttpServletResponse response,
         Throwable t, OrkwanController controller) 
         throws IOException, ServletException
    { }

    /* 
     * handleNotFound URL (Orkwan framework override)
     */
    protected void handleNotFound(HttpServletRequest request, HttpServletResponse response)
        throws Exception
    { }

    /* 
     * initialize servlet to request (Orkwan framework override)
     */
    protected void init(HttpServletRequest request, HttpServletResponse response)
        throws Exception
    { }

    /* 
     * validate http request (Orkwan framework override)
     */
    protected void validate(HttpServletRequest request, HttpServletResponse response)
        throws Exception
    { }
}

MyServlet must implement all methods which are declared abstract in the base class OrkwanServlet. These methods are designed to be key placeholders which allow a web application to customize the default behavior in the Orkwan framework. The required methods in MyServlet are:

  1. handleError(): this method is invoked by the framework when an error (throwable) occurs during processing a request. The error (throwable) as well as the executing controller where the error occured is available for handling. A typical implementation of this method will call the log function in the application and redirect the user to an error page.
  2. handleNotFound(): this method is invoked by the framework when it can not find a controller matching the URL of the request (equivalent to a 404 response code in a web server). A typical implementation of this method will redirect the user to a page explaining that the resource can not be found.
  3. init(): this method is invoked by the framework to allow for different kinds of initialization when a new request is to be processed.
  4. validate(): this method is invoked by the framework to validate a new http request. Typical validation may involve verifying the http session, cookies, and other general request data.



MyController (inherits from OrkwanController)

MyController inherits from the abstract base class OrkwanController in the Orkwan framework. A default implementation of MyController without any customization (empty methods) is shown below:

package demo;

import com.orkwan.OrkwanController;

/**
 * MyController inherits from OrkwanController in the Orkwan framework.
 */
public class MyController extends OrkwanController
{
    /*
     * init controller (Orkwan framework override)
     */
    protected void init() throws Exception
    { }
	
    /*
     * validate input request (Orkwan framework override)
     */
    protected void validateInput() throws Exception
    { }

    /*
     * update business model (Orkwan framework override)
     */
    protected void updateModel() throws Exception
    { }
}

MyController must implement all methods which are declared abstract in the base class OrkwanController. These methods are designed to be key placeholders for defining the logic of a general web function. The required methods in MyController are:

  1. init(): this method is invoked by the framework to initialize the controller.
  2. validateInput(): this method is invoked by the framework to validate the request. A typical implementation may get and validate the input parameters of the request and save them as internal variables for later processing of the business model.
  3. updateModel(): this method is invoked by the framework to operate on the business model of the application. This method is where the business logic of the controller should be placed.



orkwan.xml

orkwan.xml is the configuration file for the Orkwan framework. It defines the mapping between a request URL, the controller to execute, and the output view to create. An example of an orkwan.xml file is:

[orkwan.xml]

<orkwan>
    <controllers>
        <controller>
            <class>demo.MyController</class>
            <url-parameter name="action" value="helloworld"/>
            <view>/helloworld.jsp</view>
        </controller>
    </controllers>
</orkwan>

The configuration above means that the controller demo.MyController will be executed for an input url containing the url parameter action=helloworld (e.g. http://www.orkwan.com/demo?action=helloworld ), and the output view is /helloworld.jsp. The value of the view tag is a relative url to the web application root, hence the root slash, "/", must be included in the path to the JSP file.

A controller can also be invoked by URI. URI is an abbreviation for Uniform Resource Identifier and is defined as "the part of the url from the protocol name up to the query string". The following definition invokes a controller by uri:

[orkwan.xml]

<orkwan>
    <controllers>
        <controller>
            <class>demo.MyController</class>
            <uri>/demo/helloworld</uri>
            <view>/helloworld.jsp</view>
        </controller>
    </controllers>
</orkwan>

The configuration above means that the controller demo.MyController will be executed for an input url containing the uri /demo/helloworld (e.g. http://www.orkwan.com/demo/helloworld ), and the output view is /helloworld.jsp.

The uri in orkwan can be defined using a regular expression and complex patterns and file names can be specified as uri. This is described in more detail in the reference.




Hello World!

In order to build a simple Hello World! web application the following components must be defined:

  1. MyServlet (must inherit from OrkwanServlet)
  2. MyController (must inherit from OrkwanController)
  3. orkwan.xml (orkwan configuration file)
  4. web.xml (standard java web application configuration file in WEB-INF/ )

Since additional customization or validation is not required in this example, the default empty implementations of MyServlet and MyController described in the previous sections will suffice. The only thing that must be added is the generation of the html output which in this case will be done in MyController directly. The implementation of MyController will thus be:

package demo;

import com.orkwan.OrkwanController;

/**
 * MyController inherits from OrkwanController in the Orkwan framework.
 */
public class MyController extends OrkwanController
{
    /*
     * init controller (Orkwan framework override)
     */
    protected void init() throws Exception
    { }
	
    /*
     * validate input request (Orkwan framework override)
     */
    protected void validateInput() throws Exception
    { }

    /*
     * update business model (Orkwan framework override)
     */
    protected void updateModel() throws Exception
    { 
        setSource("<html>Hello World!</html>");
    }
}

In this case the controller creates the hml source but it does not actually write it to the http response (that is done later by the framework). The html source of the controller can be set by either calling setSource() or by overriding the base class method createSource(). In this example the method setSource() is invoked in the updateModel() method.

Since the controller is not using a view target (jsp or servlet) and is directly generating the html source it will have the view type html in the orkwan.xml file:

[orkwan.xml]

<orkwan>
    <controllers>
        <controller>
            <class>demo.MyController</class>
            <uri>/demo/helloworld</uri>
            <view type="html"/>
        </controller>
    </controllers>
</orkwan>

The web application is deployed in the root context in the application server. The web.xml file defines MyServlet to receive all requests in the /demo context:

[web.xml]

<web-app>
    
    <servlet>
      <servlet-name>MyServlet</servlet-name>
      <servlet-class>demo.MyServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
      <servlet-name>MyServlet</servlet-name>
      <url-pattern>/demo/*</url-pattern>
    </servlet-mapping>

</web-app>

The controller can now be tested locally with an url such as http://localhost/demo/helloworld, and the response will be: "Hello World!". The localhost can of course be replaced with the actual domain name of the web site.




Hello World using JSP and request parameters

In this example the view output is created using a JSP (Java Server Page). An url parameter is added to the request. The parameter is retrieved from the request and saved as data in the controller. The controller is retrieved in the JSP and the value of the original request parameter is shown in the view.

The url of the http request in this example is (localhost is used as hostname):
http://localhost/demo/helloworld?name=jamesbond

To retrieve the name parameter and save it as data in MyController, the following implementation is used:

package demo;

import com.orkwan.OrkwanController;

/**
 * MyController inherits from OrkwanController in the Orkwan framework.
 */
public class MyController extends OrkwanController
{
    /*
     * init controller (Orkwan framework override)
     */
    protected void init() throws Exception
    { }
	
    /*
     * validate input request (Orkwan framework override)
     */
    protected void validateInput() throws Exception
    {
        String s = getRequest().getParameter("name");
        setModelData("name", s);	 
    }

    /*
     * update business model (Orkwan framework override)
     */
    protected void updateModel() throws Exception
    { }
}

The url parameter is retrieved and saved in the controller in method validateInput(). There are three equivalent ways to retrieve an url parameter from the request:

  1. getRequest().getParameter(): used in this example
  2. request.getParameter(): the http request is available as a member variable in subclasses to OrkwanController.
  3. getParameter(): a convenience method available in a controller

The data saved in a controller is usually the result of operating on the business model in updateModel(). Data in a controller can be saved using a key (String) and a value (String, int, boolean, Object) pair. The standard getters and setters are:

type set methodget method
StringsetModelData(String key, String value)getModelData(String key)
IntegersetModelInt(String key, int value)getModelInt(String key)
BooleansetModelBoolean(String key, boolean value)getModelBoolean(String key)
ObjectsetModelObject(String key, Object value)getModelObject(String key)

In the next step the orkwan.xml configuration file must be defined to match the request uri /demo/helloworld and to create the view in /helloworld.jsp:

[orkwan.xml]

<orkwan>
    <controllers>
        <controller>
            <class>demo.MyController</class>
            <uri>/demo/helloworld</uri>
            <view>/helloworld.jsp</view>
        </controller>
    </controllers>
</orkwan>

The controller responsible for executing a http request is saved as an attribute in the request under the key "controller". To get the controller in a JSP call: pageContext.getAttribute("controller", PageContext.REQUEST_SCOPE)

After casting the controller to the right type, data can be retrieved from the controller and used to create a response as shown in helloworld.jsp below:

[helloworld.jsp]

<%@ page import="demo.MyController" %>
<%
    MyController controller =
      (MyController) pageContext.getAttribute("controller", PageContext.REQUEST_SCOPE);
%>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
    <p>Hello World from <%=controller.getModelData("name")%>!</p>
</body>
</html>

In conclusion, after deploying the web application in the application server and sending the request:
http://localhost/demo/helloworld?name=jamesbond
the response received is:
Hello World from jamesbond!