edellinen
seuraava
 

5.     Sovelluksen eri osat 1

5.1        Äly eli logiikka. 1

5.2        Tieto. 2

5.3        Käyttöliittymä. 2

5.3.1     Käyttöliittymän ohjelmointi appleteilla. 2

5.3.2     Käyttöliittymän ohjelmointi JavaScriptillä. 4

5.3.3     Tietojen validointi palvelinpuolella. 5

Yhteenveto ensimmäisestä osasta. 6

Osan 1 koodit 6

6.     Osa 2 - Servletit 7

5.4        Servlettien elinkaari 7

5.5        Säikeet 8

5.6        ServletContext ja alustusparametrien käyttö. 8

5.6.1     Esimerkki 9

Tulostuksesta. 10

Init-metodista. 10

Kirjastoista. 10

5.7        Sessiot eli istunnot 10

5.7.1     Ostoskori 11

EncodeURL. 11

Session luominen ja käyttö. 12

Huomautus sessioista JSP sivuissa. 12

Huomautus selaimista. 12

 

5.      Sovelluksen eri osat

Web sovellus jakaantuu perinteisesti kolmeen osaan (MVC[1])

Näiden kolmen kerroksen erillään pitäminen on tärkeää varsinkin sovelluksen ylläpidon kannalta.

5.1         Äly eli logiikka

Javalla web sovellusta tehdessä on oleellista käyttää hyväkseen papuja (Java Beans[2]), joihin sovelluksen varsinainen äly eli toiminnallisuus koodataan.  Näin toimiessa on helppoa muuttaa käyttöliittymää tai ohjelmalogiikkaa myöhemmin. Tämä mahdollistaa myös sen, että eri henkilöt tekevät käyttöliittymän ja toiset logiikan. Kannattaa huomata myös hyvin tehtyjen luokkien uudelleenkäytön mahdollisuus.

Eräs esimerkki papujen hyödyistä olisi valuuttojen käyttö. Mikäli ennen euroihin siirtymistä aiempi valuutta (Suomen markka) olisi koodattu suoraan käyttöliittymään, olisi kaikki nämä käyttöliittymän osat jouduttu koodaamaan uudestaan. Jos sovelluksessa olisi käytetty papua, olisi riittänyt koodata uudestaan  get-metodi, joka välittää valuutan tiedot.

Tyypillisesti esimerkiksi tietokannasta haku tehdään seuraavasti papuja hyödyntäen

Pavuista lisää myöhemmin[3].

5.2         Tieto

Tyypillisesti sovelluksen käsittelemä tieto on tietokannassa. Tietokanta voi sijaita samalla palvelimella kuin sovelluskin.

Javassa tietokantoja käsitellään JDBC[4] (Java Database Connectivity) API:n avulla.

5.3         Käyttöliittymä

Käyttöliittymä muodostetaan tyypillisesti html-sivuilla ja JSP sivuilla. Tyypillisesti käyttöliittymä on siis html-pohjainen, mutta tietyissä tapauksissa ohjelman logiikkaa voidaan siirtää asiakkaan puolelle.

Periaatteessa kaiken voisi tehdä palvelinpuolella, mutta on huomattavasti järkevämpää hoitaa osa toiminnasta asiakkaan selaimessa. Varsinkin asiakkaan antamat tiedot kannattaa tarkastaa ennen kuin ne lähetetään palvelimelle esimerkiksi talletettavaksi tietokantaan.

Tietojen tarkastamisessa asiakkaan puolella on käytännössä kaksi vaihtoehtoa (muita esim. flash[5]):

  1. Appletit
  2. Scriptikielet  kuten JavaScript

5.3.1    Käyttöliittymän ohjelmointi appleteilla

Appletteja[6] käyttämällä pystyt hyödyntämään Java kielen ominaisuuksia. Appletin rakentaminen on helppoa visuaalisten editorien kuten Borlandin Jbuilderin[7] avulla. Tosin applettien lataaminen on hidasta niiden suhteellisen ison koon takia.

Appletilla saat tosin tehtyä kohtuullisen helposti dynaamisia käyttöliittymiä, sillä ne voivat kommunikoida servlettien ja JSP sivujen kanssa (lähde [1].  sivu 228) käyttäen URLConnection[8] luokan oliota jonka avulla appletti saa syötteenä kaiken servletin standardi tulostuksen.

