



<html>
<head>
  <title>javabog.dk - Webprogrammering med Java Server Pages - Javab&oslash;nner i JSP-sider</title>
  <link rev="stylesheet" type="text/css" href="../typografi.css">
  <meta name="description" content="Lærebog i Java. Af Jacob Nordfalk. Udkommet hos Forlaget Globe">
  <meta name="keywords" content="designmønster, programmering, OOP, objekter, klasser, objektorienteret programmering, Java, JSP, lærebog, UML, IT">
</head>
<body bgcolor="#ffffff">



<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel8.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel10.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_JSP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">9 <a name='afsn9'></a>Javab&oslash;nner
i JSP-sider</H1>
<DIV ID="Indholdsfortegnelse10">
  <P STYLE="margin-top: 0.5cm; margin-bottom: 0cm"><BR>
  </P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.1
  Javab&oslash;nner  164</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.1.1
  Bruge javab&oslash;nner fra en JSP-side  164</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.1.2
  &Oslash;nskeseddel med ArrayList som javab&oslash;nne   165</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.2
  At definere en javab&oslash;nne og bruge den  166</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.1
  Pakker og filplaceringer for klasser  166</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.2
  Egenskaber p&aring; en javab&oslash;nne  166</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.3
  S&aelig;tte egenskaber fra en JSP-side  167</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.4
  Afl&aelig;se b&oslash;nnens egenskaber  168</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.5
  Virkefelter for javab&oslash;nner  168</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.6
  Avanceret: Virkem&aring;den af &lt;jsp:useBean... /&gt;  169</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.7
  Initialisering af javab&oslash;nner  170</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.2.8
  Avanceret: Virkem&aring;den af &lt;jsp:setProperty .../&gt;  170</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.3
  Egenskaber p&aring; en javab&oslash;nne  171</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.3.1
  Indekserede egenskaber  171</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.4
  Eksempel: En dagskalender  173</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.4.1
  Udseende  173</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.4.2
  Programmets virkem&aring;de  174</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.4.3
  HTML-siden (kalender.jsp)  175</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.4.4
  Bruger-b&oslash;nnen (Bruger.java)  176</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.4.5
  Kalender-objektet (Kalender.java)  177</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.5
  Eksempel: Login og brugeroprettelse  179</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.1
  Brug af eksemplet  179</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.2
  Login-b&oslash;nnen  179</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.3
  Login-siden  185</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.4
  Brugeroprettelsen  186</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.5
  En beskyttet side  188</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.6
  F&oslash;r eksemplet kan k&oslash;re p&aring; din egen server  188</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">9.5.7
  Opgaver  189</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.6
  Test dig selv  190</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>9.7
  Resum&eacute;  190</B></FONT></FONT></P>
</DIV>


<P CLASS="kapiteloversigt-western"><SPAN LANG="da-DK"><BR>Dette
kapitel foruds&aelig;ttes i resten af bogen. Det foruds&aelig;tter
<a href='kapitel4.jsp'>kapitel 4</a>, Videre med JSP, og <a href='kapitel5.jsp'>kapitel 5</a>, Brug af databaser.</SPAN></P>
<P CLASS="western" STYLE="">Det er
&oslash;nskv&aelig;rdigt at adskille tekstligt indhold og programkode
fra hinanden, s&aring;dan at f.eks. en HTML-designer kan koncentrere
sig om JSP-sidernes HTML-layout og indhold, mens en programm&oslash;r
koncentrerer sig om den bagvedliggende kode. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Et af de vigtigste elementer i
s&aring;dan en struktur er, at programkode og datastrukturer l&aelig;gges
for sig i separate javaklasser, som s&aring; kan bruges fra
JSP-siderne. </SPAN>Disse javaklasser anvendes derefter som
<I>j<SPAN LANG="da-DK">avab&oslash;nner</SPAN></I><SPAN LANG="da-DK">
fra JSP-siderne.</SPAN></P>
<H2 CLASS="western">9.1 <a name='afsn9.1'></a>Javab&oslash;nner</SPAN></H2>
<P CLASS="western">Enhver java-klasse kan kaldes en javab&oslash;nne
(eng.: Java Bean), bare to krav er opfyldt:</P>
<UL>
  <LI><P CLASS="western">Klassen er defineret i en pakke.</P>
  <LI><P CLASS="western">Klassen har en konstrukt&oslash;r uden
  parametre.</P>
</UL>
<P CLASS="western">De fleste klasser - b&aring;de systemets og dem du
selv definerer - kan alts&aring; opfattes som javab&oslash;nner.</P>

<H3 CLASS="western">9.1.1 <a name='afsn9.1.1'></a>Bruge javab&oslash;nner fra en JSP-side</H3>
<P CLASS="western">Den mest almindelige m&aring;de at bruge en
javab&oslash;nne p&aring; er, at knytte den til brugerens session,
s&aring;dan at den f&oslash;lger med brugeren. Det g&oslash;res med
JSP-koden:</P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;b&oslash;nnenavn&quot; class=&quot;pakkenavn.Klassenavn&quot; scope=&quot;session&quot; /&gt;</PRE>
<P CLASS="western">Eksempelvis kunne vi knytte en ArrayList (eller
Vector) til brugerens session med:</P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;liste&quot; class=&quot;java.util.ArrayList&quot; scope=&quot;session&quot; /&gt;</PRE><P CLASS="western">
Derefter kan ArrayList-objektet bruges under navnet 'liste'. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Attributten scope=&quot;session&quot;
betyder, at objektet har sessionen som virkefelt, d.v.s. at objektet
vil blive husket og genbrugt n&aelig;ste gang brugeren bes&oslash;ger
siden og at hver bruger vil have sit eget objekt (som beskrevet i
<a href='kapitel4.jsp#afsn4.1'>afsnit 4.1</a>, Sessioner).</SPAN></P>
<BLOCKQUOTE CLASS="definition-western">&lt;jsp:useBean /&gt; bruges
ikke kun til at oprette et objekt, det bruges ogs&aring; til
efterf&oslash;lgende at genbruge objektet</BLOCKQUOTE>
<P CLASS="western"><SPAN LANG="da-DK">Man kan ogs&aring; knytte
objekter til andet end sessionen (beskrives senere, i <a href='kapitel9.jsp#afsn9.2.5'>afsnit 9.2.5</a>).</SPAN></P>


<H3 CLASS="western">9.1.2 <a name='afsn9.1.2'></a>&Oslash;nskeseddel med ArrayList som
javab&oslash;nne 
</H3>
<P CLASS="western">Her ses &oslash;nskeseddel-eksemplet fra <a href='kapitel4.jsp#afsn4.1.1'>afsnit 4.1.1</a>
igen, blot &aelig;ndret til at bruge klassen ArrayList som en
javab&oslash;nne, der er knyttet til brugerens session (&aelig;ndringerne
er i fed). 
</P>
<PRE CLASS="kode-western">&lt;html&gt;
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;&Oslash;nskeseddel - ArrayList som javab&oslash;nne&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK">Dette eksempel demonstrerer, hvordan et ArrayList-objektet kan knyttes til</SPAN>
<SPAN LANG="da-DK">brugerens session som en javab&oslash;nne.</SPAN>

<SPAN LANG="da-DK"><B>&lt;jsp:useBean id=&quot;&oslash;nsker&quot; class=&quot;java.util.ArrayList&quot; scope=&quot;session&quot; /&gt;</B></SPAN>

<SPAN LANG="da-DK">&lt;h3&gt;Skriv et &oslash;nske&lt;/h3&gt;</SPAN>
<SPAN LANG="da-DK">Skriv noget, du &oslash;nsker.</SPAN>
<SPAN LANG="da-DK">&lt;form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;input type=&quot;text&quot; name=&quot;oenske&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK"><I>  // se om der kommer en parameter med endnu et &oslash;nske</I></SPAN>
  String &oslash;nske = request.getParameter(&quot;oenske&quot;);
  if (&oslash;nske != null) {
    &oslash;nsker.add(&oslash;nske);                       <I>// tilf&oslash;j &oslash;nske til listen</I>
  }

  if (&oslash;nsker.size()&gt;0) {                     <I>// udskriv &oslash;nsker i listen</I>
    %&gt;
      &lt;h3&gt;&Oslash;nskeseddel&lt;/h3&gt;
      Indtil nu har du f&oslash;lgende &oslash;nsker:&lt;br&gt;
    &lt;%
<I>    // udskriv hele listen</I>
    for (int i=0; i&lt;&oslash;nsker.size(); i++) 
    { %&gt;
      &Oslash;nske nr. &lt;%= i %&gt;: &lt;%= &oslash;nsker.get(i) %&gt;&lt;br&gt;
    &lt;% }
  }
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western">
Sammenlignet med det oprindelige eksempel i <a href='kapitel4.jsp#afsn4.1.1'>afsnit 4.1.1</a> ser man, at
al arbejdet med at hente listen ud af brugerens session (og evt.
oprette listen) er sparet v&aelig;k.</P>

<H2 CLASS="western" STYLE="">9.2 <a name='afsn9.2'></a>At definere
en javab&oslash;nne og bruge den</SPAN></H2>
<P CLASS="western">Lad os nu se p&aring;, hvordan man definerer sine
egne javab&oslash;nner. Vi definerer klassen Person:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Person.java</I></FONT></P>
<PRE CLASS="kode-western">package minPakke; <I>//oversat fil skal ligge i WEB-INF/classes/minPakke/Person.</I>class

<SPAN LANG="da-DK">public class Person</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private String fornavnet;           <I>// intern variabel (ikke egenskab)</I></SPAN>
<SPAN LANG="da-DK">  private int alderen;                <I>// intern variabel (ikke egenskab)</I></SPAN>

