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.