Esimerkkinä AppletServletApplet.html.

 

Kuva 1.   Appletti, joka kutsuu servlettiä ja näyttää haun tulokset

Esimerkissä tarvittavat tiedostot:

Koodeihin ei aloittelijan kannata vielä tässä vaiheessa tarkemmin perehtyä.

Jos et saa esimerkkiä toimimaan, koita käyttäen sivua AppletServletAppletConverted.html. Sivu on käsitelty HTMLConverter[9] ohjelmalla, jonka avulla varmistetaan Java PlugIn:n käyttö. Toinen testattava asia on korvata localhost koneesi IP osoitteella[10].

Toinen tapa, jolla palvelimelta voidaan välittää tietoa appletille on appletin parametrit. Palvelin generoi html-sivun, johon appletti ladataan. Samalla generoidaan sivulle vaihteleva määrä parametreja.

Mielestäni appletteja kannattaa käyttää vain jos tarvitaan todella näyttävää (jos html ja skriptit eivät riitä) tai korkeampaa logiikkaa vaativaa käyttöliittymää. Appleteissa on omat hyvät puolensa, mutta valitettavasti suurin haitta on selainten tuki ja toiminta. Eri selaimet saattavat näyttää appletin erilailla ja osassa selaimista appletti ei välttämättä toimi lainkaan. Muista aina testata ohjelmasi usealla selaimella. 

5.3.2    Käyttöliittymän ohjelmointi JavaScriptillä

Scriptikielillä kuten JavaScriptillä[11] on näppärää ja helppoa (ei tosin kovin ohjelmoinnillisesti eleganttia) suorittaa pieniä tarkastuksia ja käyttöliittymän viilauksia tapahtumien sekä funktioiden avulla.  Huomattavaa on, että tarkastus pitää suorittaa myös palvelimella, sillä asiakkaalla ei välttämättä ole JavaScript päällä selaimessa.

Seuraavassa pieni esimerkki, jossa tarkastetaan seuraavat asiat ennen kuin lomakkeen tiedot lähetetään palvelimelle. Palvelimella servletti näyttää annetut tiedot. Asiakkaan selaimella tarkastetaan seuraavat tiedot JavaScriptiä käyttäen:

 Mikäli jokin näistä ei pidä paikkaansa, käytetään selaimen alert-metodia näyttämään virheilmoitus käyttäjälle. Väärät kentät myös voitaisiin tyhjentää (tässä oltava erittäin varovainen. Jos käyttäjä on kirjoittanut esim. 256 merkkiä ja raja on 255, niin häntä saattaa ottaa rajusti pannuun jos ohjelma tyhjentää kentän ja käyttäjä joutuu näpyttelemään tekstinsä uudestaan), scriptissä kenttien tyhjennys kommentteina.

 <servlet>

    <servlet-name>Jep</servlet-name>

    <servlet-class>Jep</servlet-class>

 </servlet>

Nyt testaa lomakkeen toimintaa osoitteessa tutor/tarkistus.htm. Testaa ensin kaikki väärät syötteet.

Painettuasi lähetä tiedot painiketta kutsutaan Jep servlettiä, joka tulostaa seuraavanlaisen HTML-sivun. Parametrit ja niiden arvot on laitettu taulukkoon (sivujen ulkonäöstä ei kannata välittää. Tästä ei ollut tarkoituskaan tulla käyttöliittymäopasta).

Kuva 2.   Servletti tulostaa lomakkeen tiedot

5.3.3    Tietojen validointi palvelinpuolella

Lomakkeen tietojen tarkistaminen on toki mahdollista myös JSP:llä ja servleteillä. Jos tiedot eivät ole oikein, tulostetaan käyttäjälle lomake uudestaan. HTTP:n  tilattomuudesta johtuen tässä on huonona puolena se, että käyttäjä saa eteensä tyhjän lomakkeen ja joutuu kirjoittamaan kaiken uudestaan. Jos käytät tällaista tekniikkaa, niin pyri siihen, että tulostaessasi lomakkeen käyttäjälle uudestaan täytettäväksi, laita käyttäjän aiemmat syöttötiedot suoraan lomakkeelle valmiiksi.


Yhteenveto ensimmäisestä osasta

