Java Servlets och JavaServer Pages
Specifikationerna för de aktuella versionerna (Java Servlets
2.3 och JavaServer Pages 1.2) kan laddas hem från http://www.jcp.org/aboutJava/communityprocess/final/jsr053/.
API-dokumentationen för servlets finns online på http://java.sun.com/j2ee/sdk_1.3/techdocs/api/.
De paket som är aktuella för servlets är javax.servlet
och javax.servlet.http.
Servern Orion kan laddas hem på http://www.orionserver.com/.
Exemplen på denna sida är provkörda med Orion 2.0.2.
Denna sida är en mycket kortfattad introduktion, det finns
väldigt mycket mer att säga om alla områden som nämns
på sidan.
HTTP och program på serversidan
Java Servlets och JavaServer Pages (JSP) är de Java-specifikationer
som finns för att exekvera program i en HTTP-server för att
generera dynamiska svar (till exempel i form av HTML). För att förstå
hur de används är det nödvändigt att ha grundläggande
kunskaper om HTTP.
Fall 1: HTTP-servern levererar statiska filer
När vi skriver in en URL eller klickar på en länk
i en browser kommer den att skicka en HTTP-request. Om vi till exempel
vill titta på sidan http://www.isk.kth.se/kursinfo/6b2015/index.html
kommer browsern att skicka en request till servern www.isk.kth.se om
att få innehållet på sidan /kursinfo/6b2015/index.html.
Servern kommer då att läsa in filen index.html i katalogen
kursinfo/6b2015 och skicka dess innehåll till browsern som tolkar
det och visar det.
Fall 2: HTTP-servern levererar ett dynamiskt genererat svar
Allt browsern gjorde i fall 1 ovan var att skicka en sträng
med ett sidnamn till servern och få en sträng med HTML-kod
till svar. Ur browserns synpunkt är det helt ointressant om det verkligen
finns en fil i serverns filsystem som heter index.html. Om svaret genereras
dynamiskt finns ingen sådan fil utan servern använder i stället
namnet på sidan browsern vill se till att identifiera ett program.
Servern exekverar detta program och skickar utskriften från det
till browsern. Browsern tolkar svaret som (till exempel) HTML och visar
det för användaren.
JavaServer Pages (JSP)
Vad är en JSP och när ska de användas?
JSP är en standard för att skriva program i Java som
ska exekveras av en HTTP-server enligt fall två ovan. Det finurliga
med JSP är att vi inte behöver skriva själva Java-koden
utan den automatgenereras av servern enligt instruktionerna i JSP-sidan.
JSP definierar ett antal olika taggar som styr vilken Java-kod som genereras.
Allt annat i sidan än dessa taggar skickas oförändrat till
browsern när Java-programmet som genererats utifrån JSP-sidan
exekveras.
JSP ska användas för att dynamiskt generera textbaserade
sidor (tex HTML-sidor). Dessa sidor kan naturligtvis innehålla
bilder och allt annat som "vanliga" HTML-sidor kan innehålla. Med
"textbaserade" menas att vi inte ska använda JSP för att generera
tex själva bilden (tex JPEG-kod).
Att exekvera en enkel JSP (hello world)
I sin enklaste form innehåller en JSP inga av de taggar som
används för att styra omvandlingen av den till ett Java-program.
Det innebär att allt dess innehåll skickas till browsern och
att den ser ut som en vanlig HTML-sida. Här kommer ett exempel på
en sådan JSP, hello-world.jsp.
Med hjälp av denna fil ska vi nu gå igenom hur en JSP
deployas i Orion. Att få igång en ny server är oftast
ganska klurigt. Underskatta alltså inte tidsåtgången
för detta och bli heller inte bedrövad om det tar ett par dagar
innan hello world fungerar. Det är fullt normalt.
I nedanstående instruktioner syftar ORION_HOME på den
katalog där Orion installerats, till exempel c:\Program\Orion
eller /usr/local/orion.
- Ladda hem Orion från länken överst på
sidan och installera den enligt anvisningarna på http://www.orionserver.com/docs/install.html.
Kolla att det går att starta den enligt punkt åtta i Step-by-step
Installation Guide på sidan ovan. Notera att du måste
byta port servern lyssnar på (enligt punkt fyra i Step-by-step
Installation Guide) om du redan har någon annan server som lyssnar
på port 80. I UNIX/Linux är det dessutom bara root som har rättighet
att använda portnummer under 1024. Om du vill köra Orion på
port 80 måste du alltså logga in som root varje gång
du ska starta servern.
- Skapa en katalog för den nya webapplikationen (hello
world). Denna kan heta helloworld och ska ligga i ORION_HOME/applications.
- Placera filen hello-world.jsp i katalogen ORION_HOME/applications/helloworld
som skapades i föregående punkt.
- Skapa en fil som heter web.xml och ligger i katalogen
ORION_HOME/applications/helloworld/WEB-INF (som
måste skapas först). Denna fil kallas deployment descriptor
och kan innehålla information till servern om en webapplikation.
Vi återkommer till den senare. I det här exemplet behöver
den inte innehålla någon information, det räcker att den
finns och innehåller en enda rad där det står
<web-app></web-app>
- Nu måste vi tala om för Orion att vi har skapat
en ny webapplikation. Det gör vi genom att i filen ORION_HOME/config/application.xml
lägga till raden
<web-module id="helloworld" path="../applications/helloworld"/>
Värdet av path måste vara sökvägen
från application.xml till rotkatalogen för webapplikationen,
dvs den katalog där hello-world.jsp placerades. Min application.xml
ser nu ut så här, application.xml.
- Till slut måste vi koppla vår webapplikation till
en web site på Orion. Samma Orion-server kan lyssna på
flera olika portar och IP-adresser och varje unik port är en web site.
Vi behöver inte krångla till det genom att gräva djupare
i detta utan låter alla våra webapplikationer tillhöra
Orions default web site, den som användes i punkt ett ovan.
Vi kopplar vår webapplikation till den genom att i filen ORION_HOME/config/default-web-site.xml
lägga till raden
<web-app application="default" name="helloworld" root="/hello-world"/>
Alla webapplikationer i Orion måste tillhöra en J2EE-applikation.
Även detta kan vi strunta i genom att låta alla våra
webapplikationer tillhöra default-applikationen (det var den som
vi konfigurerade i punkt 5). För att de ska tillhöra default-applikationen
måste värdet av application vara just default.
Värdet av name måste vara exakt detsamma som värdet
av id i raden vi lade in i punkt fem. Värdet av root
blir början på path:en i URL:en för vår webapplikation.
Eftersom värdet av root är /hello-world
kommer vi att hitta vår webapplikation på http://localhost:8080/hello-world
(om servern finns på localhost och lyssnar på port
8080). Observera att värdet på root måste börja
med en slash (/). Min default-web-site.xml ser ut så
här, default-web-site.xml.
- Nu går det att surfa till våran JSP. Starta en
browser och surfa till http://localhost:8080/hello-world/hello-world.jsp
(om servern finns på localhost och lyssnar på port
8080). Förhoppningsvis får du då uppleva tillfredsställelsen
att se den hett efterlängtade texten Hello World!!
Trots att det i browsern ser ut exakt som om en statisk fil med
innehållet i hello-world.jsp hade skickats från servern
är det inte alls så det går till. Servern har i stället,
enligt vad som sades i avsnittet Fall 2: HTTP-servern levererar ett dynamiskt
genererat svar ovan omvandlat hello-world.jsp till
ett Java-program, kompilerat det, exekverat det och skickat dess utskrift
till browsern. Om attributet development="true" läggs till
elementet <orion-web-app> i filen ORION_HOME/application-deployments/default/helloworld/orion-web.xml
kommer källkoden för Java-programet att sparas. Min orion-web.xml
ser ut så här, orion-web.xml.
Efter att du gjort denna ändring måste du starta om servern,
ändra i hello-world.jsp och surfa till hello-world.jsp.
Därefter hittar du den automatgenererade Java-klassen i filen ORION_HOME/application-deployments/default/helloworld/persistence/hello-world.jsp.java
Mitt program ser ut så här, hello-world.jsp.java Enligt specificationen
för JSP måste klassen innehålla en metod som heter _jspService().
Denna metod måste anropas av servern varje gång en browser
frågar efter sidan. Vi kan se att denna metod hämtar ett objekt
av utströmmen JspWriter och anropar metoden write för
att skriva till strömmen. Allt som skrivs dit kommer att skickas till
browsern. I det här fallet är det HTML-koden vi skrev i hello-world.jsp
som skickas.
Om hello-world.jsp eller web.xml byts ut kommer
de nya filerna automatiskt att laddas av Orion, utan att servern behöver
startas om. Kolla gärna genom att lägga in en förändrad
hello-world.jsp och klicka på reload i browsern.
Inkludera filer i en JSP
En JSP kan inkludera en annan sida. Det görs med direktivet
<%@include file="sökväg till filen som ska inkluderas
relativt den inkluderande filen"%>. Detta innebär att innehållet
(dvs "källkoden") i den inkluderade filen läggs in i den inkluderande
filen på det ställe där include-taggen står.
Det är alltså inte resultatet av exekveringen av den
inkluderade filen som läggs in.
Inkludering är användbart om samma fragment (till exempel
en header, footer eller meny) ska finnas på flera olika sidor. Här
kommer ett exempel, filen includer.jsp
inkluderar filen footer.html.
Om vi tittar i källkoden till den java-klass Orion genererar
(includer.jsp.java) ser vi att innehållet
i footer.html hamnar i ett anrop av write() precis
som innehållet i includer.jsp.
Anropa Java-objekt från en JSP
Det finns taggar definierade i JSP för att anropa andra Java-objekt.
Dessa objekt måste då uppfylla vissa delar av JavaBeans-specifikationen.
Det finns ingen anledning att gå igenom den här, det räcker
att fastslå de krav objekten måste uppfylla:
- De måste ha en konstruktor som inte tar några inparametrar.
Den kommer att anropas när ett objekt instansieras.
- De måste gå att serialisera.
- De metoder som ska anropas från en JSP måste följa
JavaBeans-definitionen av properties. Detta innebär att de måste
ha publik åtkomst och heta setXXX() eller getXXX().
Hur XXX lagras eller beräknas spelar ingen roll.
Vi gör ett objekt synligt för en JSP med hjälp av
taggen <jsp:useBean id="myBean" class="ai1.serverjava.beanexample.MyBean"
scope="application"/>. Det finns många olika sätt att
skriva den men i den här korta genomgången nöjer vi oss
med detta sätt. Värdet av id blir namnet på det
objekt som skapas och class ska ange klassnamnet inklusive paket
på den klass objektet tillhör. scope anger hur länge
objektet ska finnas kvar. Defaultvärdet är page som innebär
att det bara finns på den sida som innehåller taggen jsp:useBean.
Det går även att ange request som innebär att
det finns kvar tills svaret är levererat till browsern, session
som innebär att det existerar under en session (se nedan) och application
som betyder att det finns kvar under hela webapplikationens existens.
Ett anrop av en set-metod i bönan genereras av taggen <jsp:setProperty
name="myBean" property="beanProperty" param="requestParam"/>
där värdet av name måste vara detsamma som värdet
av id i den jsp:useBean som deklarerade bönan.
property anger namnet på den metod som ska anropas, om
property har värdet xyz kommer metoden setXyz()
att anropas. Slutligen måste värdet på metodens inparameter
anges. Med attributet param ges namnet på en requestparameter
(från tex ett HTML-formulär) vars värde blir indata till
set-metoden. Alla requestparametrar är av typen java.lang.String
men de omvandlas automatiskt om de ska skickas till metoder som hanterar
properties av andra typer. I stället för atributet param
kan attributet value anges. Dess värde blir då det
värde som ska skickas till metoden. Om värdet är en String
kan det omvandlas på samma sätt som när attributet param
används. Om värdet inte är en String måste det vara
av samma typ som property:n som ska sättas.
Ett anrop av en get-metod i bönan genereras av taggen <jsp:getProperty
name="myBean" property="beanProperty"/> där värdet
av name måste vara detsamma som värdet av id
i den jsp:useBean som deklarerade bönan. property
anger namnet på den metod som ska anropas, om property har
värdet xyz kommer metoden getXyz() att anropas.
I svaret till browsern kommer taggen att ersättas av det som returneras
av metoden getXyz(). Om den inte returnerar en String
kommer det returnerade värdet automatiskt att omvandlas till en String.
Här kommer ett exempel, JSP:n use-bean.jsp
använder bönan MyBean.java. MyBean.java
ska kompileras och class-filen ska placeras under katalogen ORION_HOME/applications/jspbean/WEB-INF/classes
i en katalogstruktur som stämmer med paketnamnet. jspbean
är webapplikationens rotkatalog, den som motsvaras av katalogen helloworld
i exemplet ovan där hello-world.jsp deployades. Om paketet
(som i MyBean.java) heter ai1.serverjava.beanexample
ska class-filen placeras i ORION_HOME/applications/jspbean/WEB-INF/classes/ai1/serverjava/beanexample
Låt oss till sist titta i den Java-klass som Orion skapar,
use-bean.jsp.java. Vi kan se att den översätter
taggen jsp:useBean till att deklarera en variabel av typen ai1.serverjava.beanexample.MyBean
som heter myBean, försöka hämta ett sådant
objekt och, om det inte lyckas, skapa det. Vi kan också se hur den
översätter jsp:setProperty och jsp:getProperty
till anrop av set- respektive get-metoder i objektet myBean.
Observera till sist att om filen MyBean.class byts ut måste
Orion startas om.
HTTP-sessioner
Ibland måste vårat program på servern veta om samma
användare varit där tidigare och vad hon/han gjorde då.
Ett bra exempel är om användaren måste logga in på
något sätt. Om så är fallet måste vi, när
ett request kommer, kunna kolla om den som gör det requestet har loggat
in i ett tidigare request eller inte. Problemet är att vartenda request
kör exakt samma kod i en egen tråd, var ska vi då spara
informationen om användarens tidigare förehavanden?
Ett smidigt sätt att lösa detta är att låta JSP:n
delta i en HTTP-session. Att den ska göra det anges genom att lägga
till attributet session="true" i direktivet page. Om
JSP:n deltar i en session går det att spara objekt (till exempel JavaBeans)
under exakt sesionens livslängd. Ett nytt objekt kommer då att
automatiskt skapas när en ny session startas och automatiskt kastas
när sessionen slutar. Hur detta sköts av servern får vi
hoppa över i den här korta genomgången.
Default för Orion lever en session från att en sida som
deltar i sessionen accessas tills browsern stängs. Sessionen överlever
en omstart av servern. Default hanteras sessioner i JSP med cookies, men
den hanteringen sköts helt av servern.
Här kommer ett exempel på en JSP som deltar i en session,
session.jsp. Den använder en böna,
CounterBean.java,
för att räkna hur många gånger sidan accessats i
en och samma request, session och webapplikation. Vad som räknas styrs
av vilket scope som angetts för bönan i jsp:useBean.
Titta på sidan i en browser och tryck på reload några
gånger. Räknaren för session och applikation ökar medans
antalet accesser i requesten aldrig blir mer än ett. Det beror på
att varje anrop till servern är en ny request. Prova att stänga
av servern och starta den igen. Sessionsräknaren nollställs inte
eftersom sessioner överlever en omstart av servern, däremot startas
webapplikationen om på nytt varje gång servern startar. Detta
gör att applikationsräknaren börjar om på ett. Prova
till sist att avsluta browsern och starta den igen. Nu nollställs sessionsräknaren
men applikationen lever tills servern stängs.
Java Servlets
Vad är en servlet och när ska de användas?
En servlet är, precis som en JSP, ett Java-program som körs
av en HTTP-server till följd av ett HTTP-request. Den stora skillnaden
är att en servlet skrivs direkt som ett Java-program, i stället
för att programmet automatgenereras av servern.
En servlet har två användningsområden. Det absolut
vanligaste är att den används som controller i en webapplikation,
dvs att den tar emot HTTP-request, utför de operationer på servern
som krävs och sedan vidarebefodrar requestet till den JSP som utgör
nästa skärmbild i browsern. Det andra användningsområdet
är att skicka binärt data till browsern. Ett bra exempel på
det är om en bild (som inte finns i filsystemet) ska genereras. Servleten
kan då göra det och sedan skicka det binära datat (dvs bilden).
Ett exempel på en servlet
En servlet är som sagt en "vanlig" Java-klass som vi skriver
själva. Den ska ärva av den abstrakta klassen javax.servlet.http.HttpServlet.
Om någon form av initiering ska göras ska den ske genom att
metoden public void init() omdefinieras. Det ska inte finnas någon
konstruktor i en servlet. Containern kommer att anropa init()
exakt en gång för varje servletobjekt som instansieras.
Om det kommer ett HTTP GET-request (vanligtvis pga av att användaren
klickat på en länk eller skrivit in en URL) kommer containern
att anropa metoden public void doGet(HttpServletRequest req, HttpServletResponse resp).
Objektet req hanterar requestet och objektet resp hanterar svaret som
ska skickas till browsern. Om det kommer ett HTTP POST-request (vanligtvis
pga av att användaren fyllt i och skickat ett HTML-formulär)
kommer containern att anropa metoden public void doPost(HttpServletRequest req,
HttpServletResponse resp). Ofta finns det ingen anledning att
behandla post och get olika, då är det lämpligt att låta
dessa två metoder innehålla en enda rad som anropar samma privata
metod där allt arbete görs.
Servlet-api:et innehåller väldigt mycket mer än så,
ta gärna en titt på api-dokumentationen i länken överst
på sidan, men det här är allt som behövs för
att komma igång.
Här kommer en enkel servlet som inte gör något mer
än att skriva till System.out när den anropas, SysOutServlet.java.
Utskriften kommer att synas i det fönster servern startades, i browsern
händer ingenting. För att kompilera servleten måste klassbiblioteket
för servlet-api:et finnas på classpath. Du kan till exempel
stå i den katalog där SysOutServlet.java finns och
skriva
javac -classpath .:ORION_HOME/orion.jar SysOutServlet.java
I Windows används ; i stället för : för att skilja
olika sökvägar i classpath.
Vi väntar med att deploya servleten tills vi tittat på deployment
descriptorn i nästa avsnitt.
Deployment descriptor
Deployment descriptorn, som används för att konfigurera och
deklarera innehållet i en webapplikation, utgörs av filen web.xml.
Hittils har den filen varit helt tom, men nu när webapplikationen
innehåller en servlet måste deployment descriptorn innehålla
en deklaration av servleten. En servlet deklareras genom att följande
rader läggs in i web.xml
<servlet>
<servlet-name>SysOutServlet</servlet-name>
<servlet-class>ai1.serverjava.servlet.SysOutServlet</servlet-class>
</servlet>
Detta talar om att det finns en servlet som heter SysOutServlet
och finns i klassen ai1.serverjava.servlet.SysOutServlet. Min
web.xml ser nu ut så här, web.xml. Nu kan vi deploya
servleten. web.xml placeras som vanligt i ORION_HOME/applications/servlet/WEB-INF
förutsatt att vi angett i application.xml att path
för webapplikationen har värdet ../applications/servlet.
Filen SysOutServlet.class placeras i ORION_HOME/applications/servlet/WEB-INF/classes/ai1/serverjava/servlet
om klassen, liksom i exemplet, ligger i paketet ai1.serverjava.servlet.
Nu kan vi surfa till servleten på URL:en http://localhost:8080/servlet-example/servlet/SysOutServlet
förutsatt att servern finns på localhost och lyssnar
på port 8080. Två delar av URL:en förtjänar
en närmare förklaring: servlet-example är webapplikationens
rotkatalog, dvs det vi angett som värde för attributet root
i default-web-site.xml. servlet kommer sig av att alla
servlets hittas i URL:en i en "underkatalog" till webapplikationens rot
som heter just servlet. Om SysOutServlet.class byts ut
laddar Orion automatiskt den nya versionen vid nästa request.
Vi kan förenkla det lite genom att lägga till nedanstående
rader i web.xml:
<servlet-mapping>
<servlet-name>SysOutServlet</servlet-name>
<url-pattern>SysOutServlet/*</url-pattern>
</servlet-mapping>
Nu ser web.xml ut så här, web.xml.Det gör att alla URL:er som
börjar med SysOutServlet kommer att hanteras av servleten vars
<servlet-name> har värdet SysOutServlet, dvs
av den servlet vi nyss deklarerade i web.xml. Vinsten med detta
är att vi slipper katalogen servlet i URL:en, vi kan nu hitta
vår servlet på http://localhost:8080/servlet-example/SysOutServlet
Att skicka ett request vidare från en servlet till en JSP (eller
HTML-fil)
Enligt asvnittet Vad är en servlet och när ska de användas?
ovan är det vanligt att en servlet skickar ett request vidare till
en annan fil som utgör själva vyn. Att skicka ett request vidare
på det viset görs i två steg:
- Skaffa ett objekt av javax.servlet.RequestDispatcher
genom att anropa metoden getParameter() i javax.servlet.http.HttpServletRequest
och skicka med en sträng som är den URL till vilken requestet
ska vidarebefodras. URL:en kan anges absolut, den börjar då efter
webapplikationens rotkatalog och dess första tecken ska vara en slash
(/). Den kan också anges relativt den URL som browsern skickade requestet
till, dess första tecken ska då inte vara en slash (/).
- Anropa metoden forward() i RequestDispatchern
och skicka med request- och response-objekten. Detta metodanrop betyder
att svaret till browsern skickas från den URL som RequestDispatchern
är kopplad till. Observera dock att metoden forward() sedan
returnerar och att exekveringen av koden i servleten fortsätter.
Här kommer en servlet som skickar alla request vidare, ForwardingServlet.java
och dess web.xml. Anropa den med URL:en
http://localhost:8080/ForwardingServlet?newUrl=XXX Den kommer då
att skicka det som finns på XXX till browsern. Om det till
exempel finns en fil i webapplikationens rotkatalog som heter whatever.html
kommer den att visas om vi surfar till http://localhost:8080/ForwardingServlet?newUrl=/whatever.html
En komplett webapplikation (number guess game)
Till sist tar vi en titt på en komplett webapplikation. Det är
ett litet spel som går ut på att gissa rätt nummer. För
att få spela det är det nödvändigt att logga in. Här
finns hela applikationen, numguess.war. war
(Web ARchive) är det format som används för
att packa webapplikationer. Det är precis likadant som jar bortsett
från att katalogen WEB-INF (som innehåller web.xml)
finns med. Webapplikationen kan packas upp med kommandot jar xvf numguess.war.
Den uppackade katalogstrukturen går att deploya oförändrad.
Förstasidan är filen index.jsp. Här finns källkoden
för de ingående Java-klasserna, numguess-src.jar.
Till sist några kommentarer om applikationen:
- Applikationens struktur
- Alla jsp- och html-filer finns under katalogen WEB-INF.
Det beror på att innehållet i den katalogen aldrig får
visas för en klient (enligt servlet-specifikationen). Det enda sättet
för en klient att komma åt dessa filer är att FrontController
gör forward till någon av dem. På det sättet kan vi
förhindra att användaren hoppar över inloggningen och skriver
in url:en direkt till någon viss fil. Att index.jsp finns
direkt i roten (alltså utanför WEB-INF) beror på
att det är tillåtet för användaren att se inloggningssidan
utan att vara inloggad.
- All navigering mellan olika vyer sker med värdet av request-parametern
action. Dess värde sätts i de olika HTML-formulären
som visas för användaren. I metoden processRequest() på
rad 38 i FrontController läses action. Beroende på
dess värde avgörs vilka operationer som ska utföras och vilken
vy som ska visas härnäst.
- FrontController.java
- På rad 86 kan vi se hur ett sessionsobjekt skapas, det
görs genom att anropa metoden getSession() i klassen HttpServletRequest.
Den returnerar ett objekt av typen HttpSession.
- I sessionsobjekt (se punkt 1) kan vi spara andra objekt på
det vis som sker på rad 86, genom att anropa metoden setAttribute(String,
Object). Strängen är ett godtyckligt namn som används
för att hämta objektet.
- Objekt som sparats i sessionsobjekt (se punkt 1 och 2) hämtas
med metoden getAttribute(String) som finns i klassen HttpSession,
eller med taggen jsp:useBean i en jsp. Detta görs på
rad 109 i FrontController repsektive (tex) rad 3 i fail.jsp.
- På rad 62 anropas metoden getSession(false)
i HttpServletRequest. Den returnerar ett sessionsobjekt
om användaren deltar i en session, annars returneras null.
Eftersom sessionsobjektet skapas när användaren loggar in kan
vi på detta sätt kolla om användaren är inloggad.
Finns det ett sessionsobjekt är hon/han inloggad, annars inte.
- När användaren loggar ut exekveras rad 99 därmetoden
invalidate() i klassen HttpSession anropas. Den
tar bort sessionsobjektet.
- På rad 90 anropas metoden setAttribute(String, Object)
i klassen HttpServletRequest. Den används fär att spara
ett objekt i request-objektet på precis samma sätt som i ett
sessionsobjekt, se punkt 2.
- Det objekt som sparats i request-objektet hämtas på
precis samma sätt som objekt hämtas ur sessionsobjekt, se punkt
3. Detta sker i filen index.jsp, se punkt 2 under index.jsp
nedan.
- index.jsp
- Det går att skriva java-kod i en jsp. Den läggs
då in i den automatgenererade java-klassen på exakt den plats
den står i jsp-filen. Det är inte lämpligt att använda
den möjligheten eftersom syftet med jsp:er och servlets är
att dela upp javakod och vyer. Desto mer java-kod det finns i jsp:erna desto
svårare är det att underhålla dem. Speciellt svårt
blir det för en person som inte kan java. tex någon som arbetar
med grafisk layout av sidorna i applikationen. Det går utmärkt
att helt undvika java-kod i jsp:erna, men inte utan att lära sig mer
än vad som finns på den här sidan. Med de kunskaper vi har
nu finns inget annat sätt än java-kod att skriva villkorssatser
och loopar i en jsp. Hur det sker syns på rad 10 och 12 i index.jsp.
- På rad 11 i index.jsp finns taggen <%=
... %>. Inom den taggen ska det stå java-kod som returnerar
ett värde. Det värdet kommer att skickas till browsern. Om värdet
inte är en sträng omvandlas det automatiskt till en sträng.
Här används denna tag för att returnera felmeddelandet som
läses från request-objektet. I punkt 6 under FrontController.java
ovan förklaras hur felmeddelandet hamnade där.
Tyvärr följer Orion inte servlet-specifikationen när det
gäller att spara information om vilken session användaren deltar
i. Den använder nämligen inte cookies utan skriver i stället
om url:erna. Detta ställer till problem, men genom att ändra i
filen orion-web.xml som beskrivs i slutet av avsnittet Att exekvera
en enkel JSP (hello world) ovan kan vi tvinga Orion att göra som
den ska, dvs använda cookies. Vi måste lägga till taggen
<session-tracking autoencode-urls="false"/>. Kom ihåg
att servern måste startas om för att ändringen ska gälla.
Min orion-web.xml ser ut så här, orion-web.xml.