javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

2 Grundelementer i JSP


2.1 JSP-programkode 28

2.1.1 En simpel side med HTML-kode 28

2.1.2 Lægge JSP-serverkode ind i siden 28

2.1.3 Eksempel: Dags dato og tid 29

2.1.4 Hvis du ikke har en server til rådighed 29

2.1.5 JSTL - en ny måde at arbejde på 29

2.2 Variabler 30

2.2.1 Indlejrede java-udtryk 31

2.2.2 Variabler med objekter 31

2.2.3 Importere klassedefinitioner (pakker) 32

2.3 Blanding af HTML og Java - to stilarter 33

2.3.1 Blandet Java og HTML 33

2.4 Data om klienten (request-objektet) 34

2.5 Kommentarer 35

2.6 Test dig selv 36

2.7 Resumé 36

2.8 Avanceret 37

2.8.1 Læse filer fra harddisken 37

2.8.2 Erklæring af metoder og blivende variabler 38

2.8.3 Trådsikkerhed i JSP-sider 39

2.8.4 Producere grafik fra JSP 40

2.8.5 Eksempel: JSP-side der danner et JPG-billede 40

2.8.6 Indlejre og nedskalere billeder fra harddisken 43

2.8.7 Opload af filer til server 44

En grundig forståelse af emnerne i dette kapitel forudsættes i resten af bogen.
Bemærk: De avancerede emner i slutningen af kapitlet forudsættes ikke, de er frivillig læsning, du senere kan vende tilbage til.

I dette kapitel laver vi den allerførste helt simple JSP-fil. Her kan du også teste, om din server er sat rigtigt op og kan køre JSP.

Grundlæggende er en JSP-fil en tekstfil med endelsen .jsp, som består af:

Tekst og HTML-koder kender du, så lad os kigge lidt mere på JSP-programkoden.

2.1 JSP-programkode

Når man programmerer JSP så skriver man i virkeligheden i programmeringssproget Java. Derfor kan det være en god ide at lære lidt Java undervejs, f.eks. ved at kigge på de første kapitler af af en lærebog som http://javabog.dk.

2.1.1 En simpel side med HTML-kode

Start med at lave et ganske almindeligt HTML-dokument, navngiv filen hej.jsp, og placer den sammen med de andre JSP-filer der fulgte med din webserver (med Tomcat er stien nok jakarta-tomcat-5.0.27/webapps/ROOT/hej.jsp). HTML-koden skal se sådan her ud:

<html>
<head><title>Hej</title></head>
<body>
Her kommer noget JSP-kode:

</body>
</html>

Prøv så at hente siden gennem webserveren.

Sandsynligvis er adressen http://localhost:8080/hej.jsp.

2.1.2 Lægge JSP-serverkode ind i siden

Husk at JSP er at skrive opgaver til en server, og lad os så prøve at skrive en opgave til serveren. For at fortælle serveren, hvad den skal kigge efter, må vi have nogle koder som fortæller, hvornår serverkoderne starter og slutter. I JSP bruger man <% og %> til at markere start og slut på det, som serveren skal udføre.

Prøv derefter at tilføje følgende helt simple kodestump til din HTML-kode:

<html>
<head><title>Hej</title></head>
<body>
Her kommer noget JSP-kode:

<%
  out.println( "<h1>Hej verden!</h1>" );
  out.println( "To plus to er: " );
  out.println( 2 + 2 );
%>

</body>
</html>

Når du nu ser JSP-dokumentet i en netlæser, skulle resultatet gerne være som vist til højre.

Men det interessante viser sig først, når du får vist HTML-koden i netlæseren (ved at vælge "vis kilde" eller "View Source"):

<html>
<head><title>Hej</title></head>
<body>
Her kommer noget JSP-kode:

<h1>Hej verden!</h1>
To plus to er: 
4

</body>
</html>

JSP-koderne er væk. Som allerede nævnt er det kun serveren som kan se JSP-koderne - klienten (netlæseren) ser kun resultatet af beregningerne. Serveren har udført Java-koden:

  out.println( "<h1>Hej verden!</h1>" );
  out.println( "To plus to er: " );
  out.println( 2 + 2 );

Lidt teknisk udtrykt ville man sige, at her brugte vi out-objektets metode println() til at skrive strenge til klienten. Bemærk at Java-kommandoer altid afsluttes med semikolon (;).

2.1.3 Eksempel: Dags dato og tid

Lad os prøve at få serveren til at skrive noget andet. Vi kunne f.eks. bede den om at udskrive den aktuelle dato og tidspunkt:

<html>
<head><title>Tiden</title></head>
<body>
<%
  out.print( new java.util.Date() );
%>
</body>
</html>

Vi kan altså få serveren til at udskrive dato og tidspunkt, når JSP-siden vises. Bemærk, at hvis man trykker på opdater/genindlæs/reload i sin netlæser, vises et nyt tidspunkt. Serveren beregner og udskriver altså dato og tidspunkt hver gang siden sendes til en klient.

Det er også væsentligt at bemærke, at den HTML-kode klienten ser, ikke indeholder andet end datoen. Det vil sige at JSP ikke stiller krav til, hvilken netlæser, der anvendes. Det er således sådan, at ting, der er lavet med serverside teknologier, virker i alle netlæsere.

2.1.4 Hvis du ikke har en server til rådighed

Hvis du ikke har en server, der kan køre JSP, til rådighed, kan du prøve alle eksemplerne fra bogen på http://javabog.dk:8080/JSP/kode/. Ovenstående eksempel har således adressen http://javabog.dk:8080/JSP/kode/kapitel_02/hej.jsp .

2.1.5 JSTL - en ny måde at arbejde på

Er du ikke så erfaren med Java er JSTL (JSP Standard Tag Library), der beskrives i kapitel 6, JSTL - JSP Standard Tag Library, nok lettere for dig end Java. JSTL er et HTML-lignende sprog som man kan skrive koden, der udføres på serveren i, i stedet for Java.

I kapitel 6 er der en række eksempler med JSTL, der gør det samme som eksemplerne i dette og de efterfølgende kapitler. Selvom denne bogs 'hovedsprog' er Java og ikke JSTL kan du derfor vælge at lære JSTL i stedet ved at læse hovedteksten og så ved Java-eksemplerne i stedet kigge på og lege med JSTL-eksemplerne i kapitel 6.

2.2 Variabler

En variabel kan opfattes som en navngiven papirlap, hvor der til enhver tid kan stå netop én ting. Variabler bruges til at huske data.

Variabler i Java skal altid erklæres, dvs. at man skal fortælle serveren, at der skal oprettes en variabel, hvad slags data den skal indeholde og hvad den skal hedde:

  int alder = 31;

Her har vi oprettet variablen alder. Den er af typen int, det vil sige at den kan indeholde hele tal. Samtidig har vi givet (eller tildelt) den værdien 31.

Senere kunne vi så hente værdien frem ved at skrive variablens navn. Her er et eksempel:

alder.jsp (JSTL-eksempel i afsnit 6.1)

<html>
<head><title>Alder</title></head>
<body>
<p>
<%
  int alder = 31;

  out.print( "Søren er " + alder + " år gammel. " );
  out.print( "Det svarer til " + 12*alder + " måneder. <br>" );

  alder = 3;
  out.print( "Julie er " + alder + " år gammel. " );

  alder = alder*365;
  out.print( "Det svarer cirka til " + alder + " dage. <br>" );
%>
</p>
</body>
</html>

Resultatet i en netlæser er:

Bemærk, at når en variabel tildeles en ny værdi, bliver den gamle værdi fuldstændig glemt.

Bemærk også, at på højre side af lighedstegnet i en tildeling kan stå et regneudtryk, der i så fald beregnes før variablen tildeles værdien.

Udtrykket alder = alder*365 gør altså det, at det beregner alder*365, der giver 3*365=1095. Denne værdi puttes derefter ind i variablen alder.

2.2.1 Indlejrede java-udtryk

I koden <%= %> kan skrives et Java-udtryk, der bliver beregnet på serveren og indsat i HTML-koden hver gang siden hentes.

<%= dato %> er altså bare en kortere måde at skrive <% out.print(dato); %> på.

Her er en side, der udskriver 7-tabellen ved hjælp af <%= %>:

syvtabellen.jsp (JSTL-eksempel i afsnit 6.1.5)

<html>
<head><title>Syvtabellen</title></head>
<body>
<p>Her er syv-tabellen:<br>

<% 
  for (int i=1; i<=10; i++)
  {
%>
    Syv gange <%= i %> er: <%= 7*i %>.<br>
<% 
  } 
%>
</p>
</body>
</html>

Bemærk at en klump javakode gerne må slutte, selvom der mangler en }-parentes til at afslutte den blok kode, der skulle udføres i for-løkken, blot der senere kommer endnu en klump javakode, hvori blokken afsluttes (det kommer vi tilbage til i afsnit 2.3.1).