Nyt kun olet saanut Tomcatin asennettua ja configuroitua, olet saanut toimintaan jsp-sivun sekä servletin, on aika pitää tauko. Seuraavassa osassa tutustutaan Tomcattiin tarkemmin.

Osan 1 koodit

 Saat koko ensimmäisen osan websovelluksen toimintaan purkamalla tutor_osa1.zip paketin ja kopioimalla tutor hakemiston webapps\tutor hakemiston päälle. Paketti sisältää kokonaisuudessaan seuraavat tiedostot:

 Lisäksi


6.       Osa 2 - Servletit

Web sovellusten ohjelmointi Javalla on kohtuullisen helppoa ja selkeää.  Servletit tarjoavat helpon tavan kommunikoida web asiakkaiden[12] (web clients), tyypillisesti selainten, kanssa. Servlettien ohjelmoijan ei tarvitse huolehtia verkkoyhteyksien luomisesta, pyyntöjen (request) kiinniottamisesta, protokollien eri versioista eikä vastauksen (response) ohjaamisesta oikealle asiakkaalle. Lisäksi kuten Javassa on tapana, servlettien muistiin lataaminen  ja muistin vapauttaminen eivät ole ohjelmoijan rasitteena. Nämä kaikki yksityiskohdat hoitaa servlettimoottori (servlet engine, servlet container) kuten Tomcat.

Seuraavat esimerkit on tehty Java Servlet Development Kit (JSDK) versiolla 2.3, mutta esimerkit toimivat myös aiemmilla JSDK versioilla (testasin esimerkit myös versiolla 2.1).

Servlettien testaamiseen on olemassa hyvä työkalu ServletRunner[13] (JSDK:ssa mukana) minkä kanssa et tarvitse erillistä servlettimoottoria.

5.4         Servlettien elinkaari

 Tyypillisesti servlettien elinkaari kattaa seuraavat vaiheet [1].

  1. Servletti ladataan muistiin joko servlettimoottorin käynnistyessä (vaatii määrityksen sovelluksen web.xml tiedostoon) tai kun servlettiä ensimmäistä kertaa kutsutaan asiakkaan toimesta (oletus).   
  2. Servlettimoottori kutsuu servletin init-metodia . Servlet API takaa, että metodi suoritetaan loppuun ennen kuin yhtään pyyntöä aletaan käsitellä. Init-metodissa hoidetaan yleensä servletille tyypilliset alustukset kuten connection poolingin[14] alustus.
  3. Servlettimoottori luo asiakkaan pyynnössä välittyvästä datasta oliot joita käyttäen servletti kommunikoi asiakkaan kanssa (HttpServlet[15] luokan perivissä servleteissä (yleisin) luodaan HttpServletRequest[16]- ja HttpServletResponse[17]–rajapinnan toteuttavat oliot)
  4. Servletti vastaa asiakkaan pyyntöihin ylikirjoittamillaan metodeilla (tyypillisesti doGet tai doPost)  
  5. Vaiheita 3 ja 4 toistetaan satunnaisesti aina kun servlettiä kutsutaan.  
  6. Lopuksi servletti poistetaan muistista. Tällöin suoritetaan servletin destroy-metodi, jossa tyypillisesti esimerkiksi varmistetaan tietokantayhteyksien sulkeminen.

5.5         Säikeet

Oletetaan, että asiakkaan palveleminen kestää suhteellisen kauan, esim. doGet-metodin suoritus. Miten voidaan tällöin taata, että samanaikaisesti voidaan palvella muita asiakkaita? Kuten kappaleen otsikko vihjaa, vastaus on säikeet. Servletti on koodattava säieturvalliseksi (thread safe), sillä Servlet API ei sitä automaattisesti takaa. Tämä suoritetaan käytännössä viljelemällä synchronized termiä joko metodien otsikossa tai suoritettavien lauseiden yhteydessä.

Säieturvallinen koodi edellyttää luokan attribuuttien käytön suojaamista. Paikallisista muuttujista ei tarvitse olla huolissaan. Helppo mutta kustannustehoton tapa on synkronoida koko metodi seuraavasti

private synchronized void metodi ()

Tämä on hyväksyttävää lähinnä suoritukseltaan lyhyiden metodien yhteydessä tai jos kuitenkin lähes kaikki metodin koodi joudutaan synkronoimaan. Toinen tapa on synkronoida ainoastaan osia metodista seuraavasti.

private void metodi()

