Programovanie

JavaScript v Jave

Nedávny príspevok o JavaLobby Top 10 nepoužívaných funkcií v Jave bol mimoriadne populárny. V čase písania tohto článku je to najlepšie hodnotený príspevok v kategórii DZone Top Links. Okrem toho bola zverejnená aj odpoveď na ňu. V oboch blogových príspevkoch je veľa zaujímavých postrehov o nevyužitých funkciách v Jave a s niektorými súhlasím viac ako s ostatnými. Položkou, ktorá ma však naozaj zaujala, bolo tvrdenie, že Java SE 6 je jednou z najneužívanejších funkcií Java.

Veľmi rád pracujem s Java SE 6 a v minulosti som viackrát písal alebo blogoval o funkciách Java SE 6. V tomto blogovom príspevku chcem demonštrovať časť schopnosti Java SE 6 hostiť vykonávanie kódu JavaScript.

Väčšina vývojárov Java a vývojárov JavaScriptu chápe, že okrem štyroch písmen „J-A-V-A“ majú JavaScript a Java okrem spoločného dedičstva podobného písmenu C aj niečo spoločné. Napriek tomu môže byť niekedy užitočné spustiť skriptovací jazyk z kódu Java a Java SE 6 to umožňuje.

Balík javax.script bol predstavený v prostredí Java SE 6 a obsahuje triedy, rozhrania a kontrolovanú výnimku súvisiacu s používaním skriptovacích strojov v rámci Javy. Tento príspevok v blogu sa zameria na ScriptEngineFactory, ScriptEngineManager, ScriptEngine a ScriptException.

Jednou z prvých vecí, ktoré by ste možno chceli urobiť, je zistiť, ktoré skriptovacie motory sú už k dispozícii. Nasledujúci úryvok kódu ukazuje, aké ľahké je to s programom Java SE 6.

konečný správca ScriptEngineManager = nový ScriptEngineManager (); pre (finálny ScriptEngineFactory scriptEngine: manager.getEngineFactories ()) {System.out.println (scriptEngine.getEngineName () + "(" + scriptEngine.getEngineVersion () + ")"); System.out.println ("\ tLanguage:" + scriptEngine.getLanguageName () + "(" + scriptEngine.getLanguageVersion () + ")"); System.out.println ("\ t Bežné mená / Aliasy:"); pre (konečný reťazec engineAlias: scriptEngine.getNames ()) {System.out.println (engineAlias ​​+ ""); }} 

Kód zobrazený vyššie generuje výstup podobný výstupu uvedenému na nasledujúcej snímke obrazovky.

Ako ukazuje tento obrázok, JavaScriptový modul Mozilla Rhino je súčasťou aplikácie Sun Java SE 6. Vidíme tiež niektoré „bežné názvy“, ktoré sú spojené s týmto konkrétnym motorom. Na vyhľadanie tohto nástroja je možné použiť ktorékoľvek z týchto mien. V ďalších príkladoch v tomto príspevku budem pre toto vyhľadávanie používať bežný názov „js“.

Ďalšia ukážka kódu využije poskytnutý JavaScriptový stroj Rhino na vykonanie určitého kódu JavaScript z kódu Java. V takom prípade využijeme výhody funkcie toExponential JavaScriptu.

 / ** * Napíšte číslo v exponenciálnej podobe. * * @param numberToWriteInExponentialForm Číslo, ktoré má byť reprezentované v * exponenciálnej podobe. * @param numberDecimalPlaces Počet desatinných miest, ktoré sa majú použiť v * exponenciálnom zastúpení. * / public static void writeNumberAsExponential (konečné číslo numberToWriteInExponentialForm, konečné int numberDecimalPlaces) {final ScriptEngine engine = manager.getEngineByName ("js"); try {engine.put ("inputNumber", numberToWriteInExponentialForm); engine.put ("decimalPlaces", numberDecimalPlaces); engine.eval ("var outputNumber = inputNumber.toExponential (decimalPlaces);"); final String exponentialNumber = (String) engine.get ("outputNumber"); System.out.println ("Číslo:" + exponenciálne číslo); } catch (ScriptException scriptException) {LOGGER.severe ("Pri pokuse o zápis exponenciálnej hodnoty sa vyskytla ScriptException:" + scriptException.toString ()); }} 

