XINS - Scripting the Web Service (by Anthony Goubard)

Introduction

This article will show you how to implement a Web Service using a script language.


The advantages of using a script language to implement your Web Services are:

  • Reduce code size
  • Can be modified at runtime
  • No need to learn the Java language
  • Could be useful for writing a mock or a stub API


You can use different APIs to call a script:

  • Using the script API: Probably the easiest way but specific to the script language you are using.
  • JavaSE 6 scripting API: Simple, generic to any languages but requires JavaSE 6 and an extra JAR file.
  • Bean Scripting Framework: Generic, works with Java 1.4 but more difficult to use.


Groovy will be used as script language in our examples.

A XINS API using Groovy to implement the Web Services is provided in the demo\xins-project\apis\toobox directory of the release. To compile and run this example, copy the needed Groovy JAR files in the demo\xins-project\apis\toobox\lib directory and uncomment the API in the demo\xins-project\xins-project.xml file.

Setting up the environment

  • Download Groovy.
  • Copy groovy-1.0\embeddable\groovy-all-1.0.jar to <project home>\apis\<api name>\lib
  • Add to the impl.xml file of the API:
    <dependency dir="apis/<api name>/lib" includes="groovy-all-1.0.jar" />

Example 1: Hello World! using Groovy API

In this example, we will adapt the myproject demo to implement it with Groovy.

Using the script means passing the values of the Request object to the script and getting the result from the script to put in the SuccessfulResult object.


Here is the Java implementation of the Result call(Request request) method:
// The classes are in the groovy.lang package
// Put the request values in the script
Binding binding = new Binding(BeanUtils.getParametersAsString(request));
GroovyShell shell = new GroovyShell(binding);

Object value = shell.evaluate("def salutation = gender == 'male' ? 'Mister' : 'Miss'; return 'Hello ' + gender + ' ' + personLastName;");
result.setMessage((String) value);

Example 2: Script in an external file using the Java scripting API

For this example, we will use JavaSE 6 and the javax.script package. A list of languages supported for this library is available here.
  • First download the JSR-223 engine for Groovy at https://scripting.dev.java.net/.
  • Open the Zip file and extract groovy\build to the <project home>\apis\<api name>\lib directory.
  • Add also to the impl.xml file of the API:
    <dependency dir="apis/<api name>/lib" includes="groovy-engine.jar" />

Here is the Java implementation of the Result call(Request request) method:
// The classes are in the javax.script package
// Put the request values in the script
ScriptEngineManager scriptingManager = new ScriptEngineManager();
ScriptEngine groovyEngine = manager.getEngineByExtension("groovy");
Bindings bindings = new SimpleBindings(BeanUtils.getParameters(request));

// You may also want to catch the possible exceptions thrown
Reader matchScript = new InputStreamReader(getClass().getResourceAsStream("/WEB-INF/classes/com/mycompany/apiname/api/match.groovy"));
Map<String, Object> values = groovyEngine.eval(matchScript, bindings);
matchScript.close();

// Put the result returned by the script in the result object
BeanUtils.setParameters(values, result);
return result;
Here is the Groovy implementation of the function:
// Check that a text matches a regular expression
["match": entry ==~ regexp]

Example 3: Script using the Bean Scripting Framework (BSF)

The Bean Scripting Framework (BSF) is similar to the javax.script API integrated in JavaSE 6. The advantage of BSF is the ability to be used in Java 1.4 or 1.5 and to be loosely coupled to the script language. If you just want to compile using Java 1.4 or 1.5 you may prefer to use the class provided by Groovy used in example 1. More details here.
  • You need to download BSF at http://jakarta.apache.org/bsf/.
  • Copy the bsf.jar file to the <project home>\apis\<api name>\lib directory.
  • Add to the impl.xml:
    <dependency dir="apis/<api name>/lib" includes="bsf.jar" />

Here is the Java implementation of the Result call(Request request) method:
// Shuffle any given list
BSFManager manager = new BSFManager();
manager.registerBean("request", request);
Integer doubleId = (Integer) manager.eval("groovy", "double.groovy", 0, 0, "request.getIntputNumber() * 2");