2.2.2 Variabler med objekter

I eksemplet i afsnit 2.1.3 skrev vi new java.util.Date(), hvilket opretter et objekt, som repræsenterer den aktuelle dato og tid på serveren.

Sådan et objekt kan man også gemme i en variabel, sådan her:

  java.util.Date tiden = new java.util.Date();

og så bagefter udskrive objektet på skærmen:

  out.print( tiden );

Lad os udvide eksemplet og både udskrive en streng og et objekt, som vi samler med +:

<html>
<head><title>Tiden 2</title></head>
<body>
<%
  java.util.Date tiden = new java.util.Date();
  out.print( "Dato og tid er: " + tiden );
%>
</body>
</html>

Når netlæseren anmoder om siden, udfører serveren JSP-koden og sender til klienten:

<html>
<head><title>Tiden 2</title></head>
<body>
Dato og tid er: Wed Aug 28 16:00:42 CEST 2002
</body>
</html>

2.2.3 Importere klassedefinitioner (pakker)

I stedet for hele tiden at skrive Date-klassens fulde navn (som er java.util.Date) kan vi også importere java.util.* (alle klasser i pakken java.util) og således undgå at skrive pakkenavnet.

Til det skal vi bruge side-direktivet <%@ page ... %>, der kan bruges til at angive en række ting om hvordan serveren skal udføre siden (side-direktivet bliver grundigere beskrevet senere, i afsnit 4.4):

<%@ page language="java" import="java.util.*" %>
<html>
<head><title>Tiden 3 - import af pakke</title></head>
<body>
<%
  Date tiden = new Date();
  out.print( "<p>Dato og tid er: " + tiden + "</p>" );
%>
</body>
</html>

Importere flere pakker

Vil man importere klasser fra flere pakker skriver man dem adskilt af komma, f.eks. import="java.util.*,java.text.*".

Med det kan vi lave en lidt pænere side, der udskriver datoen og tiden:

<%@ page language="java" import="java.util.*,java.text.*" %>
<html>
<head><title>Tiden 4 - import af flere pakker</title></head>
<body>
<%
    DateFormat klformat, datoformat;

    klformat   = DateFormat.getTimeInstance(DateFormat.SHORT);
    datoformat = DateFormat.getDateInstance(DateFormat.FULL);

    Date tid = new Date();
    String kl = klformat.format(tid);
    String dato = datoformat.format(tid);
%>
<p>Datoen i dag er <%= dato %>, og klokken er <%= kl %>.</p>
</body>
</html>

Resultatet i en netlæser er:

2.3 Blanding af HTML og Java - to stilarter

Lad os skrive tidspunktet på dagen. Det kan vi gøre med en række kædede if-sætninger:

java_og_html_adskilt.jsp (JSTL-eksempel i afsnit 6.2.2)

<%@ page language="java" import="java.util.*" %>
<html>
<head>
<title>Java og HTML adskilt</title></head>
<body>
Det er lige nu:
  <%
    Date tid = new Date();
    int t = tid.getHours();
    if (t <= 9)       out.print("morgen");
    else if (t <= 12) out.print("formiddag");
    else if (t <= 17) out.print("eftermiddag");
    else if (t <= 21) out.print("aften");
    else              out.print("nat");
  %>
</body>
</html>

De fleste foretrækker at bruge out-objektet til udskrivning, som vist ovenfor, for på denne måde at adskille Java og HTML.

2.3.1 Blandet Java og HTML

Men det er faktisk muligt at starte og stoppe javakoden med <% og %> i stedet:

<%@ page language="java" import="java.util.*" %>
<html>
<head><title>Java og HTML blandet</title></head>
<body>
Det er lige nu:
  <%
    Date tid = new Date();
    int t = tid.getHours();
    if (t <= 9)       { %> morgen      <% }
    else if (t <= 12) { %> formiddag   <% }
    else if (t <= 17) { %> eftermiddag <% }
    else if (t <= 21) { %> aften       <% }
    else              { %> nat         <% }
  %>
</body>
</html>

For de fleste er det forvirrende med denne sammenblanding af HTML og Java. Derfor foretrækker de fleste at bruge out-objektet (en tredje mulighed er at bruge JSTL, se hvordan i afsnit 6.2).

Dette eksempel kan dog virke besnærende for nogen, fordi det ser mere overskueligt ud. Man skal dog være meget omhyggelig med at omkranse HTML-koden i {- og }-parenteser.

