Szukaj…


Wprowadzenie

Nashorn to silnik JavaScript opracowany w Javie przez Oracle, który został wydany wraz z Javą 8. Nashorn umożliwia osadzanie Javascript w aplikacjach Java za pośrednictwem JSR-223 i umożliwia tworzenie samodzielnych aplikacji JavaScript, a także zapewnia lepszą wydajność środowiska wykonawczego i lepszą zgodność z ECMA znormalizowana specyfikacja Javascript.

Składnia

  • ScriptEngineManager // Zapewnia mechanizm wykrywania i instalacji klas ScriptEngine; używa interfejsu SPI (Service Provider Interface)
  • ScriptEngineManager.ScriptEngineManager () // Zalecany konstruktor
  • ScriptEngine // Zapewnia interfejs do języka skryptowego
  • ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Metoda fabryczna dla podanej implementacji
  • Object ScriptEngine.eval (String script) // Wykonuje określony skrypt
  • Object ScriptEngine.eval (Reader reader) // Ładuje, a następnie wykonuje skrypt z określonego źródła
  • ScriptContext ScriptEngine.getContext () // Zwraca domyślnego dostawcę powiązań, czytników i pisarzy
  • void ScriptContext.setWriter (Writer writer) // Ustawia miejsce docelowe, do którego wysyłane są dane wyjściowe skryptu

Uwagi

Nashorn to silnik JavaScript napisany w Javie i zawarty w Javie 8. Wszystko, czego potrzebujesz, znajduje się w pakiecie javax.script .

Zauważ, że ScriptEngineManager zapewnia ogólny interfejs API pozwalający uzyskać silniki skryptów dla różnych języków skryptowych (tj. Nie tylko Nashorn, nie tylko JavaScript).

Ustaw zmienne globalne

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Define a global variable
engine.put("textToPrint", "Data defined in Java.");

// Print the global variable
try {
    engine.eval("print(textToPrint);");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// 'Data defined in Java.' printed on standard output

Cześć Nashorn

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Execute an hardcoded script
try {
    engine.eval("print('Hello Nashorn!');");
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output

Uruchom plik JavaScript

// Required imports
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;

// Obtain an instance of the JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Load and execute a script from the file 'demo.js'
try {
    engine.eval(new FileReader("demo.js"));
} catch (FileNotFoundException ex) {
    ex.printStackTrace();
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Script from file!' printed on standard output

demo.js :

print('Script from file!');

Wyjście skryptu przechwytującego

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Setup a custom writer
StringWriter stringWriter = new StringWriter();
// Modify the engine context so that the custom writer is now the default
// output writer of the engine
engine.getContext().setWriter(stringWriter);

// Execute some script
try {
    engine.eval("print('Redirected text!');");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// Nothing printed on standard output, but
// stringWriter.toString() contains 'Redirected text!'

Oceń ciągi arytmetyczne

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");

//String to be evaluated
String str = "3+2*4+5";
//Value after doing Arithmetic operation with operator precedence will be 16

//Printing the value
try {
    System.out.println(engine.eval(str));
} catch (ScriptException ex) {
    ex.printStackTrace();
}

//Outcome:
//Value of the string after arithmetic evaluation is printed on standard output.
//In this case '16.0' will be printed on standard output.

Wykorzystanie obiektów Java w JavaScript w Nashorn

Możliwe jest przekazywanie obiektów Java do silnika Nashorn w celu przetworzenia w kodzie Java. Jednocześnie istnieją pewne konstrukcje specyficzne dla JavaScript (i Nashorn) i nie zawsze jest jasne, jak działają z obiektami Java.

Poniżej znajduje się tabela opisująca zachowanie rodzimych obiektów Java wewnątrz konstrukcji JavaScript.

Testowane konstrukcje:

  1. Wyrażenie w klauzuli if. W wyrażeniu JS w klauzuli if nie musi być boolean, w przeciwieństwie do Javy. Jest to oceniane jako fałsz dla tak zwanych wartości fałszowania (zero, niezdefiniowane, 0, puste ciągi itp.)
  2. dla każdej instrukcji Nashorn ma specjalną pętlę - dla każdej - która może iterować po różnych obiektach JS i Java.
  3. Pobieranie rozmiaru obiektu. W JS obiekty mają długość właściwości, która zwraca rozmiar tablicy lub łańcucha.

Wyniki:

Rodzaj Gdyby dla każdego .długość
Java null fałszywy Bez iteracji Wyjątek
Pusty ciąg Java fałszywy Bez iteracji 0
Ciąg Java prawdziwe Iteruje po ciągach znaków Długość sznurka
Java Integer / Long wartość! = 0 Bez iteracji nieokreślony
Java ArrayList prawdziwe Iteruje po elementach Długość listy
Java HashMap prawdziwe Iteruje ponad wartościami zero
Java HashSet prawdziwe Iteruje po przedmiotach nieokreślony

Zalecenia:

  • Wskazane jest użycie if (some_string) aby sprawdzić, czy łańcuch nie jest pusty i nie jest pusty
  • for each może być bezpiecznie używany do iteracji w dowolnej kolekcji i nie stwarza wyjątków, jeśli kolekcja nie jest iterowalna, zerowa lub niezdefiniowana
  • Przed uzyskaniem długości obiektu należy sprawdzić, czy jest pusta lub niezdefiniowana (to samo dotyczy każdej próby wywołania metody lub uzyskania właściwości obiektu Java)

Implementowanie interfejsu ze skryptu

import java.io.FileReader;
import java.io.IOException;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class InterfaceImplementationExample {
    public static interface Pet {
        public void eat();
    }

    public static void main(String[] args) throws IOException {
        // Obtain an instance of JavaScript engine
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

        try {
            //evaluate a script
            /* pet.js */
            /*
                var Pet = Java.type("InterfaceImplementationExample.Pet");
                
                new Pet() {
                    eat: function() { print("eat"); }
                }            
            */
            
            Pet pet = (Pet) engine.eval(new FileReader("pet.js"));
            
            pet.eat();
        } catch (ScriptException ex) {
            ex.printStackTrace();
        }

        // Outcome:
        // 'eat' printed on standard output
    }
}

Ustaw i uzyskaj zmienne globalne

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

try {
    // Set value in the global name space of the engine
    engine.put("name","Nashorn");
    // Execute an hardcoded script
    engine.eval("var value='Hello '+name+'!';");
    // Get value
    String value=(String)engine.get("value");
    System.out.println(value);
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow