JSP Veebindus on üheksakümnendatest aastatest alates pidevalt kasvanud ning mitmed firmad on jõudumööda lahendusi pakkunud, mis peaksid nii kasutajate kui programmeerijate elu kergemaks tegema. Algsete CGI- programmide kõrvale on mõeldud hulga vahendeid. CGI-programmiks võis olla igas keeles kirjutatud programm, mis kasutaja saadetud andmed sai keskkonnamuutujast (get-meetod) või standardsisendist (post-meetod) ning väljundi saatis standardväljundisse, mis sealt omakorda kasutajale suunati. Ajapikku mõeldi välja vahendeid, kus õnnestus vähema koodikirjutamisega luua veebilehti. Et ei peaks programmi sisse pikki staatilisi tekste kirjutama või neid mujalt failidest lugema, vaid et võiks üksikud arvutatavad kohad kergesti HTML-lehe sisse kirjutada. Nii loodi PHP, ASP ning kuna end veebispetsideks pidavad Java loojad ei tahtnud rongist maha jääda, tuli neilgi oma vahend selleks teha, mille nimeks sai Java Server Pages ehk JSP. Tutvustavates artiklites märgitakse, et kuna JSP loodi ASP-st hiljem, siis oli võimalik varem tehtud vigu arvestada ning JSP võimalikult töökindlaks ning rudimendivabaks teha. Võibolla on neil osalt õigus, aga eks igaüks pea omaloodut kiitma, oma laps ikka kõige armsam. Kirjutatav tekst püütakse jätta võimalikult HTMLi sarnaseks, et algsel tutvumisel vaatepilt liialt ära ei ehmataks. Programmi käsud ning väljastatavad väärtused tuleb kuidagi muust tekstist eristada. JSP (ning ASP) juures on koodi algustunnuseks "<%" ning lõputunnuseks "%>", nii et kogu kirjutatav tekst jääb nurksulgude ning protsendimärkide vahele. Kuna protsendiga algavat elemendi nime HTML-is pole, siis õnnestubki algul veebiserveris läbi vaadata lehe kood, käivitada sisse kirjutatud käsud ning saata tulemus kasutaja seilurile. Kui tahetakse avaldise väärtus lihtsalt kasutajale saata, siis tuleb koodiosa alustada sõnega "<%=". Tervitus Parim hinne koolis on <%=3+2 %> Kuidas kirjutatud lehekülg tööle ning teistele näitamiseks üles panna, see sõltub juba veebiserverist. Kui viimane suudab JSP lehti käivitada ning on konfigureeritud nii, et .jsp laiendiga failid loetakse JSP lehtedeks, siis piisab vaid loodud leht nähtavasse kataloogi paigutada ning töö tulemus ongi vaatamisel näha. Ehk tuntuim JSP-võimeline vabalt kasutatav veebiserver on Jakarta Tomcat, kuid selle võimalusega saavad kas otse või lisatud moodulite abil hakkama enamik tuntumatest veebiserveritest. JSP koodiosas võib Java keele käsklusi kasutada nagu igas muuski programmis. Kui Javas tuleb muutujad deklareerida, siis ka siin peab tsükli algul ütlema, et muutuja i on tüübist int ehk täisarv. Arvude ruudud ühest kahekümneni on:

<% for(int i=1; i<=20; i++){ %> <%= i*i+"
" %> <% } %> Suur osa aktiivsete veebilehtede võludest ja võimalustest on seotud sellega, et serveris koostatakse kasutajalt saadetud andmete põhjal temale sobiv lehekülg. Tavaliseks veebilehele andmete saatmise formaadiks on lehe aadressile järgnev küsimärk, mille järgi tulevad parameetrid ning nende väärtused. Näiteks nimeleht.html?nimi=Juku&vanus=15 . Käsu getParameter abil leitakse JSP lehel parameetri nime järgi kasutaja saadetud väärtus. Nime lugemine Tere, <%= request.getParameter("nimi") %> Vormi elementidesse sisestatud väärtused pannakse andmete saatmisel automaatselt sellisele kujule, et serveripoolne programm parameetrite nimede järgi väärtusi küsida oskab. Kui vormil on vaid üks tekstiväli, siis saadetakse andmed teele pärast välja teksti kirjutamist ning sisestusklahvi vajutamist. Muul juhul tuleb andmete teele saatmiseks lisada veel eraldi nupp (tüübiga submit) või anda Javaskripti abil vormile vastav käsk. Nime sisestamine Palun nimi:

Kui soovida mitmele lehele paigutada ühist päist, jalust või muud teksti, siis pole otstarbekas seda kõikjale kopeerida. Mõistlikum on lisatav plokk panna eraldi faili ning käsuga include see lehe koostamisel sinna sisse lugeda. Faili sisu kaasamine Failis on teade: <%@ include file="teade.txt" %> Nii testimise tarvis kui hilisema koodi mõistmise jaoks kasutatakse kommentaare. Pea igas enesest lugu pidavas programmeerimiskeeles on see võimalus olemas. HTMLi sisse saab JSP kaudu lisada kommentaare nagu iga staatilisegi veebilehe juurde. Alguseks . Ka Java keele juurde kuuluvad kommentaarid kahe kaldkriisuga väljakommenteeritava rea algul võetakse vastu. Lisaks saab silma alt ära kommenteerida terve käsuploki: alguseks <%-- ning lõpuks --%>. HTMLi kommentaar jääb veebilehe koodi näha ning kasutaja võib soovi korral vaadata, mida lehe sisse lisatud on. Teised veebiserverist kaugemale ei jõua ning jäävad kasutaja eest peidetuks. Kommentaarid <%-- varjatud kommentaar --%> <% //kommentaar koodi sees %> Keerulisemateks arvutusteks ning andmete pärimiseks ja säilitamiseks soovitatakse kasutada eraldi objekte. Põhimõtteliselt on võimalik suur osa käskudest pikkida veebilehte väljastava JSP lehe koodi sisse, kuid nõnda võib lehe ehitus raskelt jälgitavaks minna ning samuti pole võimalik loodud koodi edaspidi ilma kopeerimata muudes olukordades kasutada. Selliste eraldi kasutatavate komponentidega suheldakse ubade (Java Bean) tarvis loodud vahendite abil. Oad paigutatakse veebilehtedest hoopis eraldi kataloogidesse (kuhu täpselt, sõltub veebiserverist). Samu ube võivad kasutada mitmel lehel olevad programmid. Järgnevalt uba, mis on vajalik ühe nime meeles pidamiseks. package k1; import java.io.Serializable; public class Uba1 implements Serializable{ String nimi="Triin"; public void paneNimi(String nimi1){ nimi=nimi1; } public String annaNimi(){ return nimi; } public String tutvusta(){ return "Mu nimi on "+nimi; } } Lehel saab oa kasutusele võtta avaldisega jsp:useBean, märkides, mis nime all oaga suheldakse ning millisest paketist ja millisest klassist võetud käskudega on tegemist. Kui tuleks meeles hoida korraga mitu nime, siis võiks ka samast klassist ube rohkem olla. Igaühel lihtsalt oma nimi. Oa kasutamine <%=nimehoidja.tutvusta() %> <%nimehoidja.paneNimi("Katrin"); %>

Oa sees on nüüd <%=nimehoidja.annaNimi() %> Oa kirjeldamisel lisatud parameeter scope="session" tähendab, et oas paiknevad andmed ei hävine koos lehe väljastamisega, vaid kui sama kasutaja mõne aja (sessiooni kestus, vaikimisi paarkümmend minutit) pärast uuesti sama oa poole pöördub, on seal andmed, mis eelmisest külastusest jäid. Nii on võimalik iseenesest pideva ühenduseta HTTP protokolli abil luua kasutajale mulje nagu oleks tema andmed pidevalt meeles ning järgmisel korral mäletatakse, mida kasutaja viimati tegi. Kui eelmises näites teatati pidevalt, et nimeks on Triin, siis alla näitesse teisel korral sisenemisel on seal juba olemas eelmisest korrast meelde jäetud Katrin. Oa kasutamine <%=nimehoidja.tutvusta() %> <%nimehoidja.paneNimi("Katrin"); %>

Oa sees on nüüd <%=nimehoidja.annaNimi() %> Suure osa loodud ubade ülesandeks on andmebaasist saabunud teabe edastamine. JSP lehel saab küsida ning sisestada andmeid soovitud kujul, oa ülesandeks jääb draiveri ja ühenduste eest hoolitsemine ning niimoodi võib veebilehe kirjutaja eest peita tehnilise keerukuse ning jätta selle kergemini kogu asutuse peale paari asjatundja hooleks. Järgnev uba loob konstruktori käivitamisel ühenduse andmebaasiga ning see jääb avatuks kogu oa eluea jooksul. Avalikult kasutatavad on kolm meetodit on tabeli loomiseks, andmete küsimiseks ning sisestamiseks. Andmetabel koostatakse ainult ühe kirje ning ühe väljaga. Selles peaks leiduma poes parasjagu müüdavate pallide arv. Andmevahetusega seotud käsud algavad get-i ja set-iga seetõttu, et hiljem võiks palliarv'u oa omadusena kasutada. Kui sama suuruse muutmiseks on siinkirjeldatud kujul meetodid, siis suudetakse nende omadustega vastavas keskkonnas automaatselt ümber käia. package k1; import k1.*; import java.sql.*; public class Baasiuba1{ Connection cn; Statement st; public Baasiuba1(){ try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); cn=DriverManager.getConnection("jdbc:odbc:baas1", "", ""); st=cn.createStatement(); }catch(Exception e){ System.out.println(e); } } public void looBaas() throws SQLException{ String lause="CREATE TABLE pallid (kogus int);"; st.executeUpdate(lause); lause="INSERT INTO pallid (kogus) values ('0');"; st.executeUpdate(lause); } public void setPalliarv(int arv) throws SQLException{ String lause="UPDATE pallid SET kogus="+arv+";"; st.executeUpdate(lause); } public int getPalliarv() throws SQLException{ String lause="SELECT kogus FROM pallid;"; ResultSet rs=st.executeQuery(lause); rs.next(); return rs.getInt("kogus"); } } Baasiloomine tuleb käivitada tavalise käsklusega. Pallide arvu teada saamiseks piisab pallibaasi-nimelise oa omaduse palliarv küsimisest. <% pallibaas.looBaas(); %> Baas loodud

Baas loodud

Baas pallide arvu loomiseks õnnelikult loodud. Laos on palli. Lattu pallide lisamiseks tuleb see arv kõigepealt laohoidja käest kätte saada. Pallide lisamine

Pallide lisamine

Mitu palli lisatakse lattu?
Edasi saab jätta JSP lehe hooleks andmed oale edastada, kes siis tulemused tabelisse kannab. Pallide lisamine

Pallide lisamine

<% int olemas=pallibaas.getPalliarv(); int juurde=Integer.parseInt(request.getParameter("arv")); int kokku=olemas+juurde; out.println("Laos oli palle "+olemas+" lisatakse "+juurde+"."); pallibaas.setPalliarv(kokku); %> Laos on nüüd palli. Müümisel tuleb vastav jagu palle baasist eemaldada. Pallide eemaldamine

Pallide eemaldamine

<% int olemas=pallibaas.getPalliarv(); int maha=Integer.parseInt(request.getParameter("arv")); int tulemus=olemas-maha; out.println("Laos oli palle "+olemas+" väljastada soovitakse "+maha); if(tulemus<0){ out.println("Väljastada saab vaid "+olemas+" palli"); tulemus=0; } pallibaas.setPalliarv(tulemus); %> Lattu jäi palli. RMI Suuremate programmide puhul pole kõike võimalik ega otstarbekas ühes masinas teha. Kui ühes masinas on tähtsad andmed ning kas mahu või turvalisuse mõttes pole neid mõistlik laiali kopeerida, siis võiks see andmemasin pigem pakkuda teistes masinates töötavatele programmidele võimalust teenusena suurest andmehulgast sobival kujul väljavõtteid teha. Sama kehtib ka suurt arvutusjõudlust vajavate ülesannete kohta. Tõenäoliselt on otstarbekas osta ettevõttesse üks võimas arvuti, mis raskemad ülesanded enese kanda võtaks, kui et püüda sadu masinaid sellisele tasemele viia, et nad triljoneid tehteid nõudvate operatsioonidega mõistliku aja jooksul hakkama saaksid. Eraldiseisvate masinate puhul oleks tõenäoliselt ikka märkimisväärne osa ressursse suuremal osal ajast kasutamata. Võrgu kaudu andmevahetuse ja tööülesannete jagamise võimalusi on mitmeid. Eks need allpool taanduvad ikka IP ning TCP ja UDP peale, kuid vastavalt eesmärgile on sinna juurde ehitatud mitmeid vahendeid programmeerijate töö hõlbustamiseks. Pea kõik võimalikud ühendused saab ise kirjutada ServerSocketi ning Socketi abil loodud ühenduskanalist küsitud voogude peale, kuid mõnikord võib enamvähem töökindlalt töötava süsteemi loomine hulga aega võtta ning tasub vaadata, äkki on meie eest juba märkimisväärne osa tööd ära tehtud. Andmebaasidega suheldes saab ühendussõnes määrata, millise masina juurde kuuluva baasiga suhelda. Kui tehnilisi probleeme ei teki, siis võib programmi sees kasutada kaugelt külge haagitud baasi sama edukalt kui andmeid kohalikult kettalt. URLConnectioni abil veebilehti lugedes piisab samuti vaid kord määrata, kus asuva dokumendiga plaanis suhelda on, edaspidine töö juba tehakse koodi kirjutaja tarvis nähtamatult. Kui on tarvis saata andmeid sõnest või lihttüüpidest keerukamalt, siis aitab objektivoog ning Serializable liides. Soovides aga üht objekti kaugelt kasutada, selle tarvis on välja töötatud Remote Method Invocation ehk RMI. Siinseid vahendeid kasutades võib programmeerijale jätta mulje nagu saaks ta otse suhelda teises masinas asuva objektiga, selle meetodeid kasutada ning omadusi muuta. Et mõlemas masinas paiknevad programmid teaksid, milliste omadustega ühise objektiga tegemist on, tuleb need meetodid liideses kirja panna. RMI abil kasutatavat isendit kirjeldav liides peab laiendama liidest java.rmi.Remote, millega kaasneb ühtlasi õigus osaleda RMI toimingutes. Kõik liideses kasutatavad meetodid peavad lubama heita java.rmi.RemoteException'i, et oleks võimalik teada anda ühenduse käigus tekkivatest probleemidest. import java.rmi.*; public interface Arvutaja extends Remote{ public int liida(int a, int b) throws RemoteException; } Tegelik realisatsioon tuleb kirjutada liidest realiseerivasse klassi. Tegemist on täiesti tavalise liidese realiseerimisega, kus tuleb klassi sisse paigutada kõik liideses kirjeldatud meetodid. public class Koolilaps implements Arvutaja{ public int liida(int a, int b){ return a+b; } } Failid valmis kirjutatud, võib nad kompileerida. Edaspidiseks andmevahetuse korraldamiseks tuleb klass, mis hoolitseks funktsioonide parameetrites edastatavate objektide ülekandmise eest. Genereerimistöö teeb meie eest ära standardvarustusse kuuluv programm rmic. Tuleb vaid kirjutada rmic Koolilaps ning kataloogi tekivad failid Koolilaps_stub.class ning Koolilaps_skel.class. Kui tegemist on 1.2 või kõrgema versiooniga, siis võib kirjutada rmic -v1.2 Koolilaps ning luuakse vaid fail Koolilaps_stub, mis edasiste tüübimuunduste ning ülekannete eest hoolitseb. Loodud objekt tuleb maailmale välja kuulutada, et seda RMI kaudu kasutada võimalik oleks. Kirjeldatu peaks olema lühim moodus isendi välja jagamiseks. Klassist luuakse ühiseks kasutamiseks mõeldud isend (new Koolilaps()) ning küsitud registrisse registreeritakse see nime alla arvutamine. Kui edaspidi mõni programm serverimasina RMI registrist vastava nime alt teenust küsib, siis väljastatakse kasutajale juurdepääs loodud isendile. import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; public class RMIServer1{ public static void main(String argumendid[]) throws Exception{ LocateRegistry.getRegistry().rebind("arvutamine", UnicastRemoteObject.exportObject(new Koolilaps())); } } Sama programmi saab ka veidi ilusamini kirjutada, kuid seetõttu paratamatult kasvab ühes sellega ka koodiridade hulk. Nüüd õnnestub programmi töö pärast reavahetusklahvile vajutamist viisakalt lõpetada. Enne seda võimalust polnud. import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; import java.io.*; public class RMIServer2{ public static void main(String argumendid[]) throws Exception{ Koolilaps juku=new Koolilaps(); Arvutaja kooliesindaja=(Arvutaja)UnicastRemoteObject.exportObject(juku); Registry register=LocateRegistry.getRegistry("localhost", 1099); register.rebind("arvutamine", kooliesindaja); System.out.println("Server korras"); new BufferedReader(new InputStreamReader(System.in)).readLine(); //oodatakse reavahetust register.unbind("arvutamine"); UnicastRemoteObject.unexportObject(juku, true); } } Sama masina piires suudab klassi java.rmi.Naming meetod lookup nime järgi küsida liidesele vastava isendi, mille kaudu saab serveris välja jagatud objektiga suhelda. import java.rmi.*; public class RMIKlient1{ public static void main(String argumendid[]) throws Exception{ Arvutaja a=(Arvutaja)Naming.lookup("arvutamine"); System.out.println(a.liida(3, 2)); } } Kui välja jagamine toimub eraldi masinas (mis peaks ka tavaline olema), siis tuleb aadressi märkida kõigepealt masin ja värat, kustkaudu objekti otsida. Et RMI vaikimisi pordiks on 1099, siis võib alltoodud aadressirea kirjutada ka kujul rmi://jaagup.cs.tpu.ee/arvutamine. import java.rmi.*; public class RMIKlient2{ public static void main(String argumendid[]) throws Exception{ Arvutaja a=(Arvutaja)Naming.lookup("//jaagup.cs.tpu.ee:1099/arvutamine"); System.out.println(a.liida(Integer.parseInt(argumendid[0]), Integer.parseInt(argumendid[1]))); } } Et kasutajad üle võrgu saavad ligi ühele samale objektile, siis ei pruugi see arvutada mitte ainult teenusekasutaja enese antud andmetega, vaid panna oma töö sõltuma ka teiste kasutajate tegevustest ning muudest andmetest, mis objektil õnnestub ilma pealt hankida. Tõlkimine Kui on arvata, et programmi võivad tarvitada mitmesuguse keelega kasutajad, siis oleks ilus, kui saaks suhteliselt vähese vaevaga väljundi neile loetavaks teha. Lühikese programmi puhul võib lähtekoodis paar sõna ära vahetada ning tulemus ongi oodatu. Pikema programmi puhul läheb see aga tülikaks, samuti ei pruugi olla käepärast ei kompilaatorit ega programmeerimiskeelt tundvat inimest. Sellisel juhul on otstarbekas keeleline osa põhiprogrammist välja tuua. Java keeles on paketis java.util selle tarbeks mõned klassid. Nõnda korraldades jäävad koodi sisse vaid tekstide väljakutsed. Tegelik sisu on igale keelele vastavas failis. Rakenduse ning andmefailide vahendajaks on ResourceBundle, millele öeldakse Locale abil, millisele keelele vastavat sõnastikku tuleks otsida. Locale("et", "EE") tähendab, et mõeldakse eesti keelt Eestimaal. Kolmanda parameetrina võib soovi korral märkida juurde murraku. import java.util.*; public class Tolge1 { public static void main(String argumendid[]){ ResourceBundle sonastik=ResourceBundle.getBundle( "Tolge1Sonastik", new Locale("et", "EE") ); System.out.println(sonastik.getString("hello")+ ", "+sonastik.getString("name")); } } Tõlge eesti keelde ListResourceBundle puhul tuleb väljastatavad objektid väljastada kahemõõtmelise kaheveerulise massiivina, kus igale võtmele vastab väärtus. Staatilisel juhul peaks lihtsaim olema korraldada, luues algul soovitud objekt ning meetodi käivitamisel väljastada osuti objektimassiivile. import java.util.*; public class Tolge1Sonastik_et extends ListResourceBundle{ public Object[][] getContents(){return sisu;} Object[][] sisu={ {"hello", "Tere"}, {"name", "Juku"} }; } Tõlge soome keelde Analoogiliselt tõlgitakse ka muudesse keeltesse. Vastavalt peaprogrammis ette antud Locale'le otsitakse sobivale keelele vastav sõnastik. Nagu näha, kui sõnastiku üldnimeks anti väljakutsumisel Tolge1Sonastik, siis eesti keele sõnad leiab klassist Tolge1Sonastik_et ning soome keele omad Tolge1Sonastik_fi . import java.util.*; public class Tolge1Sonastik_fi extends ListResourceBundle{ public Object[][] getContents(){return sisu;} Object[][] sisu={ {"hello", "Terve"}, {"name", "Jukka"} }; } Vaikimisi tõlge inglise keelde Kui Locale-le vastavat sõnastikku ei leitud, siis minnakse algnimega sõnastikku otsima, millest süsteemi loojate arvates peaks leidma ingliskeelse kujundise. import java.util.*; public class Tolge1Sonastik extends ListResourceBundle{ public Object[][] getContents(){return sisu;} Object[][] sisu={ {"hello", "Hello"}, {"name", "John"} }; } Sobiva sõna otsimise hierarhia võib päris pikaks ajada. Nagu ennist öeldud, minnakse kõige viimases hädas otsima laiendita sõnastiku juurde. Enne seda aga on veel mitu astet. Locale parameetrite juures tähistas esimene keelt, teine riiki. Kui otsitud sõnastikku ei leita soovitud keele ja riigiga (Tolge2Sonastik_et_EE), siis uuritakse, kas vastava keelega sõnastik on olemas (Tolge2Sonastik_ee). Aste kangem on veel kolmas parameeter: see võib tähistada murret (saare, setu), kuid võib olla ka muud sorti eristuseks (WIN_MAC). import java.util.*; import java.io.*; public class Tolge2 { public static void main(String argumendid[]){ ResourceBundle sonastik=ResourceBundle.getBundle( "Tolge2Sonastik", new Locale("et", "EE") ); System.out.println(sonastik.getString("hello")+", "+ sonastik.getString("name")+". "+ sonastik.getString("greeting")+"."); } } Tõlgete lugemine eraldi tekstifailist Koodi kirjutamine on suhteliselt tüütu ja veaothlik, eriti väiksema kogemuse korral. Hulga lihtsam on sobivad vasted lihtsalt tekstifaili kirjutada. Kui sõnastik on tehtud PropertyResourceBundle alamklassina, siis võib konstruktoris välja kutsuda ülemklassi konstruktori, andes sinna parameetriks sõnade tekstifailist lugemise vahendi. import java.util.*; import java.io.*; public class Tolge2Sonastik_et extends PropertyResourceBundle{ public Tolge2Sonastik_et() throws IOException { super(Tolge2Sonastik.class.getResourceAsStream( "Tolge2Sonastik_ee.properties")); } } Tolge2Sonastik_ee.properties: hello=Tere name=Juku Mida eestikeelseks määratud sõnastikust ei leita, seda asutakse otsima tase kõrgemalt keeleta sõnastikust. import java.util.*; import java.io.*; public class Tolge2Sonastik extends PropertyResourceBundle{ public Tolge2Sonastik() throws IOException { super(Tolge2Sonastik.class. getResourceAsStream("Tolge2Sonastik.properties")); } } Tolge2Sonastik.properties: hello=Hello name=John greeting=Good morning Numbriformaat Numbrite vormindamine on Javaga alustades küllalt vaevaline tegevus. Kui C-s aitab sprintf ning Pascalis võib komakohtade arvu lihtsalt kooloniga paika panna, siis Javas on tahetud vahendeid täiuslikemateks teha ning seepärast tundub algne kasutamine veidi puisem olema. Paketis java.text on tosinajagu klasse nii kuupäeva, numbrite kui muude andmete vormindamiseks. Kaks kohta pärast koma Väljastatava numbri kuju saab malliga ette anda pea sarnaselt kui mõnele ehk tuttavas MS Excelis. Nullide kohal peavad olema arvud, trellide kohal võivad olla. import java.text.*; public class Numbriformaat1{ public static void main(String argumendid[]){ System.out.println(new DecimalFormat("0.00"). format(5.7362)); } } väljund: 5,74 Lisatud tekst, eraldi negatiivsed arvud import java.text.*; public class Numbriformaat2{ public static void main(String argumendid[]){ DecimalFormat df=new DecimalFormat("0.00 kr;puudu # kr"); System.out.println(df.format(-5.7362)); System.out.println(df.format(5.1)); System.out.println(df.format(14)); } } väljund: puudu 5,74 5,10 kr 14,00 kr Pikema numbri tervikute eraldamine vahedega Mall tuleb kirjutada Java standardite järgi, kus punkt tähistab murdosa eraldajat ning komaga grupeeritakse täisosa arve. Grupid võetakse nii suured, kui mitu sümbolit on murdosa eraldaja ning temale lähima grupeerija vahel. Järelikult, kui sooviksin andmeid tuhandete kaupa grupeerida, siis tuleks koma mallis ühe koha võrra vasakule nihutada. Väljatrüki tarvis võib eraldaja määrata vastavalt soovile, siin meile tavapärase tühikuna. import java.text.*; import java.util.Locale; public class Numbriformaat3{ public static void main(String argumendid[]){ DecimalFormatSymbols dfs=new DecimalFormatSymbols(); dfs.setDecimalSeparator(','); dfs.setGroupingSeparator(' '); DecimalFormat df=new DecimalFormat("#,#0.00", dfs); System.out.println(df.format(5.7362)); System.out.println(df.format(51432)); System.out.println(df.format(14732829)); } } väljund: 5,74 5 14 32,00 14 73 28 29,00 Keelele vastav numbri väljastus Locale määramise puhul püütakse väljund vormistada vastava maa reeglite kohaselt ka siis, kui vaikimisi on arvutis mõni muu keel ja maa määratud. Eelnevates näidetes punkti ja koma kasutamine sõltus oluliselt sellest, kuidas need setingud arvutis määratud olid. Võimaluse korral soovitataksegi vormindamisel kasutada NumberFormat'i meetodeid, küsides vastava isendi ning määrates sel komakohtade arvu ja muudki. import java.text.*; import java.util.Locale; public class Numbriformaat4{ public static void main(String argumendid[]){ NumberFormat nf=NumberFormat.getInstance( new Locale("et", "EE")); System.out.println(nf.format(31345.543)); } } väljund: 31 345,543 Teksti ja lauseehituse määramiseks on loodud MessageFormat, arvule vaste seadmiseks ChoiceFormat.