Husk altid at bruge { og } i betingelser og løkker hvis de har indlejret HTML
Man skal være omhyggelig med, at der altid er lige mange {-startparenteser som }-slutparenteser

Er der ikke lige mange {- og }-blokparenteser får man kryptiske1 fejlmeddelelser såsom:

  'try' without 'catch' or 'finally'
  'catch' without 'try'
  'else' without 'if'

2.4 Data om klienten (request-objektet)

Out-objektet er et eksempel på et objekt, der automatisk findes i alle JSP-sider.

Der findes flere af den slags objekter (i afsnit 4.5, Appendiks: Implicit definerede objekter, er de beskrevet i detaljer), bl.a. et request-objekt (beskrevet i afsnit 4.5.1). Dette objekt repræsenterer alt det serveren ved om klienten og med det kan vi få en række ting at vide om klienten og den forespørgsel der blev foretaget.

<html>
<head><title>Data om klienten</title></head>
<body>
<h1>Nogle data om klienten (request-objektet)</h1>
<pre>
Fuld URL  - getRequestURL(): <%= request.getRequestURL() %>

Metode    - getMethod():      <%= request.getMethod() %>
Protokol  - getProtocol():    <%= request.getProtocol() %>
Værtsnavn - getServerName():  <%= request.getServerName() %>
Port      - getServerPort():  <%= request.getServerPort() %>
Webapp    - getContextPath(): <%= request.getContextPath() %>
Sti i app - getServletPath(): <%= request.getServletPath() %>

Filplacering på harddisk: <%= application.getRealPath(request.getServletPath()) %>

Klients IP-adresse - getRemoteAddr(): <%= request.getRemoteAddr() %>
Foretrukne sprog   - getLocale():     <%= request.getLocale() %>
Netlæser/browser   header user-agent: <%= request.getHeader("user-agent") %>
</pre>
</body>
</html>

Prøv eksemplet på http://javabog.dk:8080/JSP/kode/kapitel_02/data_om_klienten.jsp.

2.5 Kommentarer

Med <%-- og --%> kan man indsætte kodekommentarer i JSP. Disse fungerer lidt anderledes end HTML-kommentarer, som man laver med <!-- og -->.

<html>
<head><title>Hej med HTML- og JSP-kommentarer</title></head>
<body>
Her kommer noget JSP-kode:

  <% out.println( "<h1>Hej verden!</h1>" ); %>

<!-- HTML-kommentar
  <% out.println( "To plus to er: " ); %> 
-->

<%-- JSP-kommentar
  <% out.println( 2 + 2 ); %>
--%>

</body>
</html>

I bogen her bliver kommentarer skrevet i kursiv for læselighedens skyld.

Grunden til at JSP har sin egen måde at lave kommentarer på, er at JSP-kommentarer med <%-- og --%> (til forskel fra HTML-kommentarer med <!-- og -->) slet ikke bliver udført på serveren. De bliver også helt udeladt af koden, der sendes til klientens netlæser. Hvis ovenstående side hentes, vil netlæseren derfor kun få tilsendt (det kan ses med 'vis kilde'):

<html>
<head><title>Hej med HTML- og JSP-kommentarer</title></head>
<body>
Her kommer noget JSP-kode:

  <h1>Hej verden!</h1>

<!-- HTML-kommentar
  To plus to er: 
-->


</body>
</html>

De almindelige HTML-kommentarer lavet med <!-- og --> vil netlæseren udelade i fremvisningen, så resultatet er, at netlæseren ikke viser hverken den ene eller den anden slags kommentarer:

2.6 Test dig selv

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.7 Resumé

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8 Avanceret

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.1 Læse filer fra harddisken

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.2 Erklæring af metoder og blivende variabler

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.3 Trådsikkerhed i JSP-sider

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.4 Producere grafik fra JSP

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.5 Eksempel: JSP-side der danner et JPG-billede

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.6 Indlejre og nedskalere billeder fra harddisken

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.8.7 Opload af filer til server

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

1Som vi senere skal se, i afsnit 7.3, Avanceret: JSP-siders interne virkemåde, bliver JSP-sider lavet om til en metode i en klasse. Derfor er det meget vigtigt at {- og }-parenteser er balancerede.

2Egentlig er servletter (se afsnit 7.1) mere velegnede til at producere binære data end JSP-sider. I eksemplet kommer således fejlen 'IllegalStateException: getOutputStream() has already been called for this response' i serverens log, selvom eksemplet virker fint.

javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - Webprogrammering med Java Server Pages af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (72% af værket).

Ønsker du at se de sidste 28% af dette værk (275315 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.