Home Java Node.js vs Java + Rhino + Jetty+ FreeMarker

Node.js vs Java + Rhino + Jetty+ FreeMarker

by admin

Node.js vs Java + Rhino + Jetty+ FreeMarker
Although Node.js has been around since its inception many modules , it is still significantly inferior in capability powerful set of libraries Java.So why not take advantage of Java’s potential to develop JavaScript web applications? Let’s see how you can build a handy JavaScript MVC framework in Java.

Mozilla Rhino

First of all, let’s start with rhinos.For compiling/interpreting JavaScript we will use the engine Mozilla Rhino which provides excellent integration of ECMAScript code into Java applications.Since J2SE 6, Rhino is included in the JRE as part of the Java Scripting API, but the version in the JRE is significantly outdated and also with some unpleasant features implementation from Sun, so it’s better to use fresh build-
First of all, helloworld.js :

print('Hey you!');

Assuming that the Rhino libraries are unpacked in /lib , start the example as follows :

java-Djava.ext.dirs=./liborg.mozilla.javascript.tools.shell.Main helloworld.js

By the way, it also comes with a debugger with a nice UI, it runs like this :

java -Djava.ext.dirs=./lib org.mozilla.javascript.tools.debugger.Main helloworld.js

Node.js vs Java + Rhino + Jetty+ FreeMarker
Rhino, in addition to the standard ECMAScript objects, includes a number of features in the global context that make it easy to link JavaScript to Java. Yes, in case you haven’t figured it out yet, it will be possible to work transparently with Java code from JavaScript code. There is a global object for working with packages Packages For example, this is how to create an instance of java.io.File :

var file = new Packages.java.io.File('filename');

However, there are also global objects java , com , org , edu and net , so the code can be shortened to the following :

var file = new java.io.File('filename');

You can use this pattern to import :

var File = java.io.File;//...var file = new File('filename');

But it’s still more convenient this way:

importClass(java.io.File);//...var file = new File('filename');

Or so :

importPackage(java.io);//...var file = new File('filename');

Rhino allows you to implement Java interfaces in a JS programmer-friendly way :

var runnable = new java.lang.runnable({run:function() { print("I'm running!"); }});new java.lang.Thread(runnable).start();

By the way, notice that java.lang is not imported into the global context to avoid conflicts with built-in ECMAScript types.
And the latest versions of Rhino also include a full-fledged implementation of CommonJS which can be included in the Rhino Shell with the switch -require
If we have a module /modules/math.js :

exports.sum = function(a, b) {return a + b;}

You can use it like this :

var math = require('math');print(math.sum(2, 4));

This code is started like this :

java -Djava.ext.dirs=./lib org.mozilla.javascript.tools.shell.Main -require -modules ./modulestest.js

Jetty

As a basis for the HTTP-server let’s take Jetty Jetty is a servlet container and a flexible web-server with SPDY, WebSocket, OSGi, JMX, JNDI and JAAS support. You can download the distribution here
The simplest code to start Jetty:

importPackage(org.eclipse.jetty.server);var server = new Server(8888); // Port 8888server.start();server.join(); // Transfer control to Jetty

JARs from the Jetty distribution should also be placed in /lib , from now on we will run everything like :

java -Djava.ext.dirs=./lib org.mozilla.javascript.tools.shell.Main -require -modules ./modules server.js

Yes, that’s it.
This server gives out HTTP 404 on any request. Let’s turn it into a simple file server.

importPackage(org.eclipse.jetty.server);importPackage(org.eclipse.jetty.server.handler);var resourceHandler = new ResourceHandler();resourceHandler.setDirectoriesListed(true); // Allow the list of files in folders to be viewedresourceHandler.setResourceBase('web'); // Set the base directory to ./webresourceHandler.setWelcomeFiles(['index.html']); // index.html will be used as the home pagevar server = new Server(8888);server.setHandler(resourceHandler);server.start();server.join();

Now let’s try to create a servlet.

importPackage(org.eclipse.jetty.server);importPackage(org.eclipse.jetty.server.handler);importPackage(org.eclipse.jetty.servlet);importPackage(javax.servlet.http);var contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);contextHandler.setContextPath('/');contextHandler.addServlet(new ServletHolder(new HttpServlet({ // Let's pay attention once againto how doGet interfaces are implemented: function(request, response) {response.setContentType('text/plain');response.getWriter().println('Yes, it works!');}})), '/test');var server = new Server(8888);server.setHandler(contextHandler);server.start();server.join();

Our servlet is available at localhost:8888/test As another example, let’s make a servlet module that generates a picture with text on the fly.

importPackage(java.awt.image);importClass(java.awt.Color);importClass(javax.imageio.ImageIO); // Part of J2SE 6var width = 400, height = 400;exports.doGet = function(request, response) {var image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);var graphics = image.createGraphics();var color = new Color(Math.random(), Math.random(), Math.random());graphics.setColor(color);graphics.fillRect(0, 0, width, height);graphics.setColor(color.brighter());graphics.drawString('On the fly!', 10, 20);response.setContentType('image/png');var outputStream = response.getOutputStream();ImageIO.write(image, 'png', outputStream);outputStream.close();};

Let’s put it in the folder /modules how imageServlet.js and include in the server code :

contextHandler.addServlet(new ServletHolder(new HttpServlet(require('imageServlet')), '/image.png');

What’s up with the DBMS? Let’s see how to get a list of databases from MySQL.

importPackage(java.sql);exports.doGet = function(request, response) {try {var connection = DriverManager.getConnection('jdbc:mysql://localhost/?', 'root', '');try {var resultSet = connection.createStatement().executeQuery('show databases;');response.setContentType('text/html;charset=UTF-8');var writer = response.getWriter();writer.println('<h1> Databases</h1> ');while (resultSet.next()) {writer.println(resultSet.getString('Database') + '<br /> ');}} catch(e) {} finally {resultSet.close();}} catch(e) {} finally {if(connection)connection.close();}};

For this code you will need MySQL Connector/J For JDBC.
Now there’s one last component left, the templating tool.

FreeMarker

FreeMarker – is definitely the best template engine for Java, and not only for HTML and HTTP. We could write a separate article about its features, so let’s go straight to the specifics.
Put in /templates/template.ftl template like this :

<html><head><title> ${title}</title></head><body><h1> ${title}</h1><#if message??><pre> ${message?html}</pre><#else><form method="post"><textarea name="message"> </textarea><p> <input type="submit" value="Post!"/> </p></form></#if></body></html>

Suffix ?.html Substitutes in the variable to be substituted those special characters on the escape sequence. This pattern will use the following servlet:

importPackage(Packages.freemarker.template);importPackage(Packages.freemarker.ext.rhino);var configuration = new Configuration();configuration.setObjectWrapper(new RhinoWrapper()); // A truly pleasant surprise.var template = configuration.getTemplate('templates/template.ftl');exports.doGet = function(request, response) {response.setContentType('text/html;charset=UTF-8');template.process({'title': 'Compose a message'}, response.getWriter());};exports.doPost = function(request, response) {response.setContentType('text/html;charset=UTF-8');template.process({'title': 'Message', 'message': request.getParameter('message')}, response.getWriter());};

The comparison with Node.js I generously pass on to the reader. The full example code is available at GitHub

You may also like