Ohjelmointi

JavaScriptiä

Viimeaikainen JavaLobby-viesti The Top 10 Unused Features in Java on ollut erittäin suosittu. Tämän kirjoituksen ajankohtana se on DZone Top Links -luokan parhaiten sijoittunut viesti. Lisäksi siihen on lähetetty vastaus. Molemmissa blogiviesteissä on paljon mielenkiintoisia havaintoja Java: n alikäytetyistä ominaisuuksista, ja olen samaa mieltä joidenkin kanssa enemmän kuin toiset. Huomioni todella kiinnitti kuitenkin väite, että Java SE 6 on yksi käyttämättömimmistä Java-ominaisuuksista.

Nautin todella työskennellä Java SE 6: n kanssa ja olen aiemmin kirjoittanut tai kirjoittanut Java SE 6: n ominaisuuksista useita kertoja. Tässä blogiviestissä aion osoittaa osan Java SE 6: n kyvystä isännöidä JavaScriptiä.

Useimmat Java-kehittäjät ja JavaScript-kehittäjät ymmärtävät, että neljän kirjaimen "J-A-V-A" lisäksi JavaScriptillä ja Javalla on vain vähän yhteistä muuta kuin jotkut C-tyyppiset perinteet. Silti voi olla ajoittain hyödyllistä suorittaa komentosarjakieli Java-koodista ja Java SE 6 sallii tämän.

Javax.script-paketti esiteltiin Java SE 6: n kanssa, ja se sisältää luokkia, käyttöliittymiä ja tarkistetun poikkeuksen, joka liittyy komentosarjakoneiden käyttöön Java-käyttöjärjestelmässä. Tämä blogikirjoitus keskittyy ScriptEngineFactory-, ScriptEngineManager-, ScriptEngine- ja ScriptException-palveluihin.

Yksi ensimmäisistä asioista, jonka haluat ehkä tehdä, on selvittää, mitkä komentosarjamoottorit ovat jo käytettävissä. Seuraava koodinpätkä osoittaa, kuinka helppoa tämä on tehdä Java SE 6: lla.

lopullinen ScriptEngineManager manager = uusi ScriptEngineManager (); for (lopullinen ScriptEngineFactory scriptEngine: manager.getEngineFactories ()) {System.out.println (scriptEngine.getEngineName () + "(" + scriptEngine.getEngineVersion () + ")"); System.out.println ("\ tLanguage:" + scriptEngine.getLanguageName () + "(" + scriptEngine.getLanguageVersion () + ")"); System.out.println ("\ tYleiset nimet / aliakset:"); for (viimeinen merkkijono engineAlias: scriptEngine.getNames ()) {System.out.println (engineAlias ​​+ ""); }} 

Yllä esitetty koodi tuottaa seuraavanlaisen kuvan, kuten seuraavassa kuvakaappauksessa.

Kuten tämä kuva osoittaa, Mozilla Rhino JavaScript-moottori sisältyy Sunin Java SE 6: een. Näemme myös joitain "yleisiä nimiä", jotka liittyvät tähän moottoriin. Mitä tahansa näistä nimistä voidaan käyttää tämän moottorin hakemiseen. Tämän postin myöhemmissä esimerkeissä käytän yleisnimeä "js" tähän hakuun.

Seuraava koodinäyte hyödyntää mukana toimitettua Rhino JavaScript -moottoria suorittaakseen jonkin Java-koodin Java-koodista. Tässä tapauksessa hyödynnämme JavaScriptin toExponential-toimintoa.

 / ** * Kirjoita numero eksponentiaalimuodossa. * * @param numberToWriteInExponentialForm * Eksponentiaalisessa muodossa edustettava numero. * @param numberDecimalPlaces * eksponentiaaliesityksessä käytettävien desimaalien määrä. * / public static void writeNumberAsExponential (lopullinen numero numberToWriteInExponentialForm, lopullinen int numeroDecimalPlaces) {lopullinen ScriptEngine-moottori = manager.getEngineByName ("js"); kokeile {engine.put ("inputNumber", numberToWriteInExponentialForm); engine.put ("decimalPlaces", numberDecimalPlaces); engine.eval ("var outputNumber = inputNumber.toExponential (decimalPlaces);"); final String exponentialNumber = (String) moottori.get ("outputNumber"); System.out.println ("Luku:" + eksponentiaalinumero); } catch (ScriptException scriptException) {LOGGER.severe ("ScriptException havaitsi yrittää kirjoittaa eksponentiaalista:" + scriptException.toString ()); }} 