{

    synchronized ( this ) {

 //Nyt vain yksi säie voi suorittaa tämän koodilohkon yhtäaikaa

    }

    //koodia, joka ei ole synkronoitu

}

Voidaan myös käyttää SingleThreadModel-rajapintaa[18], jolloin taataan, ettei kaksi säiettä pääse yhtä aikaa samaan metodiin käsiksi, vaan odotetaan kunnes yksi asiakas on palveltu. Tässä on haittapuolena palvelun huomattava hidastuminen asiakasmäärän kasvaessa.

Lisää säikeistä ja synkronoinnista luettavissa esimerkiksi osoitteesta http://java.sun.com/docs/books/tutorial/essential/threads/

5.6         ServletContext ja alustusparametrien käyttö

Alustusparametreilla voidaan välittää servleteille tietoja, joita ne tarvitsevat käynnistyessään ja joita on helppo muokata.  Esimerkkinä mainittakoon tietokantayhteyksissä tarvittavat tiedot.

Oletetaan, että haluaisit asettaa jokaiselle sovelluksesi servletille ja JSP:lle jonkin yhteisen tiedon, tavallaan globaalin muuttujan. Miten tämän voisi toteuttaa? Yksi vaihtoehto olisi käyttää ServletContext-oliota, ja ladata sinne servlettiä käyttäen tarvittava data.

5.6.1    Esimerkki

Esimerkissä katsotaan seuraavia asioita:

·        ServletContexti-olion käyttäminen

·        Servletin lataaminen palvelimen käynnistyksen yhteydessä

Esimerkissä käytetään kahta servlettiä. Ensimmäinen servletti LataaContextServlet.java on oleellinen, sillä se alustaa ServletContext-olioon tarvittavan tietorakenteen. Tärkeätä onkin, että tämä servletti ladataan muistiin Tomcatin käynnistyessä ja vieläpä ensimmäisenä. Tämä saadaan aikaan muokkaamalla web.xml tiedostoa seuraavasti[19]:

 <servlet>

  <servlet-name>LataaContextServlet</servlet-name>

  <servlet-class>LataaContextServlet</servlet-class>

   <init-param>

    <param-name>titleBegin</param-name>

    <param-value>WebApplication tutoriaali - </param-value>

  </init-param>

  <load-on-startup>1</load-on-startup>

</servlet>

Esimerkin saat toimintaan asettamalla servletit WEB-INF/classes hakemistoon, muokkaamalla web.xml tiedostoa ja käynnistämällä Tomcatin uudelleen (tai pelkän tutor WEBAPPin käyttäen Tomcatin manager-apuohjelmaa). Uudelleenkäynnistys aiheuttaa sen, että servletit initialisoidaan. Itse asiassa servletit initalisoidaan joka kerta automaattisesti, kun olet muokannut web.xml tiedostoa, ja kutsut jotakin servlettiä/JSP sivua (Jos testaat tämän, muista sulkea kaikki selainikkunat ettei selaimen välimuisti sotke testauksiasi). Käynnistyksen jälkeen suunnista osoitteeseen:

 http://localhost/tutor/servlet/LueContextServlet

Tällöin huomaat, että selaimen otsikkorivillä lukee web.xml tiedostoon määritelty parametri, jonka LataaContextServlet on asettanut ServletContext-olioon. LueContextServlet puolestaan lukee arvon init-metodissa.

ServletContext-olion parametriolioiden asettaminen tapahtuu seuraavasti (ks. LataaContextServlet.java)

//luetaan alustusparametri, katso web.xml

String titleBegin = this.getServletConfig().getInitParameter("titleBegin");

System.out.println("titleBegin ==" + titleBegin);

 //asetetaan servletcontextiin kaikkien servlettien ja JSP-sivujen saataville

this.getServletContext().setAttribute("titleBegin", titleBegin);

ServletContext-oliosta ”lukeminen”  eli parametriolioiden käyttöönotto tapahtuu seuraavasti (ks. LueContextServlet.java ja LueContext.jsp):

 otsikonAlku = (String) this.getServletContext().getAttribute("titleBegin");

Tulostuksesta

Kaikki System.out virtaan kohdistettu tulostus on nähtävissä Tomcatin ikkunassa. Tämä on yksi keino tutkia servlettiesi suorituksia.