<SPAN LANG="da-DK">  public Person()                     <I>// konstrukt&oslash;r <B>uden</B> parametre skal eksistere</I></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <B>public String getFornavn()  </B>        <I>// afl&aelig;ser egenskaben </I><SPAN STYLE="font-style: normal">fornavn</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    return fornavnet;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <B>public void setFornavn(String n)</B>    <I>// s&aelig;tter egenskaben </I><SPAN STYLE="font-style: normal">fornavn</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    fornavnet = n;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <B>public int getAlder() </B>              <I>// afl&aelig;ser egenskaben </I><SPAN STYLE="font-style: normal">alder</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    return alderen;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <B>public void setAlder(int n)     </B>    <I>// s&aelig;tter egenskaben </I><SPAN STYLE="font-style: normal">alder</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    alderen =  n;</SPAN>
<SPAN LANG="da-DK">    System.out.println(&quot;Alder sat til: &quot;+n); <I>// udskriv &aelig;ndring til loggen</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><H3 CLASS="western">
9.2.1 <a name='afsn9.2.1'></a>Pakker og filplaceringer for klasser</H3>
<P CLASS="western">Vil man bruge en klasse fra en JSP-side, skal
klassen defineres i en pakke<A CLASS="sdfootnoteanc" NAME="sdfootnote1anc" HREF="#sdfootnote1sym"><SUP>1</SUP></A>.
Derfor er b&oslash;nnen defineret i pakken minPakke. 
</P>
<P CLASS="western">Webserveren leder kun efter javaklasser i
undermappen WEB-INF/classes/. Klasserne skal derfor ligge dette
specielle sted, for at kunne bruges fra JSP-siderne. 
</P>
<P CLASS="western">S&aring;ledes skal den oversatte klasse,
Person.class, ligge i WEB-INF/classes/minPakke/ i den webapplikation
klassen tilh&oslash;rer. 
</P>
<H3 CLASS="western">9.2.2 <a name='afsn9.2.2'></a>Egenskaber p&aring; en javab&oslash;nne</H3>
<P CLASS="western">Ofte har en javab&oslash;nne nogle get- og
set-metoder, som kan &aelig;ndre i objektets data. S&aring;danne
metoder kaldes ogs&aring; <I>egenskaber</I> (eng.: properties). 
</P>
<P CLASS="western">Herunder har vi for eksempel b&oslash;nnen Person
med metoderne getFornavn() og setFornavn(), svarende til egenskaben
<I>fornavn</I> og de tilsvarende metoder for egenskaben <I>alder</I>.</P>

<P CLASS="western" STYLE=""><SPAN LANG="da-DK">L&aelig;g
m&aelig;rke til, at b&oslash;nnen har egenskaben <I>alder</I></SPAN>
af typen int, f<SPAN LANG="da-DK">ordi den har metoderne</SPAN></P>
<PRE CLASS="kode-western">  public int getAlder()
<SPAN LANG="da-DK">  public void setAlder(int n)</SPAN></PRE><P CLASS="western">
Hvordan data gemmes internt er underordnet (i dette tilf&aelig;lde
gemmes det i en privat variabel kaldet alderen - data kunne lige s&aring;
godt v&aelig;re lagret p&aring; en anden m&aring;de, f.eks. i form af
 f&oslash;dsels&aring;ret). 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Tilsvarende har b&oslash;nnen
egenskaben <I>fornavn</I></SPAN> af typen String, fordi <SPAN LANG="da-DK">den
har metoderne </SPAN>
</P>
<PRE CLASS="kode-western">  public String getFornavn()
<SPAN LANG="da-DK">  public void setFornavn(String n)</SPAN></PRE><P CLASS="western">
Serveren kan automatisk kalde egenskabernes set-metoder, hvis der
kommer data fra en formular, hvor parameternavnene passer med b&oslash;nnens
egenskaber.</P>

<H3 CLASS="western">9.2.3 <a name='afsn9.2.3'></a>S&aelig;tte egenskaber fra en JSP-side</H3>
<P CLASS="western">En JSP-side, der bruger b&oslash;nnen, kunne have
en formular med parametrene <I>fornavn</I> og <I>alder</I> overf&oslash;rt.
Den kunne se s&aring;ledes ud:</P>
<PRE CLASS="kode-western">&lt;html&gt;
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;En simpel javab&oslash;nne&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:useBean id=&quot;person&quot; class=&quot;minPakke.Person&quot; scope=&quot;session&quot; /&gt;</B></SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:setProperty name=&quot;person&quot; property=&quot;*&quot; /&gt;</B></SPAN>

<SPAN LANG="da-DK">&lt;% if (person.getFornavn() == null) { %&gt;</SPAN>
<SPAN LANG="da-DK">  Indtast dit fornavn og din alder:</SPAN>
<SPAN LANG="da-DK">  &lt;form&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;input type=&quot;text&quot; name=&quot;<B>alder</B>&quot;<SPAN STYLE="font-weight: medium"> size=&quot;4&quot;</SPAN>&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;input type=&quot;submit&quot; value=&quot;OK&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;% } else { %&gt;</SPAN>
<SPAN LANG="da-DK">  Hej &lt;%= person.getFornavn() %&gt;!</SPAN>
<SPAN LANG="da-DK">  Din alder er: &lt;%= person.getAlder() %&gt;.</SPAN>
<SPAN LANG="da-DK">&lt;% } %&gt;</SPAN>
<SPAN LANG="da-DK">&lt;br&gt;Til den &lt;a href=&quot;en_simpel_javaboenne_2.jsp&quot;&gt;anden side&lt;/a&gt;.</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western" ALIGN=CENTER>
<IMG SRC="bog10_html_230cabf0.png" NAME="Grafik87" ALIGN=BOTTOM BORDER=0><SPAN LANG="da-DK">
    
<IMG SRC="bog10_html_7c632251.png" NAME="Grafik88" ALIGN=BOTTOM BORDER=0></SPAN></P>
<P CLASS="western">Udfylder man formularen, ser man, at dens indhold
kommer over i javab&oslash;nnen (i serverens log kan man ogs&aring;
se at metoden setAlder() bliver kaldt). 
</P>
<P CLASS="western">Det skyldes linjen, der afl&aelig;ser parametrene
(fornavn og alder) og kalder set-metoder i b&oslash;nnen
(setFornavn() og setAlder()):</P>
<PRE CLASS="kode-western">&lt;jsp:setProperty name=&quot;person&quot; property=&quot;*&quot; /&gt;</PRE><H4 CLASS="western">
Faldgruber</H4>
<P CLASS="western">N&aring;r du definerer egenskaber og vil binde dem
til formularfelter, s&aring; husk:</P>
<BLOCKQUOTE CLASS="definition-western">Formularfelter b&oslash;r
altid skrives med <I>lille</I> startbogstav. <SPAN LANG="da-DK">De
tilsvarende metoder i b&oslash;nnen b&oslash;r altid skrives med
<I>stort</I> startbogstav efter get/set</SPAN></BLOCKQUOTE>
<P CLASS="western">Forklaringen er, at formularfeltet (som bliver
navnet p&aring; parameteren og egenskaben) har stort <SPAN LANG="da-DK">startbogstav
i metodenavnet efter get/set. Hedder egenskaben f.eks. 'fornavn'
kommer metoderne i b&oslash;nnen til at hedde getFornavn() og
setFornavn().</SPAN></P>
<P CLASS="western">Brug derfor sm&aring; bogstaver i formularfeltet,
f.eks :</P>
<PRE CLASS="kode-western">  &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt;  <I>&lt;%-- rigtigt --%&gt;</I></PRE><P CLASS="western">
Brug aldrig f.eks. 
</P>
<PRE CLASS="kode-western">  &lt;input type=&quot;text&quot; name=&quot;<B>Fornavn</B>&quot;&gt;  <I>&lt;%-- forkert! --%&gt;</I></PRE><P CLASS="western">
og heller ikke: 
</P>
<PRE CLASS="kode-western"><SPAN LANG="da-DK">  &lt;input type=&quot;text&quot; name=&quot;<B>FORNAVN</B>&quot;&gt;  <I>&lt;%-- forkert! --%&gt;</I></SPAN></PRE><P CLASS="western">
En anden hyppig fejltagelse er at glemme formen af metoderne
beskrevet i <a href='kapitel9.jsp#afsn9.2.2'>afsnit 9.2.2</a>.</P>
<H3 CLASS="western">9.2.4 <a name='afsn9.2.4'></a>Afl&aelig;se b&oslash;nnens egenskaber</H3>
<P CLASS="western">Egenskaber kan ogs&aring; afl&aelig;ses for b&oslash;nnen
og inds&aelig;ttes i HTML-koden. Med f.eks.:</P>
<PRE CLASS="kode-western">Din alder er: &lt;jsp:getProperty name=&quot;person&quot; property=&quot;alder&quot; /&gt;.</PRE><P CLASS="western">
bliver v&aelig;rdien af b&oslash;nnens egenskab <I>alder</I> sat ind.
</P>
<P CLASS="western">Det er kortere simpelt hen at skrive f.eks.:</P>
<PRE CLASS="kode-western">Din alder er: &lt;%= person.getAlder() %&gt;.</PRE><P CLASS="western">
Derfor ses koden &lt;jsp:getProperty ... /&gt; i praksis ikke s&aring;
ofte.</P>
<H3 CLASS="western">9.2.5 <a name='afsn9.2.5'></a>Virkefelter for javab&oslash;nner</H3>
<P CLASS="western">Her er en anden side, der ogs&aring; bruger
Person-b&oslash;nnen.</P>
<PRE CLASS="kode-western">&lt;html&gt;
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;En simpel javab&oslash;nne 2&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:useBean id=&quot;person&quot; class=&quot;minPakke.Person&quot; scope=&quot;session&quot; /&gt;</B></SPAN>

<SPAN LANG="da-DK">Hej igen, &lt;%= person.getFornavn() %&gt;.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Dette er en anden side, der ogs&aring; bruger javab&oslash;nnen person.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Din alder er i &oslash;vrigt &lt;%= person.getAlder() %&gt; &aring;r.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Til den &lt;a href=&quot;en_simpel_javaboenne.jsp&quot;&gt;f&oslash;rste side&lt;/a&gt;.</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western">
Bes&oslash;ger man denne, vil man se, at dataene fra
en_simpel_javaboenne.jsp er gemt:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_m2b45912e.png" NAME="Grafik43" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Det skyldes, at b&oslash;nnen har sessionen som
virkefelt (eng.: scope). Objektet vil blive husket i brugerens
session og genbrugt, n&aring;r brugeren bes&oslash;ger andre sider,
der har koden</P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;person&quot; class=&quot;minPakke.Person&quot; scope=&quot;session&quot; /&gt;</PRE><H4 CLASS="western">
Oversigt over de mulige virkefelter</H4>
<P CLASS="western">Virkefeltet scope=&quot;session&quot;, der knytter
b&oslash;nnen til session-objektet (se <a href='kapitel4.jsp#afsn4.5.4'>afsnit 4.5.4</a>, session - objekt der f&oslash;lger den enkelte bruger)
er det mest anvendte, men der findes ogs&aring; andre virkefelter. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Eksempelvis vil
scope=&quot;application&quot;, gemme b&oslash;nnen i
application-objektet (se <a href='kapitel4.jsp#afsn4.5.5'>afsnit 4.5.5</a>, application - f&aelig;lles for hele webapplikationen)
og dermed give b&oslash;nnen hele applikationen som virkefelt, dvs.
at den samme b&oslash;nne deles mellem alle brugere og alle sider
(analogt til en global variabel).</SPAN></P>
<P CLASS="western">Derudover kan en javab&oslash;nne have virkefeltet
scope=&quot;request&quot;. Da knyttes b&oslash;nnen til den aktuelle
anmodning (til request-objektet, se <a href='kapitel4.jsp#afsn4.5.1'>afsnit 4.5.1</a>, request - anmodningen fra klienten)
og bliver smidt v&aelig;k, n&aring;r anmodningen er fuldf&oslash;rt.
Det kan bruges ved server-omdirigering fra en side til en anden (se
<a href='kapitel4.jsp#afsn4.3.2'>afsnit 4.3.2</a>, Server-omdirigering).</P>
<P CLASS="western">Det mest kortlivede virkefelt er scope=&quot;page&quot;,
der knytter b&oslash;nnen til page-objektet. B&oslash;nnen eksisterer
indtil udf&oslash;relsen af den aktuelle side er fuldf&oslash;rt
(omdirigeres der til andre sider smides b&oslash;nnen v&aelig;k). Den
har alts&aring; samme levetid som en almindelig variabel erkl&aelig;ret
i JSP-siden imellem &lt;% og %&gt;. 
</P>