Yllä oleva koodi kutsuu suoraan JavaScriptiä ScriptEngine.eval (String) -menetelmällä arvioidaksesi toimitetun merkkijonon, joka sisältää JavaScript-syntaksin. Ennen eval menetelmässä kaksi parametria "välitetään" (sidottu) JavaScript-koodiin ScriptEngine.put (String, Object) -kutsujen kautta. Suoritetun JavaScriptin tulosobjektiin pääsee Java-koodissa käyttämällä ScriptEngine.get (String) -kutsua.

Osoittaa yllä oleva koodi käyttämällä toExponential Käytän seuraavaa "asiakas" -koodia.

lopullinen int lähde numero = 675456; writeNumberAsExponential (lähdeNumero, 1, System.out); writeNumberAsExponential (lähdeNumero, 2, System.out); writeNumberAsExponential (lähdeNumero, 3, System.out); writeNumberAsExponential (lähdeNumero, 4, System.out); writeNumberAsExponential (lähdeNumero, 5, System.out); 

Kun yllä oleva koodi suoritetaan aiemmin esitettyä writeNumberAsExponential-menetelmää vastaan ​​ja käytetään JavaScriptiä, lähtö näyttää olevan samanlainen kuin seuraavassa näytön tilannekuvassa.

Tämä esimerkki riittää osoittamaan kuinka helppoa on kutsua JavaScriptiä toiminnallisuudeksi Java SE 6: n sisällä. Tämä voidaan kuitenkin toteuttaa vielä yleisemmin, kuten seuraavat kaksi esimerkkiä osoittavat. Ensimmäinen esimerkki osoittaa suhteellisen mielivaltaisen JavaScriptin kutsumisen ilman parametreja siirretty / sidottu ja toinen esimerkki osoittaa suhteellisen mielivaltaisen JavaScriptin kutsumisen parametreilla, jotka on siirretty / sidottu.

Suhteellisen mielivaltainen JavaScript-merkkijono voidaan käsitellä koodilla, joka on samanlainen kuin seuraavassa esitetty.

 / ** * Käsittele syötetty JavaScript-komentosarja, jonka tulisi sisältää määritys * muuttujalle, jonka nimi on annettu nameOfOutput ja * voi sisältää inputParametersin määrittelemiä parametreja. * * @param javaScriptCodeToProcess Merkkijono, joka sisältää JavaScript-koodin * arvioitavaksi. Tätä merkkijonoa ei tarkisteta minkään tyyppisen pätevyyden varalta, ja se voi mahdollisesti johtaa ScriptExceptionin heittämiseen, joka * kirjataan sisään. * @param nameOfOutput Lähdemuuttujan nimi, joka liittyy * toimitettuun JavaScript-komentosarjaan. * @param inputParameters Valinnainen parametrien nimikartta parametrien arvoihin *, joita saatetaan käyttää mukana olevassa JavaScript-komentosarjassa. Tämä kartta * voi olla tyhjä, jos komentosarjaan ei odoteta syöteparametreja. * / public static Object processArbitraryJavaScript (viimeinen merkkijono javaScriptCodeToProcess, viimeinen merkkijono nameOfOutput, lopullinen Map inputParameters) {Object result = null; lopullinen ScriptEngine-moottori = manager.getEngineByName ("js"); kokeile {if (inputParameters! = null) {for (viimeinen Map.Entry-parametri: inputParameters.entrySet ()) {engine.put (parametri.getKey (), parametri.getValue ()); }} engine.eval (javaScriptCodeToProcess); tulos = moottori.get (nameOfOutput); } catch (ScriptException scriptException) {LOGGER.severe ("ScriptException havaitsi yrittää kirjoittaa mielivaltaista JavaScript '" + javaScriptCodeToProcess + "':" + scriptException.toString ()); } palautustulos; } 