Tähän on kuitenkin yksi poikkeus: Servletin init-metodi. Itse varmistin, että servlettien init metodit todella tapahtuvat oikeaan aikaan luomalla molempien servlettien init-metodeissa tiedoston. Luotujen tiedostojen timestampistä selviää, milloin servlettien init-metodit tapahtuivat.

Init-metodista

Jos init metodissasi on virheitä, saat seuraavan virheilmoituksen:

 javax.servlet.ServletException: Cannot allocate servlet instance for path /tutor/servlet/LataaContextServlet

Kirjastoista

Kun laitat omia kirjastojasi WEB_INF\lib hakemistoon, laita tiedostot jar-pakettiin, vaikkei tiedostoja olisi kuin yksi. Muuten kirjastoasi ei oteta käyttöön, eivätkä servletit, joissa kirjastoja käytetään, toimi. Toki voit laittaa yksittäiset class-tiedostot WEB-INF\ classes hakemistoon

5.7         Sessiot eli istunnot

HTTP protokollan tilattomasta luonteesta  johtuen sessioiden käytön hallinta on lähes pakollista kaikissa web sovellusten tekemiseen soveltuvissa kielissä, niin myös Javassa.

Seuraavassa esimerkissä demonstroidaan sessioiden käyttö sekä servleteissä että JSP sivuissa.

5.7.1    Ostoskori

Esimerkkinä on rakennettu ostoskori, jossa ostokset tallennetaan sessiotietoihin. Lisäksi esimerkki sisältää yhden servletin ja JSP sivun, jotka näyttävät session tietoja.

Aseta ennen esimerkin testaamista selaimestasi evästeet (cookies) pois päältä!

Osta yksi JavaBean sivulta http://localhost/tutor/ShoppingCart.html. Sen jälkeen sinulle näytetään korissasi olevat ostokset.

 

Kuva 3.   Sessiotietojen käyttö ShoppingCart servletissä.

Testaa myös http://localhost/tutor/sessionTestaus.jsp, jossa on demonstroitu encodeURL metodin tärkeys myös JSP sivujen yhteydessä.

EncodeURL

Jos olet asettanut evästeet (cookies) pois päältä, niin linkit joissa lukee sulkeissa ”ei encodedURL” eivät toimi oikein. Seuraavassa selitys tähän.

Normaalisti sessiotietojen tallennukseen käytetään evästeitä. Mikäli kuitenkin evästeet on poistettu käytöstä, pitää session id numero tallentaa URL osoitteeseen (tai lomakkeen piilotettuihin kenttiin). Tämän vuoksi luodessasi sovelluksia, jotka käsittelevät sessioita, pitää kaikki osoitteet käsitellä erityisellä metodilla nimeltä encodeURL.

Eri asiakkaiden sessiotiedot erotellaan id-numerolla. Session id-numero pitää olla  joko asiakkaan selaimessa evästeenä, URL-osoitteessa parametrina tai lomakkeen piilotettuna kenttänä. Id numeron avulla palvelin tietää, kuka asiakas on kyseessä.

Metodeilla encodeURL ja encodeRedirectURL (käyttö kun haluat ohjata pyyntöjä eteenpäin) saat sessio id:n tallennettua osoitteeseen. Esimerkissä encodeURL metodia on käytetty seuraavasti

String URL = "http://localhost/tutor/session.jsp";

String encodedURL = res.encodeURL( URL);

Sessio id:tä ei kuitenkaan tallenneta osoitteeseen kahdessa tapauksessa

Session luominen ja käyttö

Session luominen ja käyttö tapahtuu käyttämällä HttpServletRequest[20] luokan metodia getSession.

// otetaan session objekti, luodaan jos ei ole olemassa

HttpSession session = req.getSession(true); 

Mikäli parametrilla on arvo true, sessio luodaan ellei sitä ole jo olemassa. Jos sessio on olemassa, se ainoastaan otetaan käyttöön. Mikäli parametrin arvo on false ja sessiota ei olemassa, palauttaa metodi arvon null.

Session attribuutteja käsitellään seuraavilla metodeilla (JSP 1.1 spesifikaatiossa)

·         putValue (String nimi, Object objekti) asettaa uuden attribuutin nimen ja arvon

·         getValue (String nimi) palauttaa attribuutin arvon ja null jos attribuuttia ei ole

