Skip to main content

Your First Phobos Application

Phobos is a lightweight web application framework that runs on the JavaTM platform but allows you to develop your entire application using a scripting language.  You can therefore take advantage of the many benefits offered by scripting languages but still leverage the power of  the Java platform. By being scripting-friendly, Phobos provides a programming environment that fosters rapid development.   This short tutorial uses a simple calculator example to show you how quickly and easily you can create web applications with Phobos.

Running the Calculator Application

To run the calculator example, follow these steps:
  1. Make sure you have the NetBeans 5.5 IDE installed and running on your system.
  2. Install the Ajax update center and all the Phobos modules in the IDE following all the instructions on the Phobos download page.
  3. Create a new project selecting "Scripting / Samples" as the category and "Calculator" as the project:

  • Click "Next" and complete the project creation step.
  • Run the application by right-clicking on the newly created project and selecting the "Run project" menu item. Your browser should open the front page of the application. If it doesn't, point it to the following URL:
  • Enter a number in the Current Total field and another number in the Second Operand field, select an arithmetic operation, and click Compute to get the result.

  • Structure of  the Calculator Application

    All Phobos applications adhere to a specific structure, which encourages building web applications according to the MVC design pattern. 

    Every Phobos application includes an application directory, which in turn includes at least a controller, a script, and a view directory.  The following diagram shows the structure of the calculator example:


    Figure 1: Structure of the Calculator Application

    As you can see from Figure 1, the application directory contains the following directories:
    • The controller directory is where you put the scripting code that creates a controller object and defines the functions that are called in response to user actions.
    • The script directory is where you can put any extra scripting code you use in the application.  In the case of the calculator, the script directory contains a script file that redirects requests to particular pages of the application.
    • The view directory is where you put the files that represent the different pages of the application.
    More complicated applications might need additional directories, such as a script directory, in which you can put static files, such as HTML pages and CSS style sheets.  The Introduction to Phobos document describes the directory structure in more detail.

    As the preceding figure shows, the calculator application contains the following files:
    • calculator.js file, which instantiates a controller object and invokes the appropriate methods to perform the arithmetic operations and redisplay the result.
    • index.js, which dispatches the first request for the application to the controller.
    • calculator.ejs, which is an embedded JavaScript file, an HTML file that contains JavaScript embedded in it.  This file represents the page of the application.
    You can take a look at these files by using the "Files" tab in NetBeans. The next section describes the role of each of these files during the processing of a request.

    How the Application Works

    Before delving into the different pieces of the calculator application, let's understand how it works.  When the browser makes the first request for the page, the following happens:

    1. The index.js file redirects the request to the /calculator/show URL.  The calculator part of the URL is a controller, and show is a function of it.  The show function is defined in calculator.js.
    2. The Phobos runtime creates the Calculator controller and invokes the show function.
    3. The show function sets the initial values of the operands, sets the selected arithmetic operation to add, and renders the calculator.ejs view.
    4. The user enters two numbers, selects an operand, and clicks Compute.
    5. When the user clicks Compute, the compute function of calculator.js is called by way of an HTTP POST to the /calculator/compute URL.
    6. The compute function does the following:
         a. Gets the values of the operands and the selected operation.
         b. Performs the appropriate calculation, and saves the result into session.
         c. Redirects to the show function so that calculator.ejs is re-rendered.

    The remaining sections describe how to perform the following tasks to create the calculator application.  You can apply these tasks while developing your own application.

    Handling the Initial Request

    When the browser makes its first request for the calculator application, it passes the URL, /.  This request is dispatched to the index.js script, located in the script directory.  This script redirects the request to the URL, /calculator/show by executing the following line:


    Code Example 1:  Redirecting the Request

    The httpserver library is one of many JavaScript libraries provided by Phobos.  This particular library includes JavaScript functions that perform basic HTTP tasks, such as request dispatching.  In this case, sendRedirect performs the same task as the sendRedirect method of HttpServletResponse, namely it sends a temporary redirect response to the client using the specified redirect location URL.

    Creating the Controller

    When the request for the URL, /calculator/show comes in, the runtime looks for a controller called calculator. It does so by executing the calculator.js script. This script defines a controller package called calculator using the library.common.define function:

    	library.common.define(controller, "calculator", function() {

    Code Example 2: Defining the Controller

    Phobos supports separate namespaces for controllers, libraries and modules.  Therefore, when you define a new package you have to say where you want to define it.  In this case, you want to define the controller package.

     As shown in the preceding code, the script passes the controller package, the name of the package (calculator), and the function to invoke to create the calculator controller.

    Now that the runtime has located the controller package, the next step is to instantiate a controller object.  To do so, the runtime looks for a Calculator property with a function value defined inside the package:

    	this.Calculator = function()

    Code Example 3: Instantiating the Calculator Controller

    The first letter of Calculator is capitalized to indicate that the function is supposed to act as a constructor.
    Don't get distracted by the use of this in the actual code; it's just an artifact of the way packages are implemented.

    At this point, the runtime has a controller instance, so it's time for it to figure out what method to invoke. To do so, it looks at the second element in the request URL, which is show, and it queries the controller object for a function-valued property of the same name. Although Javascript doesn't have classes, you should think of this function as a method.

    The controller/calculator.js code uses the following pattern to define a method:

    	this.Calculator = function() { = function() { ... }
    Code Example 4: Defining a Method

    Alternatively, you can define a method as follows:

    	this.Calculator = function() {}; = function() { ... };
    Code Example 5: Another Way to Define a Method

    It's up to you to choose which style to use.

    Setting the Initial Parameters and Rendering the View

    Now that the runtime knows to invoke the show function, let's take a look at what the show function does.  First, the show function (or action method) sets the initial values of the result and of the selected operation into the HTTP session:

          var v = invocation.session.value;
          if(v == undefined) {
    v = 0;

          var op = invocation.session.selectedOp;
    if(op == undefined) {
    op = "add";

          model = { value: String(v), selectedOp: op };
    Code Example 6: Setting Values into Session

    The Phobos framework creates the invocation.session object automatically.  As shown in the preceding code, the value of the result is set to zero because this is the first time the page is being requested.  The operation is set to a default of add.  Finally, a global variable, called model, is initialized with these values.   Later, you'll see how the page accesses these values and passes them back to the controller.

    The last thing the show function does is it displays the page, not by writing HTML directly, but by rendering a separate ''view'', represented by calculator.ejs   It does this by using the render function from the view library:

    Code Example 7:  Rendering the View

    When the preceding code is executed, the render function will try to locate the resource called calculator.ejs on the path for view resources, which includes /application/view.   As a result, the render function  resolves  to /application/view/calculator.ejs.

    The ejs extension stands for embedded Javascript, to signify that it is an HTML file with Javascript statements and expressions embedded inside it. When the view is rendered, the embedded code is evaluated at the appropriate time.  The next section describes how to create the calculator.ejs file.

    Creating the View

    You create a view using an embedded JavaScript file.    Creating an embedded JavaScript file is done in a similar way to creating a JSP page because you use the standard HTML form elements to design the interface.  The following code shows part of the form used to submit the operands and the selected operation on the calculator page.  The table tags have been removed for better readability.

       <form action="/calculator/compute" method="post">
        Current Total
          <input type="text" size="20" name="value"
    value="<%=model.value %>"/>
          Second Operand
          <input type="text" size="20" name="operand"/>
    <input id="add" type="radio" name="operator" value="add">+</input>
    <input id="subtract" type="radio" name="operator" value="subtract">-</input>
    <input id="multiply" type="radio" name="operator" value="multiply">*</input>
    <input id="divide" type="radio" name="operator" value="divide">/</input>
    <input type="submit" value="Compute"/></td></tr>

    Code Example 8: The Form Used to Submit the User's Input on the Calculator Page

    As the preceding code shows, the page has two text input fields. The Current Total field  accepts the first operand and  later displays the result of the operation when the page redisplays. The Second Operand field accepts the second operand used in the calculation.  The Current Total field gets its value from the model global variable described in the preceding section by using the expression <%=model.value%>.

    Following the text field tags, the page includes a set of radio button tags, which represent the different operations the user can choose to perform.  Finally, the page includes an input tag that represents a button that causes the form to submit when the button is clicked. 

    The action attribute on the form tag specifies the controller function that must be invoked when the form submits.  This is the calculator/compute function.  The next section describes how the compute function works.

    But first, let's take a look at the embedded JavaScript in the page:

    <script type="text/javascript">
    window.onload = function() {
    var selectedOp = "<%=model.selectedOp %>";
    document.getElementById(selectedOp).checked = true;

    Code Example 9: Embedded JavaScript on the Calculator Page

    Because this script is included in the page, it will be executed on the client.  The function in this script gets the value of the the selectedOp variable from the model global variable on the server.  The client-side script uses this value to mark the correct radio button as selected in the HTML page's DOM.

    Getting the User's Parameters and Calculating the Result

    As the preceding section explained, the data of the form on the calculator page is submitted to the URL,
    /calculator/compute using the HTTP POST method. The compute method in the Calculator controller performs the following tasks:
    1. Extracts the value, operand, and operator parameters from the request.
    2. Performs the appropriate arithmetic operation based on the value of the operator variable.
    3. Updates the value and operator values in the session.
    The first thing the compute method does is it uses the onMethod function to restrict itself to only handle POST requests:

    any: function() {

    Code Example 10:   Restricting the onMethod to Handle Only POST Requests

    According to the preceding lines of code, if a request is not a POST request, the sendNotFound function is invoked.  This function sends back a 404 error.

    The next task of the onMethod function is to extract the parameters from the request if the request is a POST:

     POST: function() {
    var value = Number(request.getParameter("value"));
    var operand = Number(request.getParameter("operand"));
    var operator = request.getParameter("operator")

    Code Example 11: Extracting Parameters From the Request

    After the function has retrieved the parameter values, it calculates the result of the operation and saves it into the value variable:

      value = ({ 
    add: function(x,y) { return x+y; },
    subtract: function(x,y) { return x-y; },
    multiply: function(x,y) { return x*y; },
    divide: function(x,y) { return y == 0 ? 0 : x/y; },
    }[operator])(value, operand);

    Code Example 12: Calculating the Result

    Note that the preceding code creates object literals.  The rough equivalent in a code running on the Java platform would be something like the following:

    switch(operator) {
        add: value =  x + y;

    Code Example 13: Equivalent of Code Example 13 in Java Code

    After updating the value variable with the result of the computation, the function needs to update the value in the session so the page can access it.  The next session describes how to do this.

    Redisplaying the New Values in the Page

    After updating the value with the result of the operation, as shown in the preceding section, the compute function updates the value and selectedOp variables in the session:

        invocation.session.value = value;
        invocation.session.selectedOp = operator;

    Code Example 14: Updating Values in Session

    The final step is to redisplay the the new values in the page.  Recall from Creating the View that the calculator page already accesses the value and selectedOp variables using expressions, as shown here:

     <script type="text/javascript">
        window.onload = function() {
          var selectedOp = "<%= model.selectedOp %>";
          document.getElementById(selectedOp).checked = true;
      <td>Current Total</td>
      <td><input type="text" size="20" name="value" value="<%= model.value %>"/></td>

    Code Example 15: Retrieving Values from Session

    So, in order to return the new values to the page, all we need to do is to re-render the page. 

    MVC design patterns recommend against returning an HTML page as the result of a POST request.  Rather, the recommendation is to send back a redirect (code 303) to a URL that will produce the desired page when invoked with the GET request. With Phobos, you can do this by using the sendFound function from the httpserver library:


    Code Example 16:  Redirecting to the show Function to Re-Render the Page

    This function is called sendFound because FOUND is the canonical message for code 303.  What the method does is it redirects to the show function, which re-renders the view.

    Deploying the Application

    Once your application is tested and ready for deployment, you can use the "Export as Web Archive (WAR)" context menu item to create a war file. The generated war file can be found under the dist directory of the project. This war file is fully portable and can be deployed on GlassFish or any other J2EE application server or servlet container.

    What's Next

    Now you understand how to create a simple Phobos application, and you can apply what you've learned to create your own  Phobos applications.  Another advantage of developing with Phobos is that  you are free to change or add on to the application while it is running.  As Phobos matures, you'll be able to do much more with it, including sophisticated database access and integration with AJAX technologies, such as jMaki.  To keep up to date on the progress of Phobos, visit and join the project aliases.

    Please Confirm