Vyššie uvedený kód priamo vyvolá JavaScript pomocou metódy ScriptEngine.eval (String) na vyhodnotenie poskytnutého reťazca obsahujúceho syntax JavaScript. Pred vyvolaním eval metóda, dva parametre sú „odovzdané“ (viazané) do kódu JavaScript prostredníctvom hovorov ScriptEngine.put (String, Object). K objektu výsledku spusteného JavaScriptu sa pristupuje v kóde Java pomocou volania ScriptEngine.get (String).

Vyššie uvedený kód demonštrovať pomocou naExponenciálne funkcie použijem nasledujúci „klientský“ kód.

konečné int číslo zdroja = 675456; writeNumberAsExponential (sourceNumber, 1, System.out); writeNumberAsExponential (sourceNumber, 2, System.out); writeNumberAsExponential (sourceNumber, 3, System.out); writeNumberAsExponential (sourceNumber, 4, System.out); writeNumberAsExponential (sourceNumber, 5, System.out); 

Keď je vyššie uvedený kód spustený proti metóde writeNumberAsExponential zobrazenej skôr a je použitý JavaScript, výstup sa zobrazí podobne ako výstup zobrazený na nasledujúcej snímke obrazovky.

Tento príklad stačí na to, aby sme demonštrovali, aké ľahké je vyvolať funkčnosť JavaScriptu z prostredia Java SE 6. To by sa však dalo implementovať ešte všeobecnejšie, ako ukážu nasledujúce dva príklady. Prvý príklad ukazuje vyvolanie relatívne ľubovoľného JavaScriptu bez zadania / zadania parametrov a druhý príklad demonštruje vyvolanie relatívne ľubovoľného JavaScriptu s zadanými / zadanými parametrami.

Relatívne ľubovoľný reťazec kódu JavaScript je možné spracovať s kódom podobným tomu, ktorý je uvedený ďalej.

 / ** * Spracuje vložený skript jazyka JavaScript, ktorý by mal obsahovať priradenie * k premennej s názvom predpísaným v poskytnutom nameOfOutput a * môže obsahovať parametre predpísané inputParameters. * * @param javaScriptCodeToProcess Reťazec obsahujúci kód JavaScript, ktorý sa má * vyhodnotiť. Tento reťazec nie je skontrolovaný na žiadny typ platnosti a * by mohol viesť k vyvolaniu ScriptException, ktorý by * bol zaprotokolovaný. * @param nameOfOutput Názov výstupnej premennej spojenej s * poskytnutým skriptom JavaScript. * @param inputParameters Voliteľná mapa názvov parametrov s hodnotami parametrov *, ktoré môžu byť použité v poskytnutom skripte JavaScript. Táto mapa * môže byť nulová, ak sa v skripte neočakávajú žiadne vstupné parametre. * / public static Object processArbitraryJavaScript (final String javaScriptCodeToProcess, final String nameOfOutput, final Map inputParameters) {Object result = null; final ScriptEngine engine = manager.getEngineByName ("js"); skus {if (inputParameters! = null) {for (final Map.Entry parameter: inputParameters.entrySet ()) {engine.put (parameter.getKey (), parameter.getValue ()); }} engine.eval (javaScriptCodeToProcess); výsledok = engine.get (nameOfOutput); } catch (ScriptException scriptException) {LOGGER.severe ("Pri pokuse o zápis ľubovoľného JavaScriptu '" + javaScriptCodeToProcess + "':" + scriptException.toString ()) sa vyskytla ScriptException; } vrátiť výsledok; } 