<H3 CLASS="western">9.2.6 <a name='afsn9.2.6'></a>Avanceret: Virkem&aring;den af
&lt;jsp:useBean... /&gt;</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_JSP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/JSP/kapitel9.jsp#afsn9.2.6">
  <input type='checkbox' name='vis' value='9.2.6'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.2.6'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">9.2.7 <a name='afsn9.2.7'></a>Initialisering af javab&oslash;nner</H3>
<P CLASS="western">Ofte &oslash;nsker man at f&aring; noget
programkode k&oslash;rt &eacute;n gang n&aring;r javab&oslash;nnen
initialiseres. Det kan man g&oslash;re ved at l&aelig;gge koden
mellem &lt;jsp:useBean&gt; og &lt;/jsp:useBean&gt;. Herunder skriver
vi ud hver gang et person-objekt bliver oprettet og s&aelig;tter
fornavnet til &quot;(ukendt)&quot;:</P>
<PRE CLASS="ikke-javakode-western">  &lt;jsp:useBean id=&quot;person&quot; class=&quot;minPakke.Person&quot; scope=&quot;session&quot; &gt;
    &lt;%
      out.print(&quot;Et nyt person-objekt blev oprettet!&quot;);
      person.setFornavn(&quot;(ukendt)&quot;);
    %&gt;
  &lt;/jsp:useBean&gt; </PRE><P CLASS="western">
<SPAN LANG="da-DK">Et eksempel p&aring; dette er vist i <a href='kapitel10.jsp#afsn10.4.4'>afsnit 10.4.4</a>.</SPAN></P>

<H3 CLASS="western">9.2.8 <a name='afsn9.2.8'></a>Avanceret: Virkem&aring;den af
&lt;jsp:setProperty .../&gt;</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_JSP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/JSP/kapitel9.jsp#afsn9.2.8">
  <input type='checkbox' name='vis' value='9.2.8'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.2.8'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H2 CLASS="western" STYLE="">9.3 <a name='afsn9.3'></a>Egenskaber
p&aring; en javab&oslash;nne</SPAN></H2>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_JSP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/JSP/kapitel9.jsp#afsn9.3">
  <input type='checkbox' name='vis' value='9.3'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.3'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  
<H3 CLASS="western">9.3.1 <a name='afsn9.3.1'></a>Indekserede egenskaber</H3>
<P CLASS="western">Derudover kan egenskaber v&aelig;re <I>indekseret</I>.
En egenskab siges at v&aelig;re indekseret, hvis HTML-sidens formular
har flere parametre, der hedder det samme.</P>
<P CLASS="western">Herunder er et eksempel p&aring; brug af
indekserede egenskaber. 
</P>
<PRE CLASS="kode-western">&lt;html&gt;
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Indekserede egenskaber&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:useBean id=&quot;ie&quot; class=&quot;minPakke.IndekseredeEgenskaber&quot; scope=&quot;session&quot; /&gt;</B></SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:setProperty name=&quot;ie&quot; property=&quot;*&quot; /&gt;</B></SPAN>
<SPAN LANG="da-DK">Indtast et antal fornavne og aldre:</SPAN>
<SPAN LANG="da-DK">&lt;form&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt; &lt;input type=&quot;text&quot; name=&quot;<B>alder</B>&quot;&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt; &lt;input type=&quot;text&quot; name=&quot;<B>alder</B>&quot;&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt; &lt;input type=&quot;text&quot; name=&quot;<B>alder</B>&quot;&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;text&quot; name=&quot;<B>fornavn</B>&quot;&gt; &lt;input type=&quot;text&quot; name=&quot;<B>alder</B>&quot;&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;submit&quot; value=&quot;OK&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;br&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Resultatet udskrives i serverens log.</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western">
Javab&oslash;nnen har defineret de indekserede egenskaber <I>fornavn</I>
og <I>alder</I> til at modtage parametrene:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>IndekseredeEgenskaber.java</I></FONT></P>
<PRE CLASS="kode-western">package minPakke;
<SPAN LANG="da-DK">public class IndekseredeEgenskaber</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  <B>public void setFornavn(String[] arr)</B>  <I>// s&aelig;tter indekseret egenskab </I><SPAN STYLE="font-style: normal">fornavn</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    for (int i = 0; i &lt; arr.length; i++) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(&quot;setFornavn(arr[&quot;+i+&quot;] = &quot;+arr[i]+&quot;)&quot;);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <B>public void setAlder(int[] arr)   </B>    <I>// s&aelig;tter indekseret egenskab </I><SPAN STYLE="font-style: normal">alder</SPAN></SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    for (int i = 0; i &lt; arr.length; i++) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(&quot;setAlder(arr[&quot;+i+&quot;] = &quot;+arr[i]+&quot;)&quot;);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western" STYLE="">
Lad os nu forestille os at brugeren udfylder formularen med f.eks.:</P>

<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_13b389d0.png" NAME="Grafik21" ALIGN=LEFT BORDER=0><BR CLEAR=LEFT><BR><BR>
</P>
<P CLASS="western">Da vil javab&oslash;nnen udskrive i serverens log
(for Tomcat hedder den logs/catalina.out):</P>
<PRE CLASS="western">setAlder(arr[0] = 33)
<SPAN LANG="da-DK">setAlder(arr[1] = 31)</SPAN>
<SPAN LANG="da-DK">setAlder(arr[2] = 15)</SPAN>
<SPAN LANG="da-DK">setAlder(arr[3] = 0)</SPAN>
<SPAN LANG="da-DK">setFornavn(arr[0] = Jacob)</SPAN>
<SPAN LANG="da-DK">setFornavn(arr[1] = Anne Mette)</SPAN>
<SPAN LANG="da-DK">setFornavn(arr[2] = G&uuml;lsen)</SPAN>
<SPAN LANG="da-DK">setFornavn(arr[3] = Aske)</SPAN>
</PRE><H2 CLASS="western" STYLE="">
9.4 <a name='afsn9.4'></a>Eksempel: En dagskalender</SPAN></H2>
<P CLASS="western">Dette eksempel er et mindre program, der viser en
dagskalender og giver mulighed for at redigere i den. 
</P>
<H3 CLASS="western">9.4.1 <a name='afsn9.4.1'></a>Udseende</H3>
<P CLASS="western">Som udgangspunkt ser kalenderen s&aring;ledes ud:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_685d1fc0.png" NAME="Grafik44" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Klikker man p&aring; &quot;rediger&quot; kommer
samme sk&aelig;rmbillede frem, men denne gang med indtastningsfelter
s&aring; man kan rette i teksten:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_m207d43c7.png" NAME="Grafik45" ALIGN=BOTTOM BORDER=0></P>

<H3 CLASS="western" STYLE="">9.4.2 <a name='afsn9.4.2'></a>Programmets
virkem&aring;de</H3>
<P CLASS="western">Programmet best&aring;r af JSP-siden kalender.jsp
og klasserne Bruger.java og Kalender.java.</P>
<P CLASS="western">Klassen Bruger er en javab&oslash;nne, der knyttes
til brugerens session. Hver bruger f&aring;r derfor sit eget
Bruger-objekt. Alle Bruger-objekterne kommunikerer med det samme
Kalender-objekt (derved bliver det en f&aelig;lles kalender). 
</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_m75f1ff7f.gif" NAME="Objekt31" ALIGN=MIDDLE></P>
<P CLASS="western">Kalender-objektet repr&aelig;senterer logikken i
programmet og er ikke specielt rettet mod en webapplikation, men
kunne ogs&aring; bruges i andre sammenh&aelig;nge. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Her er klassediagrammet
(private</SPAN> metoder og variabler er ikke vist):</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_4022809b.gif" NAME="Objekt2"></P>

<H3 CLASS="western" STYLE="">9.4.3 <a name='afsn9.4.3'></a>HTML-siden
(kalender.jsp)</H3>
<P CLASS="western">F&oslash;rst JSP-siden som brugeren ser:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>kalender.jsp</I></FONT></P>
<PRE CLASS="kode-western"><I>&lt;%-- Knyt b&oslash;nnen Bruger til brugerens session under navnet b --%&gt;</I>
<SPAN LANG="da-DK"><B>&lt;jsp:useBean id=&quot;b&quot; class=&quot;kalender.Bruger&quot; scope=&quot;session&quot; /&gt;</B></SPAN>

<SPAN LANG="da-DK"><I>&lt;%-- Overf&oslash;r parametre til b, der svarer til egenskaber --%&gt;</I></SPAN>
<SPAN LANG="da-DK"><B>&lt;jsp:setProperty name=&quot;b&quot; property=&quot;*&quot; /&gt;</B></SPAN>

<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Kalender&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;F&aelig;lleskalender for &lt;%= b.getDatostr() %&gt;&lt;/h1&gt;</SPAN>

<SPAN LANG="da-DK">&lt;a href=&quot;kalender.jsp?maaned=&lt;%= b.getMaaned()-1 %&gt;&quot;&gt;forrige&lt;/a&gt; m&aring;ned -</SPAN>
<SPAN LANG="da-DK">&lt;a href=&quot;kalender.jsp?maaned=&lt;%= b.getMaaned()+1 %&gt;&quot;&gt;n&aelig;ste&lt;/a&gt; m&aring;ned -</SPAN>
<SPAN LANG="da-DK">&lt;% </SPAN>
<SPAN LANG="da-DK">  if (b.isRediger()) { <I>// redigering - vis en input-formular</I></SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>

<SPAN LANG="da-DK">  &lt;a href=&quot;kalender.jsp?rediger=false&quot;&gt;vis&lt;/a&gt; kalenderen.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;br&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;form action=&quot;kalender.jsp&quot; method=&quot;post&quot;&gt;</SPAN>
<SPAN LANG="da-DK">    Tryk &lt;input type=&quot;submit&quot; value=&quot;OK&quot;&gt; n&aring;r du vil gemme &aelig;ndringer.&lt;br&gt;</SPAN>

<SPAN LANG="da-DK">    &lt;% b.udskrivDagsprogram(out); %&gt;</SPAN>

<SPAN LANG="da-DK">    &lt;br&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;input type=&quot;submit&quot; value=&quot;OK&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  } else {             <I>// fremvisning</I></SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;a href=&quot;kalender.jsp?rediger=true&quot;&gt;redig&eacute;r&lt;/a&gt; kalenderen.&lt;br&gt;</SPAN>

<SPAN LANG="da-DK">  &lt;% b.udskrivDagsprogram(out); %&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  } </SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western">
Bem&aelig;rk hvordan vi definerer variablen b af type Bruger og
opretter et objekt, der genbruges i hele den kommende session:</P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;b&quot; class=&quot;kalender.Bruger&quot; scope=&quot;session&quot; /&gt;</PRE><P CLASS="western">
<SPAN LANG="da-DK">JSP-siden benytter Bruger-b&oslash;nnens
egenskaber <I>rediger</I>, <I>maaned</I> og <I>dagsprogram</I>. Vi
s&oslash;rger for at egenskaber p&aring; b bliver sat, hvis de
tilsvarende parametre overf&oslash;res til siden med:</SPAN></P>
<PRE CLASS="kode-western">&lt;jsp:setProperty name=&quot;b&quot; property=&quot;*&quot; /&gt;</PRE><P CLASS="western">
der (j.v.f. <a href='kapitel9.jsp#afsn9.2.6'>afsnit 9.2.6</a>) svarer til koden:</P>
<PRE CLASS="kode-western">  String parm1 = request.getParameter(&quot;rediger&quot;);
<SPAN LANG="da-DK">  if (parm1 != null) b.setRediger( parm1.equals(&quot;true&quot;) );</SPAN>