Yllä oleva koodi tarjoaa melko vähän joustavuutta käsiteltävän JavaScriptin suhteen. Tämä ei luultavasti ole paras idea tuotantokoodille, mutta se helpottaa Java-ohjelman eri JavaScript-ominaisuuksien käytön osoittamista.

Ensimmäinen esimerkki tämän suhteellisen mielivaltaisen JavaScript-käsittelyn käyttämisestä hyödyntää JavaScriptin Date-objektia. Näytekoodi näkyy seuraavaksi.

 System.out.println ("Päivän päivämäärä:" + 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) "," vuosi ", null)); 

Tämä koodi määrittelee, että JavaScript-päivämäärä tulisi noutaa (joka on nykyinen päivämäärä) ja että kyseinen kuukausi, kuukauden päivämäärä ja koko vuosi olisi purettava kyseisestä päivitetystä päivämäärästä. Tämän tulos näytetään seuraavaksi.

Viimeinen esimerkki toimi mielivaltaisella JavaScript-merkkijonolla, mutta ei käyttänyt mitään parametreja. Seuraava esimerkki osoittaa parametrien toimittamisen tälle mielivaltaiselle JavaScript-merkkijonokäsittelylle, koska se osoittaa JavaScriptin pow-toiminnon käytön. Tämän esimerkin koodi on seuraavassa.

 lopullinen Map exponentParameters = uusi HashMap (); exponentParameters.put ("base", 2); exponentParameters.put ("eksponentti", 5); System.out.println ("2 - 5 on:" + processArbitraryJavaScript ("var answer = Math.pow (pohja, eksponentti)", "vastaus", exponentParameters)); 

Tämän esimerkin suorittamisen tulos näkyy seuraavassa näytön tilannekuvassa.

Viimeisessä esimerkissä blogikirjoituksesta esitän standardin toString () tuotos ScriptException joissakin edellisissä esimerkeissä. ScriptEngine.eval method heittää tämän tarkistetun poikkeuksen, jos toimitetun komentosarjan suorittamisessa / arvioinnissa on virhe. Tämä menetelmä heittää myös NullPointerExceptionin, jos annettu merkkijono on tyhjä. Komentosarjavirheen pakottamiseen käytetty koodi näkyy seuraavaksi.

 / ** * Aiheuttaa tarkoituksellisesti komentosarjojen käsittelyvirheen näyttämään tietotyypit *, jotka ScriptException sisältää. * / public static void testScriptExceptionHandling () {System.out.println (processArbitraryJavaScript ("Garbage In", "none", null)); } 

Tämä koodi tarjoaa järjettömän komentosarjan (JavaScript-syntaksin kannalta), mutta juuri sitä tarvitaan osoittamaan ScriptException.toString (), jota kutsutaan osana poikkeusten käsittelyä yllä esitetyssä menetelmässä mielivaltaisen JavaScript-merkkijonon käsittelemiseksi. . Kun koodi suoritetaan, näemme poikkeustiedot seuraavan kuvan mukaisesti.

Tuloksen osa, josta se tulee ScriptException.toString () on osa, joka sanoo: "javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: puuttuu; ennen lausetta (# 1) rivillä 1."

ScriptException sisältää tiedoston nimen, rivinumeron ja sarakkeen numeron poikkeuksesta, mikä on erityisen hyödyllistä, jos arvioitavaksi toimitetaan tiedosto, jossa on JavaScript-koodi.

Johtopäätös

Java SE 6 helpottaa JavaScriptiä Java-koodissa. Muita komentosarjamoottoreita voidaan liittää myös Java: iin, mutta on kätevää, että yksi toimitetaan valmiina Mozilla Rhino -palvelun kanssa.

Täydellinen koodin ja tulostusnäytön tilannekuva

Täydellisyyden vuoksi lisäämään täydellisen koodiluettelon yhteen paikkaan tässä ja tuloksena olevan tuotoksen sen jälkeen.

JavaScriptInJavaExample.java

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