Vyššie uvedený kód poskytuje dosť veľkú flexibilitu, pokiaľ ide o JavaScript, ktorý je možné spracovať. Toto asi nie je najlepší nápad na produkčný kód, ale uľahčuje to demonštráciu použitia rôznych funkcií jazyka JavaScript v prostredí Java.

Prvý príklad použitia tohto relatívne ľubovoľného spracovania JavaScriptu využíva výhodu objektu JavaScript. Vzorový kód je uvedený ďalej.

 System.out.println ("Dnešný dátum:" + processArbitraryJavaScript ("var date = new Date (); var month = (date.getMonth () + 1) .toFixed (0)", "month", null) + " / "+ processArbitraryJavaScript (" var date = new Date (); var day = date.getDate (). toFixed (0) "," day ", null) +" / "+ processArbitraryJavaScript (" var date = new Date () ; var year = date.getFullYear (). toFixed (0) "," year ", null)); 

Tento kód určuje, že by sa mal načítať dátum JavaScriptu (ktorý bude aktuálnym dátumom) a že mesiac, dátum mesiaca a celý rok by sa mali extrahovať z tohto inštančného dátumu. Výstup pre toto sa zobrazí ďalej.

Posledný príklad pracoval na ľubovoľnom reťazci JavaScriptu, ale nepoužíval žiadne parametre. Nasledujúci príklad demonštruje poskytnutie parametrov tomuto ľubovoľnému spracovaniu reťazca JavaScriptu, pretože demonštruje použitie funkcie pow Java. Kód tohto príkladu je uvedený ďalej.

 final map exponentParameters = new HashMap (); exponentParameters.put ("základ", 2); exponentParameters.put ("exponent", 5); System.out.println ("2 až 5 je:" + processArbitraryJavaScript ("var answer = Math.pow (base, exponent)", "answer", exponentParameters)); 

Výstup zo spustenia tohto príkladu je uvedený na nasledujúcej snímke obrazovky.

Za môj posledný príklad tohto uverejnenia v blogu uvádzam štandard natiahnuť() výstup z ScriptException deklarované v niektorých predchádzajúcich príkladoch. The ScriptEngine.eval metóda hodí túto kontrolovanú výnimku, ak dôjde k chybe pri vykonávaní / vyhodnocovaní poskytnutého skriptu. Táto metóda tiež vyvolá NullPointerException, ak je zadaný reťazec null. Ďalej sa zobrazuje kód použitý na vynútenie chyby skriptu.

 / ** * Zámerne spôsobí chybu pri spracovaní skriptu, aby zobrazila typ informácií *, ktoré obsahuje výnimka ScriptException. * / public static void testScriptExceptionHandling () {System.out.println (processArbitraryJavaScript ("Garbage In", "none", null)); } 

Tento kód poskytuje nezmyselný skript (z hľadiska syntaxe JavaScriptu), ale to je presne to, čo je potrebné na demonštráciu ScriptException.toString (), ktorý sa volá ako súčasť spracovania výnimiek vo vyššie uvedenej metóde na spracovanie ľubovoľného reťazca JavaScriptu. . Po vykonaní kódu vidíme informácie o výnimke, ako je znázornené na nasledujúcom obrázku.

Časť výstupu, z ktorej pochádza ScriptException.toString () je časť, ktorá uvádza: „javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: missing; before statement (# 1) in in line number 1.“

The ScriptException obsahuje názov súboru, číslo riadku a číslo stĺpca výnimky, čo je obzvlášť užitočné, ak je na vyhodnotenie poskytnutý súbor s kódom JavaScript.

Záver

Java SE 6 umožňuje jednoduché použitie JavaScriptu v kóde Java. S Java môžu byť spojené aj ďalšie skriptovacie enginy, ale je užitočné mať jeden dodávaný priamo s Mozilla Rhino.

Kompletná snímka obrazovky kódu a výstupu

Pre úplnosť tu uvádzam kompletný zoznam kódov na jednom mieste a výsledný výstup potom.

JavaScriptInJavaExample.java

$config[zx-auto] not found$config[zx-overlay] not found