<SPAN LANG="da-DK">  String parm2 = request.getParameter(&quot;maaned&quot;);</SPAN>
<SPAN LANG="da-DK">  if (parm2 != null) b.setMaaned( Integer.parseInt(parm2) );</SPAN>

<SPAN LANG="da-DK">  String[] parm3 = request.getParameterValues(&quot;dagsprogram&quot;);</SPAN>
<SPAN LANG="da-DK">  if (parm3 != null) b.setDagsprogram  ( parm3 );</SPAN></PRE><H3 CLASS="western" STYLE="">
9.4.4 <a name='afsn9.4.4'></a>Bruger-b&oslash;nnen (Bruger.java)</H3>
<P CLASS="western">Herunder er Bruger-b&oslash;nnens<I>.</I> Metoder
der svarer til egenskaber er fremh&aelig;vet med fed:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Bruger.java</I></FONT></P>
<PRE CLASS="kode-western">package kalender;
<SPAN LANG="da-DK">import java.util.*;</SPAN>
<SPAN LANG="da-DK">import java.text.*;</SPAN>
<SPAN LANG="da-DK">import java.io.*;</SPAN>

<SPAN LANG="da-DK">public class Bruger {</SPAN>
<SPAN LANG="da-DK">  private SimpleDateFormat m&aring;nedFormat;</SPAN>
<SPAN LANG="da-DK">  private SimpleDateFormat dagugedagFormat;</SPAN>

<SPAN LANG="da-DK">  public void setLocale(Locale sproget) { </SPAN>
<SPAN LANG="da-DK">    m&aring;nedFormat = new SimpleDateFormat(&quot;MMMM yyyy&quot;,sproget); <I>// f.x. 'maj 2004'</I></SPAN>
<SPAN LANG="da-DK">    dagugedagFormat = new SimpleDateFormat(&quot;dd EE&quot;,sproget); <I>// f.x. '31 ma'</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <I>// tom konstrukt&oslash;r - ellers er det ikke en javab&oslash;nne</I></SPAN>
<SPAN LANG="da-DK">  public Bruger() { setLocale(</SPAN>new Locale(&quot;da&quot;,&quot;DK&quot;)); }

<SPAN LANG="da-DK">  private boolean redigering;</SPAN>
<SPAN LANG="da-DK">  public void <B>setRediger(boolean r)</B> { redigering = r; }</SPAN>
<SPAN LANG="da-DK">  public boolean isRediger() { return redigering; }</SPAN>

<SPAN LANG="da-DK">  private GregorianCalendar dato = new GregorianCalendar();</SPAN>

<SPAN LANG="da-DK">  public void <B>setMaaned(int m)</B> {</SPAN>
<SPAN LANG="da-DK">    dato.set(Calendar.MONTH, m);</SPAN>
<SPAN LANG="da-DK">    dato.set(Calendar.DAY_OF_MONTH, 1); <I>// f&oslash;rste dag, s&aring; hele m&aring;neden ses</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">  public int getMaaned() { return dato.get(Calendar.MONTH); }</SPAN>

<SPAN LANG="da-DK">  <I>/** Giver aktuelle m&aring;ned og &aring;r som en streng */</I></SPAN>
<SPAN LANG="da-DK">  public String getDatostr() { return m&aring;nedFormat.format(dato.getTime()); }</SPAN>

<SPAN LANG="da-DK"><I>  /** Egenkaben </I><SPAN STYLE="font-style: normal">dagsprogram</SPAN><I> er et array af strenge, en for hver dag.</I></SPAN>
<SPAN LANG="da-DK"><I>   *  der kaldes videre i det f&aelig;lles Kalender-objekt                   */</I></SPAN>
<SPAN LANG="da-DK">  public void <B>setDagsprogram(String[] dagsprogram) </B>{</SPAN>
<SPAN LANG="da-DK">    redigering = false;</SPAN>
<SPAN LANG="da-DK">    int start = Kalender.instans.beregnIndex(dato);</SPAN>
<SPAN LANG="da-DK">    for (int i=0; i&lt;dagsprogram.length; i++)</SPAN>
<SPAN LANG="da-DK">      Kalender.instans.s&aelig;tDagstekst(start+i,dagsprogram[i]);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /** Producerer HTML-kode der viser et dagsprogram */</I></SPAN>
<SPAN LANG="da-DK">  public void udskrivDagsprogram(Writer out) throws IOException {</SPAN>
<SPAN LANG="da-DK">    GregorianCalendar kal = (GregorianCalendar) dato.clone();</SPAN>
<SPAN LANG="da-DK">    int start = Kalender.instans.beregnIndex(kal);</SPAN>
<SPAN LANG="da-DK">    int antal = 1 + dato.getActualMaximum(Calendar.DAY_OF_MONTH)</SPAN>
<SPAN LANG="da-DK">                  - dato.get(Calendar.DAY_OF_MONTH);</SPAN>
<SPAN LANG="da-DK">    for (int i=0; i&lt;antal; i++) {</SPAN>
<SPAN LANG="da-DK">      String dagugedag = dagugedagFormat.format(kal.getTime());</SPAN>
<SPAN LANG="da-DK">      out.write(&quot;&lt;br&gt;\n&lt;code&gt;&quot;);</SPAN>
<SPAN LANG="da-DK">      out.write(dagugedag);</SPAN>
<SPAN LANG="da-DK">      out.write(&quot;&lt;/code&gt; &quot;);</SPAN>
<SPAN LANG="da-DK">      if (!redigering) out.write(Kalender.instans.hentDagstekst(i+start));</SPAN>
<SPAN LANG="da-DK">      else out.write(&quot;&lt;input type='text' size=30 <B>name='dagsprogram'</B> value='&quot;</SPAN>
<SPAN LANG="da-DK">        + Kalender.instans.hentDagstekst(i+start).replace('\'','\&quot;') + &quot;'&gt;&quot;);</SPAN>
<SPAN LANG="da-DK">      kal.roll(Calendar.DAY_OF_MONTH,1);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<P CLASS="western">Bem&aelig;rk hvordan egenskaben <I>dagsprogram</I>
svarer til metoden setDagsprogram() og inputfeltet i HTML-formularen
med navnet dagsprogram. Egenskaben er et eksempel p&aring; en
<I>indekseret</I> egenskab, da den s&aelig;ttes med et array (se
<a href='kapitel9.jsp#afsn9.3.1'>afsnit 9.3.1</a>, Indekserede egenskaber).</P>
<P CLASS="western">Selve HTML-koden til dagsprogrammet bliver ikke
produceret af JSP-siden. I stedet kaldes metoden udskrivDagsprogram()
med out-objektet som parameter p&aring; Bruger-objektet, der s&aring;
producerer HTML-koden.</P>
<P CLASS="western">Man kunne ogs&aring; havde ladet JSP-siden
producere HTML-koden til kalenderen (det ville nok v&aelig;re bedre
stil, men ville ogs&aring; g&oslash;re eksemplet sv&aelig;rere at
overskue).</P>
<H3 CLASS="western">9.4.5 <a name='afsn9.4.5'></a>Kalender-objektet (Kalender.java)</H3>
<P CLASS="western">Den anden klasse er et Kalender-objekt, der
fungerer som data-lager og husker aftalerne. 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Kalender.java</I></FONT></P>
<PRE CLASS="kode-western">package kalender;

<SPAN LANG="da-DK">import java.util.*;</SPAN>
<SPAN LANG="da-DK">import java.text.*;</SPAN>
<SPAN LANG="da-DK">import java.beans.*;</SPAN>
<SPAN LANG="da-DK">import java.io.*;</SPAN>

<SPAN LANG="da-DK">public class Kalender</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private boolean &aelig;ndret;</SPAN>
<SPAN LANG="da-DK">  private List liste;</SPAN>
<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param kal Datoen vi &oslash;nsker at kende indekset i listen p&aring;</I></SPAN>
<SPAN LANG="da-DK"><I>   * @returns indekset der skal bruges i kald til s&aelig;t() og hent().</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  public int beregnIndex(Calendar kal) {</SPAN>
<SPAN LANG="da-DK">    int &aring;r = kal.get(Calendar.YEAR);</SPAN>
<SPAN LANG="da-DK">    int dag = kal.get(Calendar.DAY_OF_YEAR);</SPAN>
<SPAN LANG="da-DK">    <I>// det vigtigste er at to dage aldrig f&aring;r samme indeks</I></SPAN>
<SPAN LANG="da-DK">    return (&aring;r-2003)*366+dag;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * S&aelig;t teksten for en bestemt dag.</I></SPAN>
<SPAN LANG="da-DK"><I>   * @see #beregnIndeks(Calendar)</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param indeks Indekset i listen. Skal f&oslash;rst findes med beregnIndeks()</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param tekst Teksten for dagen</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  public void s&aelig;tDagstekst(int indeks, String tekst) {</SPAN>
<SPAN LANG="da-DK">    <I>// Fyld op med tomme strenge hvis der g&aring;s ud over listen</I></SPAN>
<SPAN LANG="da-DK">    while (indeks&gt;=liste.size()) liste.add(&quot;&quot;);</SPAN>
<SPAN LANG="da-DK">    liste.set(indeks,tekst);</SPAN>
<SPAN LANG="da-DK">    &aelig;ndret = true;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * Hent teksten for en bestemt dag.</I></SPAN>
<SPAN LANG="da-DK"><I>   * @see #beregnIndeks(GregorianCalendar)</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param index Indekset i listen. Skal f&oslash;rst findes med beregnIndeks()</I></SPAN>
<SPAN LANG="da-DK"><I>   * @return tekst Teksten for dagen</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  public String hentDagstekst(int indeks) {</SPAN>
<SPAN LANG="da-DK">    if (indeks&lt;0 || liste.size()&lt;=indeks) return &quot;&quot;;</SPAN>
<SPAN LANG="da-DK">    else return (String) liste.get(indeks);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public static final Kalender instans = new Kalender(); <I>// singleton med</I></SPAN>

<SPAN LANG="da-DK">  private Kalender() {                                   <I>// privat konstrukt&oslash;r</I></SPAN>
<SPAN LANG="da-DK">    try { <I>// indl&aelig;s kalenderen fra XML-fil p&aring; disken (hvis den findes)</I></SPAN>
<SPAN LANG="da-DK">      XMLDecoder kal = new XMLDecoder(new FileInputStream(&quot;kalender.xml&quot;));</SPAN>
<SPAN LANG="da-DK"><I>      // alternativ: hent serialiseret objekt i stedet for XML-data</I></SPAN>
<SPAN LANG="da-DK"><I>      //ObjectInputStream kal = new ObjectInputStream(</I></SPAN>
<SPAN LANG="da-DK"><I>      //                        new FileInputStream(&quot;kalender.ser&quot;));</I></SPAN>
<SPAN LANG="da-DK">      liste = (ArrayList) kal.readObject();</SPAN>
<SPAN LANG="da-DK">      kal.close();</SPAN>
<SPAN LANG="da-DK">      System.out.println(&quot;Kalender indl&aelig;st: &quot;+liste);</SPAN>
<SPAN LANG="da-DK">    } catch (Exception e) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(&quot;Kalender ikke indl&aelig;st, opretter ny: &quot;+e);</SPAN>
<SPAN LANG="da-DK">      liste = new ArrayList();</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    GemRegelm&aelig;ssigt g = new GemRegelm&aelig;ssigt(); <I>// gemmer kalenderen p&aring; disken</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /** S&oslash;rger for at gemme kalenderen regelm&aelig;ssigt (i en separat tr&aring;d) */</I></SPAN>
<SPAN LANG="da-DK">  class GemRegelm&aelig;ssigt extends Thread</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    public GemRegelm&aelig;ssigt() {</SPAN>
<SPAN LANG="da-DK">      setDaemon(true);   <I>// systemet m&aring; godt stoppe selvom tr&aring;den stadig k&oslash;rer</I></SPAN>
<SPAN LANG="da-DK">      setPriority(MIN_PRIORITY);</SPAN>
<SPAN LANG="da-DK">      start();</SPAN>
<SPAN LANG="da-DK">    }</SPAN>

<SPAN LANG="da-DK">    public void run() {</SPAN>
<SPAN LANG="da-DK">      while (true) try {</SPAN>
<SPAN LANG="da-DK">        Thread.sleep(1*60*1000); <I>// hvert minut,</I></SPAN>
<SPAN LANG="da-DK">        if (&aelig;ndret) {            <I>// hvis kalenderen er &aelig;ndret</I></SPAN>
<SPAN LANG="da-DK">          &aelig;ndret = false;        <I>// gem kalenderen p&aring; disken</I></SPAN>
<SPAN LANG="da-DK"><I>          // gem som XML</I></SPAN>
<SPAN LANG="da-DK">          XMLEncoder kal = new XMLEncoder(new FileOutputStream(&quot;kalender.xml&quot;));</SPAN>
<SPAN LANG="da-DK"><I>          // alternativ: gem som serialiseret objekt i stedet for XML</I></SPAN>
<SPAN LANG="da-DK"><I>          //ObjectOutputStream kal = new ObjectOutputStream(</I></SPAN>
<SPAN LANG="da-DK"><I>          //                         new FileOutputStream(&quot;kalender.ser&quot;));</I></SPAN>
<SPAN LANG="da-DK">          kal.writeObject(liste);</SPAN>
<SPAN LANG="da-DK">          kal.close();</SPAN>
<SPAN LANG="da-DK">          System.out.println(&quot;Kalender gemt: &quot;+liste);</SPAN>
<SPAN LANG="da-DK">        }</SPAN>
<SPAN LANG="da-DK">      } catch (Exception e) { e.printStackTrace(); }</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
Denne kalender er f&aelig;lles for alle brugerne og er programmeret
s&aring;dan, at der kun bliver oprettet &eacute;t objekt af typen
Kalender (en singleton). 
</P>
<P CLASS="western"><SPAN LANG="da-DK">I stedet for at bruge en
database henter og gemmer kalenderen en gang imellem sine data i en
XML-fil (med navnet 'kalender.xml'). Formatet og indholdet af
XML-filen diskuteres i <a href='kapitel11.jsp#afsn11.2.2'>afsnit 11.2.2</a>, Nem generering af XML fra Java-objekter.
Kommenteret v&aelig;k er ogs&aring; kode til i stedet at gemme data
serialiseret i en fil (med navnet 'kalender.ser').</SPAN></P>

<H2 CLASS="western" STYLE="">9.5 <a name='afsn9.5'></a>Eksempel:
Login og brugeroprettelse</SPAN></H2>
<P CLASS="western">Det f&oslash;lgende eksempel viser, hvordan man
kan have beskyttede sider, hvor brugerne skal logge ind med
brugernavn og adgangskode, defineret i en database.</P>
<P CLASS="western">Derudover kan nye brugere registrere sig, ved at
opgive en epost-adresse, hvorefter en bruger vil blive oprettet i
databasen og en adgangskode vil blive sendt til epost-adressen. 
</P>
<P CLASS="western">Hvis brugeren &oslash;nsker det, kan hans
oplysninger gemmes i en cookie, s&aring;dan at han automatisk kan
blive logget ind, n&aelig;ste gang han bes&oslash;ger siden.</P>
<H3 CLASS="western">9.5.1 <a name='afsn9.5.1'></a>Brug af eksemplet</H3>
<P CLASS="western">Eksemplet er udformet s&aring;ledes, at du kan
tage det og bruge det i dit eget projekt. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Bem&aelig;rk dog, at der i
n&aelig;sten alle webservere allerede findes foruddefinerede m&aring;der
at lave beskyttede sider p&aring;, blot ved at &aelig;ndre i
konfigurationsfilerne, som beskrevet i <a href='kapitel8.jsp#afsn8.2.1'>afsnit 8.2.1</a>, Containerstyret adgangskontrol.
</SPAN>
</P>
<P CLASS="western">Eksemplet her er derfor reelt kun n&oslash;dvendigt
at kopiere, hvis du &oslash;nsker f.eks. dynamisk brugeroprettelse
med tilsending af adgangskoder eller du selv vil styre det pr&aelig;cise
udseende af login-sk&aelig;rmbilledet eller en af de andre ting n&aelig;vnt
i <a href='kapitel8.jsp#afsn8.2'>afsnit 8.2</a>, Adgangskontrol.</P>
<H3 CLASS="western">9.5.2 <a name='afsn9.5.2'></a>Login-b&oslash;nnen</H3>
<P CLASS="western">F&oslash;rst javab&oslash;nnen Login.java. Den har
egenskaberne <I>brugernavn og adgangskode<SPAN STYLE="text-decoration: none">,
</SPAN></I><SPAN STYLE="text-decoration: none"><SPAN STYLE="font-style: normal">der
skal v&aelig;re korrekt sat f&oslash;r egenskaben </SPAN><I>ok</I><SPAN STYLE="font-style: normal">
bliver sand og brugeren f&aring;r lov til at komme videre.</SPAN></SPAN></P>
<P CLASS="western">Metoderne, der svarer til egenskaber, er fremh&aelig;vet
med fed. 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Login.java</I></FONT></P>
<PRE CLASS="kode-western">package javabog;

<SPAN LANG="da-DK">import java.sql.*;</SPAN>
<SPAN LANG="da-DK">import java.util.*;</SPAN>
<SPAN LANG="da-DK">import javax.mail.*;</SPAN>
<SPAN LANG="da-DK">import javax.mail.internet.*;</SPAN>
<SPAN LANG="da-DK">import javax.servlet.*;</SPAN>
<SPAN LANG="da-DK"><I>/**</I></SPAN>
<SPAN LANG="da-DK"><I> * Denne javab&oslash;nne har ansvaret for registrering og logintjek af en bruger.</I></SPAN>
<SPAN LANG="da-DK"><I> * Husk at mail.jar, activation.jar og MySQL-driveren skal v&aelig;re i CLASSPATH</I>.</SPAN>
<SPAN LANG="da-DK"><I> */</I></SPAN>
<SPAN LANG="da-DK">public class Login</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private String brugernavn = &quot;&quot;;</SPAN>
<SPAN LANG="da-DK">  private String adgangskode = &quot;&quot;;</SPAN>
<SPAN LANG="da-DK">  private String epost = &quot;&quot;;</SPAN>
<SPAN LANG="da-DK">  private String meddelelse = &quot;&quot;;       <I>// fejlmeddelelse til brugeren</I></SPAN>

<SPAN LANG="da-DK">  private boolean tjek = false;         <I>// om adgangskode skal tjekkes</I></SPAN>
<SPAN LANG="da-DK">  private boolean loggetInd = false;    <I>// om adgangskoden var korrekt</I></SPAN>

<SPAN LANG="da-DK">  public void <B>setBrugernavn(String bn)</B>  { tjek=true; brugernavn=bn; }</SPAN>
<SPAN LANG="da-DK">  public <B>String getBrugernavn()</B>         { return brugernavn; }</SPAN>

<SPAN LANG="da-DK">  public void <B>setAdgangskode(String ak)</B> { tjek=true; adgangskode = ak; }</SPAN>

<SPAN LANG="da-DK">  public void <B>setEpost(String epost)</B>    { this.epost = epost; }</SPAN>
<SPAN LANG="da-DK">  public <B>String getEpost()</B>              { return epost; }</SPAN>

<SPAN LANG="da-DK">  public void <B>setMeddelelse(String m)</B>   { meddelelse = m; }</SPAN>
<SPAN LANG="da-DK">  public <B>String getMeddelelse()</B> { String m=meddelelse; meddelelse=&quot;&quot;; return m; }</SPAN>

<SPAN LANG="da-DK"><I>  /** Egenskaben loggetInd. Kan af sikkerhedsgrunde kun afl&aelig;ses */</I></SPAN>
<SPAN LANG="da-DK">  public <B>boolean isLoggetInd()</B> {</SPAN>
<SPAN LANG="da-DK">    if (tjek) return false;       <I>// er der sket &aelig;ndringer skal der logges ind</I></SPAN>
<SPAN LANG="da-DK">    return loggetInd;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /** Forbindelsen til databasen. Oprettes n&aring;r klassen indl&aelig;ses */</I></SPAN>
<SPAN LANG="da-DK">  private static Connection con = null;</SPAN>
<SPAN LANG="da-DK">  private static String postserver = null;</SPAN>
<SPAN LANG="da-DK">  private static String postafsender = null;</SPAN>

<SPAN LANG="da-DK"><I>  /** Initialisering. Skal kaldes f&oslash;r b&oslash;nnen bruges */</I></SPAN>
<SPAN LANG="da-DK">  public synchronized static void init(ServletContext application)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (con!=null) return; <I>// initialis&eacute;r kun hvis det ikke allerede er gjort</I></SPAN>

<SPAN LANG="da-DK">   <I>  // Opret forbindelse til databasen n&aring;r klassen bruges f&oslash;rste gang</I></SPAN>
<SPAN LANG="da-DK">    try {</SPAN>
<SPAN LANG="da-DK">      String drv=null, url=null, bru=null, adg=null;</SPAN>
<SPAN LANG="da-DK">      if (application!=null) {</SPAN>
<SPAN LANG="da-DK">        drv = application.getInitParameter(&quot;dbDriver&quot;);</SPAN>
<SPAN LANG="da-DK">        url = application.getInitParameter(&quot;dbUrl&quot;);</SPAN>
<SPAN LANG="da-DK">        bru = application.getInitParameter(&quot;dbBruger&quot;);</SPAN>
<SPAN LANG="da-DK">        adg = application.getInitParameter(&quot;dbAdgangskode&quot;);</SPAN>
<SPAN LANG="da-DK">        postserver = application.getInitParameter(&quot;postserver&quot;);</SPAN>
<SPAN LANG="da-DK">        postafsender = application.getInitParameter(&quot;postafsender&quot;);</SPAN>
<SPAN LANG="da-DK">      }</SPAN>
<SPAN LANG="da-DK">      if (drv==null) drv = &quot;com.mysql.jdbc.Driver&quot;;</SPAN>
<SPAN LANG="da-DK">      if (url==null) url = &quot;jdbc:mysql:///test&quot;;</SPAN>
<SPAN LANG="da-DK">      if (bru==null) bru = &quot;root&quot;;</SPAN>
<SPAN LANG="da-DK">      if (adg==null) adg = &quot;&quot;;</SPAN>

<SPAN LANG="da-DK">      System.out.println(&quot;url=&quot;+url+&quot; bru=&quot;+bru+&quot; adg=&quot;+adg); <I>// til fejlfinding</I></SPAN>
<SPAN LANG="da-DK">      Class.forName(drv);                                  <I>// indl&aelig;s driver</I></SPAN>
<SPAN LANG="da-DK">      con = DriverManager.getConnection(url, bru, adg);    <I>// opret forbindelse</I></SPAN>

<SPAN LANG="da-DK">      Statement s = con.createStatement();</SPAN>

<SPAN LANG="da-DK">      try { <I>// opret tabellen (dette giver en fejl hvis den allerede eksisterer)</I></SPAN>
<SPAN LANG="da-DK">        s.executeUpdate(&quot;CREATE TABLE brugere (brugernavn varchar(20), &quot;+</SPAN>
<SPAN LANG="da-DK">                        &quot;adgangskode varchar(20), epost varchar(50))&quot;);</SPAN>

<SPAN LANG="da-DK">        <I>// Inds&aelig;t s&aring; ogs&aring; nogle brugere, s&aring; der er nogle til at starte med</I></SPAN>
<SPAN LANG="da-DK">        s.executeUpdate(&quot;INSERT INTO brugere VALUES ('Jacob','hemli','')&quot;);</SPAN>
<SPAN LANG="da-DK">        s.executeUpdate(&quot;INSERT INTO brugere VALUES ('Preben','hemli','')&quot;);</SPAN>
<SPAN LANG="da-DK">        s.executeUpdate(&quot;INSERT INTO brugere VALUES ('S&oslash;ren','hemli','')&quot;);</SPAN>
<SPAN LANG="da-DK">        System.out.println(&quot;Bem&aelig;rk: Standardbrugere oprettet (sikkerhedshul!)&quot;);</SPAN>
<SPAN LANG="da-DK">      } catch (SQLException sqlex) {} <I>// OK med fejl her, log dem derfor ikke</I></SPAN>

<SPAN LANG="da-DK">      ResultSet rs = s.executeQuery(&quot;SELECT brugernavn FROM brugere&quot;);</SPAN>
<SPAN LANG="da-DK">      while (rs.next()) System.out.println( &quot;bruger: &quot;+rs.getString(1) );</SPAN>
<SPAN LANG="da-DK">      rs.close();</SPAN>
<SPAN LANG="da-DK">      s.close();</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    catch (Exception ex) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(&quot;Problem med databasen: &quot;+ex);</SPAN>
<SPAN LANG="da-DK">      ex.printStackTrace(); <I>// Kritisk fejl, log den</I></SPAN>
<SPAN LANG="da-DK">      con = null; <I>// s&aelig;t forbindelsen til null og pr&oslash;v at oprette den senere</I></SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /** Tjekker om brugernavn og adgangskode er OK */</I></SPAN>
<SPAN LANG="da-DK">  public void tjekLogin()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (!tjek) return; <I>// er der ikke sket &aelig;ndringer beh&oslash;ver vi ikke tjekke igen</I></SPAN>
<SPAN LANG="da-DK">    loggetInd = false;</SPAN>
<SPAN LANG="da-DK">    tjek = false;</SPAN>
<SPAN LANG="da-DK">    if (brugernavn.length() &gt; 0 &amp;&amp; adgangskode.length() &gt; 0) try {</SPAN>
<SPAN LANG="da-DK">      if (con == null) init(null); <I>// ingen forbindelse - fors&oslash;g at oprette en</I></SPAN>
<SPAN LANG="da-DK">      PreparedStatement s = con.prepareStatement(</SPAN>
<SPAN LANG="da-DK">        &quot;SELECT brugernavn FROM brugere WHERE brugernavn=? AND adgangskode=?&quot;);</SPAN>
<SPAN LANG="da-DK">      s.setString(1, brugernavn);</SPAN>
<SPAN LANG="da-DK">      s.setString(2, adgangskode);</SPAN>
<SPAN LANG="da-DK">      ResultSet rs = s.executeQuery();</SPAN>
<SPAN LANG="da-DK">      if (rs.next()) loggetInd = true; <I>// korrekt! Brugeren er logget ind.</I></SPAN>
<SPAN LANG="da-DK">      else meddelelse = &quot;Forkert brugernavn eller adgangskode&quot;;</SPAN>

<SPAN LANG="da-DK">      rs.close();</SPAN>
<SPAN LANG="da-DK">      s.close();</SPAN>
<SPAN LANG="da-DK">    } catch (Exception e) {</SPAN>
<SPAN LANG="da-DK">      e.printStackTrace();</SPAN>
<SPAN LANG="da-DK">      meddelelse = &quot;Kunne ikke logge ind: &quot; + e;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * Registrerer ny bruger og sender adgangskode til epost-adressen</I></SPAN>
<SPAN LANG="da-DK"><I>   * @return true hvis oprettelsen gik godt, ellers false.</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  public boolean opretBruger()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    tjek = false;</SPAN>
<SPAN LANG="da-DK">    loggetInd = false;</SPAN>
<SPAN LANG="da-DK">    if (brugernavn.length() &gt;= 1 &amp;&amp; epost.length() &gt;= 5 ) try {</SPAN>
<SPAN LANG="da-DK">      String nyAdgangskode = lavNyAdgangskode();</SPAN>
<SPAN LANG="da-DK">      PreparedStatement s = con.prepareStatement(</SPAN>
<SPAN LANG="da-DK">        &quot;INSERT INTO brugere VALUES (?,?,?)&quot;);</SPAN>
<SPAN LANG="da-DK">      s.setString(1, brugernavn);</SPAN>
<SPAN LANG="da-DK">      s.setString(2, nyAdgangskode);</SPAN>
<SPAN LANG="da-DK">      s.setString(3, epost);</SPAN>
<SPAN LANG="da-DK">      s.executeUpdate();</SPAN>
<SPAN LANG="da-DK">      s.close();</SPAN>
<SPAN LANG="da-DK">      sendAdgangskode(nyAdgangskode);</SPAN>
<SPAN LANG="da-DK">      return true;             <I>// oprettelse lykkedes!</I></SPAN>
<SPAN LANG="da-DK">    } catch (Exception e) {</SPAN>
<SPAN LANG="da-DK">      e.printStackTrace();</SPAN>
<SPAN LANG="da-DK">      meddelelse = &quot;Fejl under oprettelsen: &quot;+e;</SPAN>
<SPAN LANG="da-DK">    } else {</SPAN>
<SPAN LANG="da-DK">      meddelelse = &quot;Brugernavn og epost skal v&aelig;re udfyldt&quot;;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    return false;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * adgangskode genereres til ny bruger</I></SPAN>
<SPAN LANG="da-DK"><I>   * @return koden</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  private String lavNyAdgangskode()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    String ord = &quot;&quot;;</SPAN>
<SPAN LANG="da-DK">    for (int j=0; j&lt;6; j++) {</SPAN>
<SPAN LANG="da-DK">      ord = ord + (char) ('a' + (char) (Math.random()*25));</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    return ord;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * Send adgangskoden til brugeren med e-post</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  private void sendAdgangskode(String adgangskoden) throws Exception </SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (postafsender==null) postafsender = &quot;din@adresse.dk&quot;;</SPAN>
<SPAN LANG="da-DK">    if (postserver==null) postserver = &quot;post.tele.dk&quot;;</SPAN>

<SPAN LANG="da-DK">    Properties prop = new Properties();</SPAN>
<SPAN LANG="da-DK">    prop.setProperty(&quot;mail.host&quot;, postserver);   <I>// afh&aelig;nger af internetudbyder</I></SPAN>
<SPAN LANG="da-DK">    prop.setProperty(&quot;mail.transport.protocol&quot;, &quot;smtp&quot;);</SPAN>
<SPAN LANG="da-DK">    Session session = Session.getInstance(prop);</SPAN>

<SPAN LANG="da-DK"><I>    // Opbyg beskedden</I></SPAN>
<SPAN LANG="da-DK">    Message besked = new MimeMessage(session);</SPAN>
<SPAN LANG="da-DK">    besked.setFrom(new InternetAddress(postafsender));</SPAN>
<SPAN LANG="da-DK">    besked.setRecipient(Message.RecipientType.TO, new InternetAddress(epost));</SPAN>
<SPAN LANG="da-DK">    besked.setSubject(&quot;Din adgangskode til javabog.dk&quot;);</SPAN>
<SPAN LANG="da-DK">    String txt = &quot;Din adgangskode til javabog.dk er: &quot;+adgangskoden+&quot;\n&quot;</SPAN>
<SPAN LANG="da-DK">      + &quot;Du kan ogs&aring; logge ind ved at klikke p&aring; nedenst&aring;ende henvisning:\n&quot;</SPAN>
<SPAN LANG="da-DK">      + &quot;http://javabog.dk:8080/JSP/kode/kapitel_09/log_ind.jsp?brugernavn=&quot;</SPAN>
<SPAN LANG="da-DK">      + java.net.URLEncoder.encode(brugernavn,&quot;UTF-8&quot;)+&quot;&amp;adgangskode=&quot;</SPAN>
<SPAN LANG="da-DK">      + java.net.URLEncoder.encode(adgangskoden,&quot;UTF-8&quot;)+&quot;&amp;handling=log+ind&quot;;</SPAN>
<SPAN LANG="da-DK">    besked.setContent(txt, &quot;text/plain&quot;); <I>// put beskedden ind</I></SPAN>
<SPAN LANG="da-DK">    System.out.println(txt);              <I>// skriv ogs&aring; beskedden i serverens log</I></SPAN>

<SPAN LANG="da-DK">    Transport.send(besked);               <I>// send beskedden</I></SPAN>
<SPAN LANG="da-DK">    meddelelse = &quot;Adgangskoden er sendt til adressen &quot;+ epost;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<P CLASS="western"><SPAN LANG="da-DK">Metoden init() skal kaldes f&oslash;r
javab&oslash;nnen tages i brug. Den initialiserer forbindelsen til
databasen (og opretter for nemheds skyld bruger-tabellen, hvis den
ikke allerede findes)<A CLASS="sdfootnoteanc" NAME="sdfootnote2anc" HREF="#sdfootnote2sym"><SUP>2</SUP></A>.</SPAN></P>
<P CLASS="western"><SPAN LANG="da-DK">Metoden forventer at
application-objektet bliver overf&oslash;rt, s&aring;dan at den kan
afl&aelig;se initialiseringsparametrene dbDriver, dbUrl, dbBruger,
dbAdgangskode fra web.xml, som beskrevet i <a href='kapitel4.jsp#afsn4.5.5'>afsnit 4.5.5</a> (der er dog
nogle fornuftige standardv&aelig;rdier i koden, hvis
application-objektet ikke overf&oslash;res eller
initialiseringsparametrene ikke er defineret).</SPAN></P>
<P CLASS="western"><SPAN LANG="da-DK">Metoden tjekLogin() tjekker,
ved at kontakte databasen, om brugeren har angivet korrekt brugernavn
og adgangskode. Af sikkerhedsgrunde bruger den PreparedStatement, for
at undg&aring; SQL-injektioner (se <a href='kapitel5.jsp#afsn5.4.2'>afsnit 5.4.2</a>). </SPAN>
</P>
<P CLASS="western">Resultatet kan afl&aelig;ses med metoden
isLoggetInd(), der svarer til egenskaben <I>loggetInd</I>.</P>
<P CLASS="western"><SPAN LANG="da-DK">Meto</SPAN>den
sendAdgangskode() bruger JavaMail til at sende adgangskoden til
brugeren med epost. For at det virker i din webapplikation skal du
have sat initialiseringsparametren &quot;postserver&quot; til at pege
p&aring; din internetudbyders SMTP-server.</P>

<H3 CLASS="western" STYLE="">9.5.3 <a name='afsn9.5.3'></a>Login-siden</H3>
<P CLASS="western"><SPAN LANG="da-DK">Her kommer log_ind.jsp,
sk&aelig;rmbilledet, hvor brugeren kan logge ind:</SPAN></P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><IMG SRC="bog10_html_fa550f0.png" NAME="Grafik89" ALIGN=BOTTOM BORDER=0><FONT SIZE=2 STYLE="font-size: 9pt"><I><SPAN LANG="da-DK"><BR>log_ind.jsp</SPAN></I></FONT></P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;login&quot; class=&quot;javabog.Login&quot; scope=&quot;session&quot;&gt;
<SPAN LANG="da-DK">  &lt;% login.init(application); %&gt;  <I>&lt;%-- k&oslash;res f&oslash;rste gang b&oslash;nnen bruges --%&gt;</I></SPAN>
<SPAN LANG="da-DK">&lt;/jsp:useBean&gt;</SPAN>

<SPAN LANG="da-DK">&lt;%</SPAN>
<I><SPAN LANG="da-DK">  // Hvis brugernavn og kode er sat i en cookie (se <a href='kapitel3.jsp#afsn3.6.5'>afsnit 3.6.5</a>) s&aring; brug dem:</SPAN></I>
<SPAN LANG="da-DK">  Cookie[] cookier = request.getCookies();</SPAN>
<SPAN LANG="da-DK">  if (cookier != null) for (int i=0; i&lt;cookier.length; i++) {</SPAN>
<SPAN LANG="da-DK">    Cookie c = cookier[i];</SPAN>
<SPAN LANG="da-DK">    System.out.println(&quot;cookie &quot;+c.getName()+&quot;=&quot;+c.getValue());</SPAN>
<SPAN LANG="da-DK">    if (c.getName().equals(&quot;brugernavn&quot;)) login.setBrugernavn(c.getValue());</SPAN>
<SPAN LANG="da-DK">    if (c.getName().equals(&quot;adgangskode&quot;)) login.setAdgangskode(c.getValue());</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK"><I>  // Hvis brugernavn og kode kommer med request-objektet s&aring; s&aelig;t dem:</I></SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;jsp:setProperty name=&quot;login&quot; property=&quot;brugernavn&quot;/&gt;</SPAN>
<SPAN LANG="da-DK">&lt;jsp:setProperty name=&quot;login&quot; property=&quot;adgangskode&quot;/&gt;</SPAN>

<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Log ind&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;img src=&quot;../kapitel_02/billede_med_avatar.jsp&quot; align=&quot;right&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;h1&gt;Log ind&lt;/h1&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form method=&quot;post&quot; action=&quot;log_ind.jsp&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;table&gt;</SPAN>
<SPAN LANG="da-DK">&lt;tr&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;Brugernavn:&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;brugernavn&quot; value=&quot;&lt;%=login.getBrugernavn()%&gt;&quot;&gt;&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/tr&gt;</SPAN>
<SPAN LANG="da-DK">&lt;tr&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;Adgangskode:&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;input type=&quot;password&quot; name=&quot;adgangskode&quot;&gt;&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/tr&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/table&gt;</SPAN>

<SPAN LANG="da-DK">&lt;input type=&quot;submit&quot; name=&quot;handling&quot; value=&quot;log ind&quot;&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;input type=&quot;checkbox&quot; name=&quot;saet cookie&quot;&gt;Husk mig p&aring; denne computer&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Jeg er &lt;a href=&quot;ny_bruger.jsp&quot;&gt;ny bruger&lt;/a&gt; og &oslash;nsker at registrere mig.</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;p&gt;</SPAN>

<SPAN LANG="da-DK">&lt;font color=&quot;red&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">login.tjekLogin();</SPAN>
<SPAN LANG="da-DK">if (login.isLoggetInd()) {</SPAN>
<SPAN LANG="da-DK">  if (request.getParameter(&quot;saet cookie&quot;) != null) {</SPAN>
<SPAN LANG="da-DK">    response.addCookie(</SPAN>
<SPAN LANG="da-DK">      new Cookie(&quot;brugernavn&quot;, request.getParameter(&quot;brugernavn&quot;)));</SPAN>
<SPAN LANG="da-DK">    response.addCookie(</SPAN>
<SPAN LANG="da-DK">      new Cookie(&quot;adgangskode&quot;, request.getParameter(&quot;adgangskode&quot;)));</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">  %&gt;</SPAN>
<SPAN LANG="da-DK">  Du er logget ind som &lt;jsp:getProperty name=&quot;login&quot; property=&quot;brugernavn&quot;/&gt;.</SPAN>
<SPAN LANG="da-DK">  &lt;%</SPAN>
<SPAN LANG="da-DK">} else {</SPAN>
<SPAN LANG="da-DK">  String handling = request.getParameter(&quot;handling&quot;);</SPAN>
<SPAN LANG="da-DK">  if (&quot;log ind&quot;.equals(handling)) {</SPAN>
<SPAN LANG="da-DK">    if (login.getBrugernavn().length()&gt;0) {</SPAN>
<SPAN LANG="da-DK">      %&gt;</SPAN>
<SPAN LANG="da-DK">      &lt;%=login.getMeddelelse()%&gt;</SPAN>
<SPAN LANG="da-DK">      Pr&oslash;v igen.</SPAN>
<SPAN LANG="da-DK">  &lt;%  } else { %&gt;</SPAN>
<SPAN LANG="da-DK">      Indtast brugernavn og adgangskode.</SPAN>
<SPAN LANG="da-DK">      &lt;%</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/font&gt;</SPAN>

<SPAN LANG="da-DK">&lt;a href=&quot;beskyttet_side.jsp&quot;&gt;G&aring; til den beskyttede side&lt;/a&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><H3 CLASS="western">
9.5.4 <a name='afsn9.5.4'></a>Brugeroprettelsen</H3>
<P CLASS="western"><SPAN LANG="da-DK">Hvis der er tale om en ny
bruger vises dette sk&aelig;rmbillede, hvor brugeren kan v&aelig;lge
et brugernavn og angive sin epost-adresse,</SPAN> for at f&aring;
oprettet en bruger.</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_m3472e314.png" NAME="Grafik90" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">For at undg&aring; at alle mulige opretter brugere
i fl&aelig;ng (eller endda laver et program, der g&oslash;r det
automatisk!), skal der ogs&aring; indtastes en sikkerhedskode, der
bliver p&aring; et billede. Til det bruger vi eksemplet fra <a href='kapitel2.jsp#afsn2.8.5'>afsnit 2.8.5</a>,
til at producere et JPG-billede med sikkerhedskode. Teksten p&aring;
billedet bestemmer vi ved at s&aelig;tte <SPAN LANG="da-DK">attributten
&quot;billedtekst&quot; i sessionen.</SPAN></P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>
ny_bruger.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;login&quot; class=&quot;javabog.Login&quot; scope=&quot;session&quot;/&gt;
<SPAN LANG="da-DK">&lt;jsp:setProperty name=&quot;login&quot; property=&quot;brugernavn&quot;/&gt;</SPAN>
<SPAN LANG="da-DK">&lt;jsp:setProperty name=&quot;login&quot; property=&quot;epost&quot;/&gt;</SPAN>

<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Ny bruger&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;Registrering af ny bruger&lt;/h1&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form action=&quot;ny_bruger.jsp&quot; method=&quot;get&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;table&gt;</SPAN>
<SPAN LANG="da-DK">&lt;tr&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&Oslash;nsket brugernavn:&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;brugernavn&quot; value=&quot;&lt;%= login.getBrugernavn() %&gt;&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/tr&gt;</SPAN>
<SPAN LANG="da-DK">&lt;tr&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;Epost:&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;epost&quot; value=&quot;&lt;%= login.getEpost() %&gt;&quot;&gt;&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/tr&gt;</SPAN>
<SPAN LANG="da-DK">&lt;tr&gt;</SPAN>
  &lt;td&gt;Indtast sikkerhedskode&lt;/td&gt;
  &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;sikkerhedskode&quot;&gt;&lt;/td&gt;
<SPAN LANG="da-DK">&lt;/tr&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/table&gt;</SPAN>

<SPAN LANG="da-DK">&lt;% <I>// Ekstra sikkerhedskode som bruger skal afl&aelig;se fra billede</I></SPAN>
<SPAN LANG="da-DK">  String sikkerhedskode = (String) session.getAttribute(&quot;sikkerhedskode&quot;);</SPAN>
<SPAN LANG="da-DK">  if (sikkerhedskode==null) {</SPAN>
<SPAN LANG="da-DK">    sikkerhedskode = &quot;&quot; + (int) (Math.random()*100000);</SPAN>
    <SPAN LANG="da-DK">session.setAttribute(&quot;sikkerhedskode&quot;, sikkerhedskode);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<I>  // Billedet henter sin tekst fra sessionsattribut &quot;billedtekst&quot;, se <a href='kapitel2.jsp#afsn2.8.5'>afsnit 2.8.5</a></I>
<SPAN LANG="da-DK">  session.setAttribute(&quot;billedtekst&quot;, &quot;    Sikkerhedskoden er : &quot;+sikkerhedskode);</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
&lt;img src=&quot;../kapitel_02/billede.jsp&quot;&gt;
<SPAN LANG="da-DK">  &lt;input type=&quot;submit&quot; name=&quot;handling&quot; value=&quot;opret bruger&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;font color=&quot;red&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  String handling = request.getParameter(&quot;handling&quot;);</SPAN>
<SPAN LANG="da-DK">  if (&quot;opret bruger&quot;.equals(handling)) {</SPAN>
<SPAN LANG="da-DK">    if (!sikkerhedskode.equals(request.getParameter(&quot;sikkerhedskode&quot;)))</SPAN> {
<SPAN LANG="da-DK">      %&gt;Du har tastet en forkert sikkerhedskode. &lt;% </SPAN>
<SPAN LANG="da-DK">    </SPAN>} else <SPAN LANG="da-DK">  if (login.opretBruger()) { </SPAN>
<SPAN LANG="da-DK">      %&gt;&lt;jsp:forward page=&quot;log_ind.jsp&quot; /&gt;&lt;% </SPAN>
<SPAN LANG="da-DK">    } else { </SPAN>
<SPAN LANG="da-DK">      %&gt;Bruger kunne ikke oprettes. Pr&oslash;v med et andet brugernavn og tjek epost</SPAN>.<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%= login.getMeddelelse() %&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/font&gt;</SPAN>

<SPAN LANG="da-DK">&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">&lt;a href=&quot;log_ind.jsp&quot;&gt;G&aring; til login&lt;/a&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE>
<H3 CLASS="western">9.5.5 <a name='afsn9.5.5'></a><SPAN LANG="da-DK">En beskyttet side</SPAN></H3>
<P CLASS="western">Den beskyttede side tjekker om der er logget
korrekt ind:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>beskyttet_side.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;login&quot; class=&quot;javabog.Login&quot; scope=&quot;session&quot;/&gt;

<SPAN LANG="da-DK"><I>&lt;%-- klient-omdirigering med JSP --%&gt;</I></SPAN>
<SPAN LANG="da-DK">&lt;% if (!login.isLoggetInd()) response.sendRedirect(&quot;log_ind.jsp&quot;); %&gt;</SPAN>


<SPAN LANG="da-DK"><I>&lt;%-- server-omdirigering med JSP</I></SPAN>
<SPAN LANG="da-DK"><I>&lt;% if (!login.isLoggetInd()) { %&gt;&lt;jsp:forward page=&quot;log_ind.jsp&quot;/&gt;&lt;% } %&gt;</I></SPAN>
<SPAN LANG="da-DK"><I>--%&gt;</I></SPAN>

<SPAN LANG="da-DK"><I>&lt;%-- server-omdirigering med JSTL </I></SPAN>
<SPAN LANG="da-DK"><I>&lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&gt;</I></SPAN>
<SPAN LANG="da-DK"><I>&lt;c:if test=&quot;${!login.loggetInd}&quot;&gt;&lt;jsp:forward page=&quot;log_ind.jsp&quot; /&gt;&lt;/c:if&gt;</I></SPAN>
<SPAN LANG="da-DK"><I>--%&gt;</I></SPAN>

<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Beskyttet side&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body bgcolor=&quot;#ffffff&quot;&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;Den beskyttede side&lt;/h1&gt;</SPAN>
<SPAN LANG="da-DK">Denne tekst kan du kun se, hvis du er logget korrekt p&aring;.</SPAN>

<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western">
<SPAN LANG="da-DK">Bem&aelig;rk at det kunne v&aelig;re en god id&eacute;
at l&aelig;gge login-tjekket i et kodefragment, som beskrevet i
<a href='kapitel4.jsp#afsn4.2.1'>afsnit 4.2.1</a>. I eksemplet er brugt klient-omdirigering (kommenteret
bort findes en server-omdirigering - se <a href='kapitel4.jsp#afsn4.3'>afsnit 4.3</a>).</SPAN></P>

<H3 CLASS="western">9.5.6 <a name='afsn9.5.6'></a>F&oslash;r eksemplet kan k&oslash;re p&aring;
din egen server</H3>
<P CLASS="western">Eksemplet bruger klasser fra pakken javax.mail til
at sende adgangskoden til brugeren samt MySQL-klasser til at
kommunikere med en database.</P>
<P CLASS="western">Disse klasser findes ikke som standard i Tomcat,
men de kan nemt installeres, ved at kopiere nogle JAR-filer ind i din
webapplikations WEB-INF/lib/ eller Tomcats common/lib/.</P>
<P CLASS="western"><SPAN LANG="da-DK">For at bruge javax.mail, skal
du kopiere filerne mail.jar og activation.jar derind. S&oslash;g
efter filerne p&aring; din computer, de er nemlig sandsynligvis
allerede inkluderet i dit udviklingsv&aelig;rkt&oslash;j. Ellers hent
dem fra </SPAN><A CLASS="western" HREF="http://java.sun.com/products/javamail"><SPAN LANG="da-DK">http://java.sun.com/products/javamail</SPAN></A><SPAN LANG="da-DK">
(bem&aelig;rk at du ogs&aring; skal hente activation.jar fra
</SPAN><A CLASS="western" HREF="http://java.sun.com/products/javabeans/glasgow/jaf.html"><SPAN LANG="da-DK">http://java.sun.com/products/javabeans/glasgow/jaf.html</SPAN></A><SPAN LANG="da-DK">).</SPAN></P>
<P CLASS="western"><SPAN LANG="da-DK">Hvordan du f&aring;r fat i
databasedriverklasserne er beskrevet i f.eks. <a href='kapitel5.jsp#afsn5.3.2'>afsnit 5.3.2</a>, Kontakt til MySQL-database.
Kopi&eacute;r ogs&aring; denne JAR-fil ind.</SPAN></P>
<P CLASS="western">Se <a href='kapitel4.jsp#afsn4.9.6'>afsnit 4.9.6</a>, Hvis klasse(bibliotek)er ikke kan findes,
hvis du har problemer med at f&aring; webserveren til at finde
JAR-filerne.</P>


<H3 CLASS="western">9.5.7 <a name='afsn9.5.7'></a>Opgaver</H3>
<OL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Afpr&oslash;v eksemplet,
  f&oslash;rst ved at se det p&aring;:
  </SPAN><A CLASS="western" HREF="http://javabog.dk:8080/JSP/kode/"><SPAN LANG="da-DK">http://javabog.dk:8080/JSP/kode/</SPAN></A><SPAN LANG="da-DK">,
  dern&aelig;st  i din egen webserver (du skal m&aring;ske rette i
  databasedriverklassen og database-URLen).Husk at du skal bruge en
  r&aelig;kke ekstra klasser (se <a href='kapitel9.jsp#afsn9.5.6'>afsnit 9.5.6</a>).</SPAN></P>
  <LI><P CLASS="western">Som koden foreligger, kan enhver registrere
  sig og logge ind. Du skal derfor &aelig;ndre (begr&aelig;nse)
  systemet, s&aring;dan at brugere ikke selv kan registrere sig, men
  skal v&aelig;re oprettet i forvejen.</P>
  <LI><P CLASS="western">Du skal &aelig;ndre kalender-eksemplet, s&aring;dan
  at brugerne af kalenderen skal v&aelig;re logget ind med brugernavn
  og adgangskode f&oslash;r de kan f&aring; adgang til kalenderen.</P>
  <LI><P CLASS="western">Pr&oslash;v at skrive login-eksemplet om,
  s&aring;dan at brugere godt nok kan registrere sig, men ikke f&aring;r
  adgang til de beskyttede sider, f&oslash;r de er blevet godkendt af
  en administrator.</P>
</OL>


<H2 CLASS="western">9.6 <a name='afsn9.6'></a>Test dig selv</SPAN></H2>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_JSP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/JSP/kapitel9.jsp#afsn9.6">
  <input type='checkbox' name='vis' value='9.6'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.6'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H2 CLASS="western">9.7 <a name='afsn9.7'></a>Resum&eacute;</SPAN></H2>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_JSP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/JSP/kapitel9.jsp#afsn9.7">
  <input type='checkbox' name='vis' value='9.7'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.7'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <DIV ID="sdfootnote1">
  <P CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote1sym" HREF="#sdfootnote1anc">1</A>Hvis
  en klasse skal kunne bruges andre steder fra (f.eks. fra en
  JSP-side) skal den kunne importeres. Det kan klasser uden pakkenavn
  ikke fra og med JDK 1.4.</P>
</DIV>
<DIV ID="sdfootnote2">
  <P CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote2sym" HREF="#sdfootnote2anc">2</A><SPAN LANG="da-DK">Bruger
  du MySQL og f&aring;r fejlen 'Server configuration denies access to
  data source', s&aring; kig p&aring;
  </SPAN><A CLASS="western" HREF="http://dev.mysql.com/doc/connector/j/en/cj-troubleshooting.html"><SPAN LANG="da-DK">http://dev.mysql.com/doc/connector/j/en/cj-troubleshooting.html</SPAN></A>
  for enl&oslash;sning<SPAN LANG="da-DK">.</SPAN></P>
</DIV>

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel8.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel10.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_JSP.html'>om bogen</a>
<hr>
<font size=-2>http://javabog.dk/ - <b>Webprogrammering med Java Server Pages</b> af Jacob Nordfalk.
<br>
  Licens og kopiering under <a href='http://www.linuxbog.dk/licens.html'>&Aring;ben Dokumentlicens</a> (&Aring;DL)
  hvor intet andet er nævnt (72% af værket).
</font>
<br>
Ø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.
<!-- netlæser: Wget/1.10, autoHent: true  -->
     

</body>
</html>
