Scripting with servlets [rhino] - part III (Sun Java System WebServer 7.0)

Writing Javascript servlets using Rhino on Sun Java System WebServer 7.0.

About the language

Javascript is one of the few languages that are exceptionally neat in the specification. The syntax
is very simple and there are are very few exceptions to the rules. It provides a prototype based
inheritance model and supports all the higher order constructs like closures, objects, exceptions
etc.. 

Since I had already discussed the complete sequence of instructions to get the servlets up and
running using other languages, I will stick to a somewhat brief outline here.

If you are using JDK6, then you already have access to scripting APIs in java, using which you
can load the language dynamically. It is simple to modify our parent ScriptServlet to do this (based
on a parameter passed in init, you can decide on the language loaded. I will treat that in a later entry.)

RhinoServlet

The ScriptServlet developed in the previous entry is used here as the parent class.
 

package com.sun.servlet;

import javax.servlet.http.\*;
import org.mozilla.javascript.\*;
import org.mozilla.javascript.tools.shell.Global;

public class RhinoServlet extends ScriptServlet {
    public Context jm = Context.enter();
    protected final Global global = new Global();

    protected void finalize() throws Throwable {
        Context.exit();
    }

    public void initialize(String handler, Object code) throws Exception {
        global.init(jm);
        Function funct = jm.compileFunction(global, (String)code, handler, 1, null);
        funct.call(jm, global, funct, new Object[] {jm.javaToJS(this, global)});
    }

    public void eval(Object fn, HttpServletRequest request, HttpServletResponse response) {
        ((Function)fn).call(jm, global, (Function)fn, new Object[] {
            jm.javaToJS(request, global),
            jm.javaToJS(response, global)});
    }
}

 

Providing the javascript handler

Jvm Bindings.

The bindings are just like pure java, ie Use the 'dot' notation to access methods in objects.
(check out the nice entry by Sundararajan that compares the java bindings of various jvm languages
if you would like to know more.)

docroot/WEB-INF/code/rhino.js

function (httpservlet) {
    do_get = function (request,response) {
        response.setContentType("text/html");
        this.out = response.getWriter();

        this.request = request;
        this.response = response;
        this.httpservlet = httpservlet;

        try {
            spath = request.getServletPath();
            filename = httpservlet.getServletConfig().getServletContext().getRealPath(spath);
            body = httpservlet.read(filename) + ""; // convert body to javascript string.
            this.out.println(eval(body));
        } catch (e) {
            this.out.println("<html><body><b>Servlet Error ("
                    + e.name + ")</b><xmp>" + e.message + "</xmp></body></html>");
        }
    }
    httpservlet.add('get', do_get);
    httpservlet.add('post', do_get);
}


As usual, we return a proc object with an arity 1 using which we get the current instance of  ScriptServlet. then we proceed
to set the 'get' and 'post' symbols

An example js script that can get executed:

/docroot/hello.js

"<html> <head><title>abc</title></head> <body> <h1> Hello at "
    + new Date() + " from " + request.getServletPath()
    + " </h1> </body> </html>"

Build  Steps.

          The complete rhino-webapp is provided here. You can download it and extract the contents to a
directory called 'rhino' inside your installation. It should be in the samples/java/webapps/rhino directory
in your installation of webserver as it refers to the common.xml for building.

Update the js.jar if required. 

Your extracted directory will look like this.

|cd rhino
|find .
./docs
./docs/index.html
./src
./src/build.xml
./src/RhinoServlet.java
./src/docroot
./src/docroot/WEB-INF
./src/docroot/WEB-INF/lib
./src/docroot/WEB-INF/lib/js.jar
./src/docroot/WEB-INF/web.xml
./src/docroot/WEB-INF/sun-web.xml
./src/docroot/WEB-INF/code
./src/docroot/WEB-INF/code/rhino.js
./src/docroot/index.html
./src/docroot/hello.js
./src/ScriptServlet.java
./deploy.tcl


You can run 'ant' from inside the src directory which will create the rhino-webapp.war in the
rhino directory. This war file can be deployed on the webserver using the wadm.

wadm  -u admin -f deploy.tcl

 Once the deployment goes through, you will be able to access the js file using the url

http://yourserver:port/rhino/hello.js

 

Comments:

This is very cool... I've been looking for a good simple way to implement javascript as a server-side scripting language and this is perfect. One thing I would like to change though is that I noticed that you're compiling the script in the initialize method. This prevents dynamic reloading of the script if the script changes. I'm trying to use evaluateString instead, but can't get it to work. Any ideas?

Posted by Rich on February 21, 2007 at 04:32 PM IST #

I think you want to reload the 'script' file rather than the servlet script.
ie, you want to reload the 'hello.js' rather than the 'rhino.js'

The rhino.js loads and executes the hello.js or any other js file that you
supply and generally does not need to change.

The reason the script is not being picked up is due to the below lines in
'rhino.js' servlet
==================================
spath = request.getServletPath();
filename = httpservlet.getServletConfig().getServletContext().getRealPath(spath);
body = httpservlet.read(filename) + ""; // convert body to javascript string.
this.out.println(eval(body));
==================================

Here, the httpservlet.read method has a cache and fetches the body from there if
it was read earlier.

What you should do, is to disable the caching in the ScriptServlet.read
(Parent class For RhinoServlet) -- possibly by looking for an init argument to the servlet.
(so that you can use the cache in production but disable it in dev)

Do let me know of your progress.

Posted by rahul on February 22, 2007 at 05:02 AM IST #

I think you want to reload the 'script' file rather than the servlet script.
ie, you want to reload the 'hello.js' rather than the 'rhino.js'

The rhino.js loads and executes the hello.js or any other js file that you
supply and generally does not need to change.

The reason the script is not being picked up is due to the below lines in
'rhino.js' servlet
[
spath = request.getServletPath();
filename = httpservlet.getServletConfig().getServletContext().getRealPath(spath);
body = httpservlet.read(filename) + ""; this.out.println(eval(body));
]

Here, the httpservlet.read method has a cache and fetches the body from there if
it was read earlier.

What you should do, is to disable the caching in the ScriptServlet.read
(Parent class For RhinoServlet) -- possibly by looking for an init argument to the servlet.
(so that you can use the cache in production but disable it in dev)

Posted by rahul on February 22, 2007 at 05:06 AM IST #

I think you want to reload the 'script' file rather than the servlet script.
ie, you want to reload the 'hello.js' rather than the 'rhino.js'

The rhino.js loads and executes the hello.js or any other js file that you
supply and generally does not need to change.

The reason the script is not being picked up is due to the below lines in
'rhino.js' servlet
[
spath = request.getServletPath();
filename = httpservlet.getServletConfig().getServletContext().getRealPath(spath);
body = httpservlet.read(filename) + ""; this.out.println(eval(body));
]

Here, the httpservlet.read method has a cache and fetches the body from there if
it was read earlier.

What you should do, is to disable the caching in the ScriptServlet.read
(Parent class For RhinoServlet) -- by looking for an init argument to the servlet.
(so that you can use the cache in production but disable it in dev)

Posted by rahul on February 22, 2007 at 05:08 AM IST #

even better

http://today.java.net/pub/a/today/2005/09/23/dynamic-web-app-interaction.html

Posted by X on July 07, 2008 at 10:53 AM IST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

blue

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today