Uudemmissa spesifikaatioissa suositellaan käytettäväksi setAttribute ja getAttribute metodeja. Metodien käyttö on täsmälleen samanlaista kuin niiden ”esi-isien” (esimerkeissä on käytetty molempia).  

Huomautus sessioista JSP sivuissa

JSP sivuihin sessioiden käyttö on ”sisään-rakennettu”, eli yhtenä JSP sivun implisiittisenä objektina on session. Älä siis luo sessiota äläkä ota käyttöön sessio objektia eksplisiittisesti, sillä objekti on olemassa automaattisesti.

Huomautus selaimista

Netscape Navigatorilla[21] sessioiden ja evästeiden testaaminen on huomattavasti helpompaa, koska evästeiden managerointi on hoidettu paremmin kuin Internet Explorerissa. Lisäksi Netscape näyttää tilarivillä linkissä olevan sessioID:n, IE[22] puolestaan ei. Itse asiassa en itse saanut IE:tä poistamaan evästeiden käyttöä käyttäessäni localhostia[23], vaikka kuinka yritin. Kielsin selaimen asetuksista evästeiden käytön, tyhjensin temporary internet files kansion ja suljin selaimen uudestaan. Silti sessiotiedot kyettiin lukemaan vaikkei linkkiä ollutkaan käsitelty encodeURL metodilla. Toiselta koneelta ajettuna IE:kin suostui toimimaan. Outoako?

Netscapella katsottaessa ShoppingCart servletin tulostaman html-sivun lähdekoodi on seuraavanlainen.

<html><head><title>Shopping Cart Contents</title></head><body>

<h1>Items currently in your cart</h1>

<hr>JavaBeanie Baby<br><hr><a HREF="../ShoppingCart.html">Back to the shop</a><br>

<a HREF="../session.jsp;jsessionid=9F590CDBA347EB83CAD40EB31C530C2A"> sessiotiedot JSP </a>

<br>

<a HREF="../session.jsp">sessiotiedot JSP(ei encodedURL)</a>

<br>

<a HREF="SessionInfoServlet;jsessionid=9F590CDBA347EB83CAD40EB31C530C2A">

sessiotiedot servlet</a>

<br>

<a HREF="SessionInfoServlet">sessiotiedot servlet(ei encodedURL)</a>

<br>

</body></html>

Kuten huomaat, session id-numero on liitetty linkin osoitteeseen. IE:llä vastaavaa ei tapahtunut localhostia käytettäessä, joten olettaa saattaa, että kaikesta kielloista huolimatta IE käytti evästeitä sessiotiedon tallentamiseen.

 



[1] Ks. http://java.sun.com/blueprints/patterns/MVC-detailed.html

[2] Spesifikaatio nähtävillä osoitteessa http://java.sun.com/products/javabeans/docs/spec.html

[3] Ks. kappale ” Pavuista eli JavaBeaneista”.

[4] Ks. http://java.sun.com/products/jdbc/

[5] Ks. http://www.macromedia.com/

[6] Ks. http://java.sun.com/applets/

[7] Ks. http://www.borland.com

[8] Ks. http://java.sun.com/j2se/1.4.2/docs/api/java/net/URLConnection.html

[9] Ks. http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/html_converter.html

[10] Windowsissa IP osoitteesi saat selville komennolla ipconfig.

[11] Selaimen ymmärtämä ohjelmointikieli. Huomaa, että eri selaimet ymmärtävät JavaScriptiä varsin vaihtelevasti.

[12] Asiakkaalla tarkoitetaan ohjelmaa, joka kommunikoi palvelimen kanssa

[13] Ks. http://java.sun.com/developer/onlineTraining/Servlets/Fundamentals/magercises/ServletRunnerHosting/

[14] Yhteysallas, käytetään useasti esimerkiksi tietokantojen kanssa.

[15] Ks. http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServlet.html

[16] Ks. http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/servlet/http/HttpServletRequest.html

[17] Ks. http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/servlet/http/HttpServletResponse.html

[18] Ks. http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/servlet/SingleThreadModel.html

[19] Huomaa erityisesti load-on-startup elementti

[20] Ks. http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html

[21] Ks. http://www.netscape.com

[22] Microsoft Internet Explorer

[23] Samalla koneella sijaitsevaa palvelinta voi kutsua URL:lla 127.0.0.1 tai nimellä localhost

 
edellinen
seuraava