Transferred from: Http://www.tuicool.com/articles/imEbQbA
One of the most compelling new features of Java SE 6 is the embedded scripting support. By default, Java SE 6 only supports JavaScript, but this does not mean that Java SE 6 can only support JavaScript. In Java SE 6, a number of interfaces are provided to define a scripting specification, known as JSR223. By implementing these interfaces, Java SE 6 can support any scripting language (such as PHP or Ruby).
Run the first script program
Before you run a script with Java SE 6, you must know what scripting language your Java SE 6 supports. There are many classes in the Javax.script package, but the most important of these classes is Scriptenginemanager. All scripts supported by the current Java SE 6 can be obtained through this class. The following example will list all script engine factories that can be used.
Import Javax.script.*; Import java.io.*; Import Java.util.*; Import static Java.lang.System.*; public class Listscriptengines {public static void main (String args[]) {Scriptenginemanager manager = new ScriptEngine Manager ();Get all the script engine factory List factories = Manager.getenginefactories ();This is the Java SE5 and Java SENew for statement syntax for 6for (Scriptenginefactory factory:factories) {Print script information out.printf"Name:%s%n "+ %s%n "+" Span class= "string" > "Language Name: %s%n" + %s%n "+ %s%n "+ " Mime types: %s
%n "+
%s%n ", Factory.getenginename (), Factory.getengineversion (), Factory.getlanguagename (), Factory.getlanguageversion (), Factory.getextensions (), Factory.getmimetypes (), Factory.getnames ()); //get the current scripting engine ScriptEngine engine = Factory.getscriptengine (); }}}
The above example must be compiled in Java SE 6. Where import static java.lang.system.* is the new syntax that references all static members in System, you can use out, in, or err directly later.
By running Java Listscriptengines, the following information is displayed
Mozilla Rhino1.6 Release 2ECMAScript 1. 6 [JS] [Application/javascript, Application/ecmascript, Text/javascript, Text/ecmascript] [JS, Rhino, JavaScript, JavaScript, ECMAScript, ECMAScript]
The bottom line is the alias of the script, that is, any one of them can be used. There are 3 ways to get a specific scripting engine.
- Get the scripting engine based on the extension
ScriptEngine engine = manager.getenginebyextension ("JS");
The getenginebyextension parameter is EXTENSIONS:[JS] [...] Part of the room.
- Get the scripting engine based on MIME type
ScriptEngine engine = Manager.getenginebymimetype ("Text/javascript");
The parameters of the Getenginebymimetype can be MIME types: [Application/javascript, Application/ecmascript, Text/javascript,
Text/ecmascript], you can change the text/javascript to Text/ecmascript.
- Get the scripting engine by name
ScriptEngine engine = Manager.getenginebyname ("javascript");
The parameters after getenginebyname can be either names: [JS, Rhino, JavaScript, JavaScript, ECMAScript, ECMAScript],
If you can change JavaScript to ECMAScript.
============================================================================================
The first step in executing the script has been discussed above, which is to get an available scripting engine. After doing this, you can use the scripting engine to execute the appropriate script. We can use the ScriptEngine eval method to execute the script. The Eval method is overloaded multiple times, but the most common is the public Object eval (String script).
The following example shows how to use the Eval method to execute a JavaScript script.
Import javax.script.*;Import java.io.*;ImportStatic java.lang.system.*;PublicClass Firstjavascript {PublicStaticvoid Main (String args[]) {Scriptenginemanager manager =New Scriptenginemanager ();//Get the JavaScript scripting engine ScriptEngine = Manager.getenginebyname ("JavaScript");try {// start running the script and return the current hour Double hour = (double) engine.eval ("var date = new Date ();" +"date.gethours ();"); String msg; // convert hours to greeting information if (Hour < ) {msg = "Good Morning"; } Else if (Hour < ) {msg = "Good Afternoon"; } Else if (Hour < ) {msg = "Good evening"; } Else {msg = "Goodnight"; } out.printf ("hours%s:%s%n", hour, msg); } catch (Scriptexception e) {err.println (e); }}}
The above example is done by getting the current hour and translating it into a greeting. The output information for the above program is:
Hour 9.0: Good Morning
The most notable of this example is the execution of the 2-sentence script, and the last sentence is date.gethours (). This value is not assigned to a JavaScript variable. At this point, the Eval method returns such a value. This is somewhat similar to the C language (...) Operator. For example (C=a+b, C + D), the return value of this expression is a+b+d.
=======================================================================================
Interacting with the scripting language
The above example just runs a very simple script. This script is orphaned and does not pass any value to the script through Java. Although a value has been returned from this script, this return is implicit.
In addition to these simple features, the scripting engine provides us with more powerful features. You can even pass parameters to the scripting language through Java, and you can also take the values of variables in the scripting language. These functions depend on the two methods put and get in ScriptEngine.
Put has two parameters, one is the script variable name and the other is the value of the variable, which is the object type, so you can pass any value.
Get has a parameter, which is the name of the script variable.
The following code flips a string through a JavaScript script (the string is passed to JavaScript via Java), then gets the flipped character through Java and then outputs it.
Import javax.script.*;Import java.io.*;ImportStatic java.lang.system.*;PublicClass reversestring {PublicStaticvoid Main (String args[]) {Scriptenginemanager manager =New Scriptenginemanager ();// build JavaScript script engine ScriptEngine engine = Manager.getenginebyname (
"JavaScript");
try {// pass variable name and variable value ABCDEFG to JavaScript script Engine.put ( "name", "ABCDEFG"); // start execution script Engine.eval ( "var output = ';" + " output = Name.charat (i) + output "+
"}");
// get the value of the output variable String name = (string) engine.get ( " Output "); out.printf (catch (scriptexception e) {err.println (e); }}}
The output of the above code is:
The string after being flipped: GFEDCBA
=============================================================================================================== ===========
Make the script run faster
As we all know, explaining how to run is the slowest way to run. Some of the above examples are operated in an interpreted way, without exception. Because the scripting engine of Java EE 6 can support any language that implements the scripting engine interface. There are many such languages that provide compile functionality, which means that the scripts are compiled before the script is run (the compilation here will typically not build the executable, but simply compile in memory to make it easier to run) before executing. This is very fast if a script has to be run multiple times. We can use ScriptEngine's compile method to compile. Not all scripting engines support compilation, and only the scripting engine that implements the Compilable interface can compile with compile, or an error will be thrown. The following example shows how to compile and run a JavaScript script using the Compile method.
Import javax.script.*;Import java.io.*;ImportStatic java.lang.system.*;PublicClass Compilescript {PublicStaticvoid Main (String args[]) {Scriptenginemanager manager =New Scriptenginemanager (); ScriptEngine engine = Manager.getenginebyname ("JavaScript"); Engine.put ("Counter",0);//Passing a parameter to JavaScript//if (engine instanceof compilable) {compilable Compengine = (compilable) engine; try {// compile compiledscript script = Compengine.compile ( "function count () {" + "return counter; "+ "}; Count (); "); out.printf ( "Counter:%s%n", Script.eval ()); out.printf ( "Counter:%s%n", Script.eval ()); out.printf ( "Counter:%s%n", Script.eval ()); } catch (scriptexception e) {err.println (e); }} else {err.println ( "This scripting engine does not support compiling!"); }}}
The above code runs after the display information is as follows:
1.02.03.0
In this example, the script is compiled by the compile method and then called multiple times through the Eval method. There is only one function in this code, so eval returns the value of the function .
=============================================================================================================== ==========
Methods for dynamically invoking scripting languages
The above example has only one function that can be called by Eval and return its value. However, if there are multiple functions in the script or if you want to decide which function to call through the user's input, this requires a dynamic invocation using the Invoke method. As with compilation, the scripting engine must implement the Invocable interface to dynamically invoke methods in the scripting language. The following example shows how to run a JavaScript script above the flip string in a dynamic way.
Import javax.script.*;Import java.io.*;ImportStatic java.lang.system.*;PublicClass invocabletest {PublicStaticvoid Main (String args[]) {Scriptenginemanager manager =New Scriptenginemanager (); ScriptEngine engine = Manager.getenginebyname ("JavaScript"); String name="ABCDEFG"; if (engine instanceof invocable) { try {engine.eval ("function reverse (name) {" + "var output = ') '; ' + ' for (i = 0; I <= name.length; i++) {"+ " output = Name.charat (i) + output "+ "} return output;} "); Invocable invokeengine = (invocable) engine; Object o = invokeengine.invokefunction ("reverse", name); out.printf ("flipped string:%s", O); } catch (Nosuchmethodexception e) {err.println (e); } catch (Scriptexception e) {err.println (e); }} else {err.println ("This scripting engine does not support dynamic invocation"); }}
=============================================================================================================== =======
Dynamically implement interfaces
The scripting engine also has a more attractive feature, which is the dynamic implementation of interfaces. If we want the script to execute asynchronously, that is, through multithreading, the Invokeengine class must implement the Runnable interface to start multithreading through thread. Therefore, the GetInterface method can be used to enable invokeengine to dynamically implement the Runnable interface. This can generally be divided into 3 steps.
1. Write a run function using JavaScript
Engine.eval ("function run () {print (Asynchronous execution);}");
2. Implementing the Runnable interface via the GetInterface method
Runnable runner = Invokeengine.getinterface (Runnable.class);
3. Start multithreading using the Thread class
Thread t = new thread (runner);
T.start ();
The following is the detailed code to implement this feature.
Import javax.script.*;ImportStatic java.lang.system.*;public class interfacetest {public static void main (String args[]) {Scriptenginemanager manager = new Scriptenginemanager (); ScriptEngine engine = manager.getenginebyname ( "JavaScript"); try {engine.eval (new Thread (runner); T.start (); T.join (); } catch (interruptedexception e) {err.println (e); } catch (scriptexception e) {System.err.println (e); }}}
Java scriptengine Use (Java Run script file)