



<html>
<head>
  <title>javabog.dk - Webprogrammering med Java Server Pages - Arkitekturer i webprogrammering</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='kapitel9.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel11.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="">10 <a name='afsn10'></a>Arkitekturer
i webprogrammering</H1>
<DIV ID="Indholdsfortegnelse11">
  <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>10.1
  Trelagsmodellen  192</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>10.2
  Model 1 og model 2-arkitekturer  192</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">10.2.1
  Model 1-arkitektur: Logik sammen med HTML  192</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">10.2.2
  Model 2-arkitektur: Logik adskilt fra HTML  192</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>10.3
  Model-View-Controller-arkitekturen  193</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">10.3.1
  Modellen  193</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">10.3.2
  Pr&aelig;sentationen  194</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">10.3.3
  Kontroll&oslash;ren  194</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">10.3.4
  Informationsstr&oslash;m gennem MVC  194</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>10.4
  Eksempel p&aring; MVC: Bankkonti  196</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">10.4.1
  Model (Bankmodel.java og Kontomodel.java)  196</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">10.4.2
  Javab&oslash;nnen (Brugervalg.java)  197</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">10.4.3
  Pr&aelig;sentationen (JSP-siderne)  199</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">10.4.4
  Kontroll&oslash;ren (kontrol.jsp)  202</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">10.4.5
  Fejlh&aring;ndtering (fejl.jsp)  204</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">10.4.6
  Hvordan pr&aelig;sentation henviser til kontroll&oslash;r  205</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>10.5
  Designm&oslash;nster: Frontkontrol  205</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">10.5.1
  Variationer (til st&oslash;rre applikationer)  205</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">10.5.2
  Implementering af en Frontkontrol  206</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">10.5.3
  Eksempel p&aring; en Frontkontrol  206</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>10.6
  Test dig selv  208</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>10.7
  Resum&eacute;  208</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>10.8
  Rammer for webarkitekturer  209</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">10.8.1
  Jakarta Struts  209</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">10.8.2
  JSF - Java Server Faces  209</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>10.9
  Mere l&aelig;sning  210</B></FONT></FONT></P>
</DIV>



<P CLASS="kapiteloversigt-western"><SPAN STYLE="font-weight: medium"><SPAN STYLE="text-decoration: none">Dette
kapitel er frivillig l&aelig;sning; det </SPAN></SPAN>foruds&aelig;ttes
ikke i resten af bogen. Det foruds&aelig;tter <a href='kapitel5.jsp'>kapitel 5</a>,  Brug af databaser,
og <a href='kapitel9.jsp'>kapitel 9</a>, Javab&oslash;nner i JSP-sider.</P>
<P CLASS="western" STYLE="">Efterh&aring;nden
som en webapplikation vokser sig st&oslash;rre og st&oslash;rre,
bliver den sv&aelig;rere at overskue. Det bliver sv&aelig;rt at finde
rundt i de mange linjers kode i de mange filer og fejlfinding og
videreudvikling bliver mere og mere tidskr&aelig;vende.</P>
<P CLASS="western"><SPAN LANG="da-DK">Der opst&aring;r et behov for
et system, der opdeler applikationens dele i nogle bidder, der hver i
s&aelig;r har et klart ansvar og som er nogenl</SPAN>unde afgr&aelig;nset
fra de andre dele af applikationen.</P>
<H2 CLASS="western">10.1 <a name='afsn10.1'></a>Trelagsmodellen</SPAN></H2>
<P CLASS="western">Et hyppigt brugt system til inddeling er <SPAN LANG="da-DK">at
<I>lagdele</I> applikationen, oftest i tre lag:</SPAN></P>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">&Oslash;verste lag er
  JSP-siderne med HTML-koden og pr&aelig;sentationslogik. </SPAN>
  </P>
  <LI><P CLASS="western">Mellemste lag er klasser, der tager sig af
  forretningslogikken i applikationen.</P>
  <LI><P CLASS="western">Nederste lag er databasen.</P>
</UL>
<P CLASS="western"><SPAN LANG="da-DK">Denne - n&aelig;rmest klassiske
- opdeling er meget popul&aelig;r og kaldes <I>trelagsmodellen</I>.</SPAN>
JSP-siderne har ikke nogen databasekode selv, men kalder metoder i
forretningslogik-klasser, som s&aring; fremfinder og &aelig;ndrer p&aring;
de relevante data i databasen. <SPAN LANG="da-DK">Brugerinteraktions-kode
(behandle parametre fra request-objektet og beslutning om, hvilken
side brugeren skal se n&aelig;ste gang) ligger som regel i &oslash;verste
lag.</SPAN></P>
<P CLASS="western"><SPAN LANG="da-DK">Trelagsmodellen</SPAN> er en
god l&oslash;sning i mange sammenh&aelig;nge, men i en webapplikation
kan &oslash;verste lag (JSP-siderne) vokse sig endog meget stort og
en yderligere opdeling derfor blive n&oslash;dvendig. 
</P>
<P CLASS="western">Model-View-Controller-arkitekturen er et meget
popul&aelig;rt bud p&aring; hvordan trelagsmodellen yderligere kan
inddeles. En stor del af kapitlet handler derfor om denne arkitektur.</P>
<H2 CLASS="western">10.2 <a name='afsn10.2'></a>Model 1 og model 2-arkitekturer</SPAN></H2>
<P CLASS="western">Inden for webprogrammering taler man ikke om
trelagsmodellen men om model 1 og model 2-arkitekturer.</P>
<H3 CLASS="western">10.2.1 <a name='afsn10.2.1'></a>Model 1-arkitektur: Logik sammen med HTML</H3>
<P CLASS="western"><SPAN LANG="da-DK">I webprogrammeringens sp&aelig;de
barndom lavede de fleste mindre applikationer, hvor programlogikken
l&aring; sammen med HTML-koden. Et eksempel p&aring; denne m&aring;de
at programmere kan findes i <a href='kapitel5.jsp#afsn5.5'>afsnit 5.5</a> (Eksempel - g&aelig;stebog).</SPAN></P>
<P CLASS="western">Har man en webapplikation hvor programlogikken
ligger sammen med HTML-koden kaldes det en model 1-arkitektur. Denne
arkitektur har f&oslash;lgende konsekvenser:</P>
<UL>
  <LI><P CLASS="western">Simpel struktur</P>
  <LI><P CLASS="western">Nem at starte med</P>
  <LI><P CLASS="western">Velegnet til sm&aring; projekter</P>
  <LI><P CLASS="western">Sv&aelig;rt at adskille programlogik og HTML</P>
  <LI><P CLASS="western">Samme person er programm&oslash;r og
  HTML-designer</P>
  <LI><P CLASS="western">Decentral - hver side behandler data fra sin
  egen formular</P>
  <LI><P CLASS="western">Potentiel redundans (samme programlogik flere
  steder)</P>
</UL>
<H3 CLASS="western">10.2.2 <a name='afsn10.2.2'></a>Model 2-arkitektur: Logik adskilt fra HTML</H3>
<P CLASS="western">Efterh&aring;nden som webprogrammerne blev st&oslash;rre
og st&oslash;rre og kr&aelig;vede mere og mere vedligeholdelse, blev
f&oslash;lgende anbefaling mere og mere relevant:</P>
<BLOCKQUOTE CLASS="definition-western">Adskil tekstligt indhold og
programkode fra hinanden, s&aring;dan at f.eks. en HTML-designer kan
koncentrere sig om HTML-layout og indhold, mens en programm&oslash;r
kan koncentrere sig om funktionalitet og den bagvedliggende kode, som
behandler data og afg&oslash;r, hvilken side der skal vises</BLOCKQUOTE>
<P CLASS="western">Dette kaldes en model 2-arkitektur. Denne
arkitektur har f&oslash;lgende konsekvenser:</P>
<UL>
  <LI><P CLASS="western">Mere omfattende struktur</P>
</UL>
<UL>
  <LI><P CLASS="western">Sv&aelig;rere at starte med</P>
</UL>
<UL>
  <LI><P CLASS="western">Lettere at vedligeholde ved st&oslash;rre
  projekter</P>
  <LI><P CLASS="western">Programlogik og HTML relativt adskilt</P>
</UL>
<UL>
  <LI><P CLASS="western">Forskellige personer kan tage sig af
  programmering og HTML-design</P>
</UL>
<UL>
  <LI><P CLASS="western">Centraliseret: Programlogik og beslutning om,
  hvilken side, der skal vises sker &eacute;t sted</P>
</UL>
<P CLASS="western"><SPAN LANG="da-DK">En udbygning af tankegangen om
at adskille tekstligt indhold og programkode er ogs&aring;, at
adskille sprogligt indhold fra HTML-design, f.eks. for at kunne lade
webapplikationen kunne k&oslash;re p&aring; flere sprog
(internationalisering). Dette behandles i <a href='kapitel13.jsp'>kapitel 13</a>, Internationale sider.</SPAN></P>
<P CLASS="western">Model 2-arkitekturen kaldes ogs&aring;
Model-View-Controller-arkitekturen. I n&aelig;ste afsnit vil vi g&aring;
i dybden med delene i teorien og i det efterf&oslash;lgende afsnit
give et konkret eksempel.</P>
<H2 CLASS="western">10.3 <a name='afsn10.3'></a>Model-View-Controller-arkitekturen</SPAN></H2>
<P CLASS="western">Model-View-Controller-arkitekturen (forkortet MVC)
er et designm&oslash;nster beregnet til programmer med en
brugergr&aelig;nseflade. Den anbefaler, at man opdeler ens
applikation (i hvert fald mentalt) i tre dele: En model, en
pr&aelig;sentation og en kontroll&oslash;r:<BR><IMG SRC="bog11_html_1872a7c9.gif" NAME="Object4"></P>
<P CLASS="western">Model-View-Controller-arkitekturen og det meste af
ovenst&aring;ende diagram er ikke specielt rettet mod
webapplikationer, men g&aelig;lder for alle slags programmer. P&aring;
ovenst&aring;ende diagram er forklaringer, der er specielt rettet mod
webapplikationer, skrevet i kursiv.</P>
<P CLASS="western">Lad os nu kigge n&aelig;rmere p&aring; de tre dele
af Model-View-Controller-arkitekturen.</P>
<H3 CLASS="western">10.3.1 <a name='afsn10.3.1'></a>Modellen</H3>
<BLOCKQUOTE CLASS="definition-western">Modellen <I>indeholder data og
registrerer, hvilken tilstand den p&aring;g&aelig;ldende del af
programmet er i</I> 
</BLOCKQUOTE>
<P CLASS="western">Oftest er data indkapslet i nogle klasser, s&aring;dan
at konsistens sikres. I s&aring; fald er der kun adgang til at sp&oslash;rge
og &aelig;ndre p&aring; data gennem metodekald.</P>
<P CLASS="western">Modellen b&oslash;r v&aelig;re uafh&aelig;ngig af,
hvordan data pr&aelig;senteres over for brugeren og er der flere
programmer, der arbejder med de samme slags data, kan de i princippet
have den samme datamodel, selvom de i &oslash;vrigt er helt
forskellige.</P>
<P CLASS="western">Eksempel: En bankkonto har navn p&aring; ejer,
kontonummer, kort-ID, saldo, bev&aelig;gelser, renteoplysninger
e.t.c.. Saldoen kan ikke &aelig;ndres direkte, men med handlingerne
overf&oslash;rsel, udbetaling og indbetaling kan saldoen p&aring;virkes
(se eksempelvis klassen Kontomodel i <a href='kapitel10.jsp#afsn10.4.1'>afsnit 10.4.1</a>).</P>
<P CLASS="western">Bem&aelig;rk hvordan modellen for en bankkonto er
universel. Modellen kunne anvendes f.eks. b&aring;de i et program til
en Dankort-automat, et hjemmebank-system og i programmet som
kassedamen anvender ved skranken. 
</P>
<P CLASS="western">Den samme model kunne anvendes b&aring;de af en
webapplikation og et almindeligt program. 
</P>
<H3 CLASS="western">10.3.2 <a name='afsn10.3.2'></a>Pr&aelig;sentationen</H3>
<BLOCKQUOTE CLASS="definition-western">Pr&aelig;sentationen (eng.:
View) <I>henter relevante data fra modellen og viser dem for brugeren
i en passende form</I></BLOCKQUOTE>
<P CLASS="western">Selvom to pr&aelig;sentationer deler model (viser
data fra samme model) kan de v&aelig;re meget forskellige, da de er
beregnet p&aring; en bestemt brugergr&aelig;nseflade.</P>
<P CLASS="western">Eksempel: Bankkontoen pr&aelig;senteres meget
forskelligt. I en Dankort-automat vises ingen personlige oplysninger
overhovedet. I et hjemmebank-system kan saldo og bev&aelig;gelser
ses. Ved skranken kan medarbejderen se endnu mere, f.eks. filial og
kontaktperson i banken (det kunne v&aelig;re implementeret som en
grafisk applikation, der k&oslash;rer hos brugeren).</P>
<P CLASS="western">I en webapplikation producerer pr&aelig;sentationen
HTML-koden, som brugeren ser. Oftest er pr&aelig;sentationen
implementeret som nogle JSP-sider (nogle kan dog foretr&aelig;kke
servletter).</P>
<H3 CLASS="western">10.3.3 <a name='afsn10.3.3'></a>Kontroll&oslash;ren</H3>
<BLOCKQUOTE CLASS="definition-western">Kontroll&oslash;ren (eng.:
Controller) definerer hvad programmet kan. Den <I>oms&aelig;tter
brugerens indtastninger til handlinger, der skal udf&oslash;res p&aring;
modellen</I></BLOCKQUOTE>
<P CLASS="western">Eksempel: I Dankort-automaten kan man kun h&aelig;ve
penge. I et hjemmebank-system kan brugeren m&aring;ske lave visse
former for overf&oslash;rsel fra sin egen konto. Ved skranken kan
medarbejderen derudover foretage ind- og udbetalinger.</P>
<P CLASS="western">I en webapplikation er kontroll&oslash;ren den,
der modtager alle parametre fra formularer fra klienten og derefter
beslutter, hvad der skal ske. Oftest er pr&aelig;sentationen
implementeret som en eller flere servletter (nogle kan dog foretr&aelig;kke
at bruge JSP-sider).</P>
<H3 CLASS="western">10.3.4 <a name='afsn10.3.4'></a>Informationsstr&oslash;m gennem MVC</H3>
<P CLASS="western">Figuren herunder illustrerer hvordan str&oslash;mmen
af information g&aring;r fra modellen, via pr&aelig;sentationen til
brugeren (symboliseret ved et &oslash;je). 
</P>

<P CLASS="western" ALIGN=CENTER><IMG SRC="bog11_html_m4d89c2bb.gif" NAME="Object3" ALIGN=MIDDLE></P>
<P CLASS="western">Brugeren foretager nogle handlinger (symboliseret
ved musen), som via kontroll&oslash;ren fortolkes som nogle
&aelig;ndringer, der foretages p&aring; modellen, hvorefter de nye
data vises for brugeren.</P>
<P CLASS="western">I praksis foreg&aring;r det i en webapplikation
ved, at brugeren udfylder en formular, som sendes til serveren, hvor
de modtages af kontroll&oslash;ren. Kontroll&oslash;ren fortolker
parametrene og beslutter, hvad det er brugeren vil g&oslash;re og
kalder de tilsvarende metoder p&aring; modellen. Til sidst
omdirigerer kontroll&oslash;ren til en pr&aelig;sentations-side med
HTML-koden brugeren skal se.</P>

<H2 CLASS="western" STYLE="">10.4 <a name='afsn10.4'></a>Eksempel p&aring;
MVC: Bankkonti</SPAN></H2>
<P CLASS="western">Det f&oslash;lgende er et eksempel p&aring;
hvordan en MVC-arkitektur kunne implementeres.</P>
<P CLASS="western">Det best&aring;r af <SPAN LANG="da-DK">f&oslash;lgende
JSP-sider og klasser:</SPAN></P>
<P CLASS="western"><IMG SRC="bog11_html_1f67c4d7.gif" NAME="Objekt1"></P>
<P CLASS="western">Pilene viser hvilke sider/klasser, der kender til
andre sider/klasser. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Kontroll&oslash;ren er her
lavet som JSP-siden kontrol.jsp. Den</SPAN> modtager alle
foresp&oslash;rgsler, &aelig;ndrer i objekterne og omdirigerer til en
af de andre sider. De andre JSP-sider pr&aelig;senterer data, som de
afl&aelig;ser fra objekterne og kender ikke til kontroll&oslash;ren. 
</P>
<P CLASS="western">Modellen best&aring;r af
forretningslogikobjekterne Bankmodel og Kontomodel. Hertil kommer
Javab&oslash;nnerne Login og Brugervalg, som husker og behandler data
n&aelig;rmere pr&aelig;sentationslaget<A CLASS="sdfootnoteanc" NAME="sdfootnote1anc" HREF="#sdfootnote1sym"><SUP>1</SUP></A>.
<SPAN LANG="da-DK">Der findes &eacute;t Brugervalg- og Login-objekt
per bruger (knyttet til brugerens session).</SPAN></P>
<P CLASS="western">I det f&oslash;lgende gennemg&aring;s koden i
r&aelig;kkef&oslash;lgen Model, Pr&aelig;sentation (d.v.s. de
JSP-sider der producerer HTML) og til sidst kontroll&oslash;ren. 
</P>
<H3 CLASS="western">10.4.1 <a name='afsn10.4.1'></a>Model (Bankmodel.java og Kontomodel.java)</H3>
<P CLASS="western">Vi har brug for en liste over samtlige konti i
banken. Denne klasse kaldes Bankmodel:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Bankmodel.java</I></FONT></P>
<PRE CLASS="kode-western">package bank;

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

<SPAN LANG="da-DK">public class Bankmodel</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  public List konti = new ArrayList();</SPAN>

<SPAN LANG="da-DK">  public Bankmodel()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    konti.add(new Kontomodel(&quot;Jacob&quot;,  1001, 113.75));</SPAN>
<SPAN LANG="da-DK">    konti.add(new Kontomodel(&quot;Jacob&quot;,  1002, 555.00));</SPAN>
<SPAN LANG="da-DK">    konti.add(new Kontomodel(&quot;Preben&quot;, 1101,   8.50));</SPAN>
<SPAN LANG="da-DK">    konti.add(new Kontomodel(&quot;S&oslash;ren&quot;,  1201,  78.25));</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
Bankmodellen burde selvf&oslash;lgelig, i et mere realistisk
eksempel, have sine data i en database, men for letheds skyld
opretter den her blot en fast liste over konti.</P>

<P CLASS="western">Hver konto er repr&aelig;senteret af et
Kontomodel-objekt, med ejer, id (kontonummer), saldo og en liste over
de bev&aelig;gelser, der har v&aelig;ret p&aring; kontoen.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Kontomodel.java</I></FONT></P>
<PRE CLASS="kode-western">package bank;

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

<SPAN LANG="da-DK">public class Kontomodel</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private String ejer;</SPAN>
<SPAN LANG="da-DK">  private int id;</SPAN>
<SPAN LANG="da-DK">  private double saldo;</SPAN>
<SPAN LANG="da-DK">  private List bev&aelig;gelser = new ArrayList();</SPAN>

<SPAN LANG="da-DK">  public Kontomodel(String ejer1, int id1) { ejer = ejer1; id = id1; }</SPAN>
<SPAN LANG="da-DK">  public Kontomodel(String ejer1, int id1, double saldo1) </SPAN>
<SPAN LANG="da-DK">    { ejer = ejer1; id = id1; saldo = saldo1; }</SPAN>

<SPAN LANG="da-DK">  public String getEjer()     { return ejer; }</SPAN>
<SPAN LANG="da-DK">  public int getId()          { return id; }</SPAN>
<SPAN LANG="da-DK">  public double getSaldo()    { return saldo; }</SPAN>
<SPAN LANG="da-DK">  public List getBev&aelig;gelser() { return bev&aelig;gelser; }</SPAN>

<SPAN LANG="da-DK">  public String toString()    { return ejer + &quot;: &quot;+saldo+&quot; kr&quot;; }</SPAN>

<SPAN LANG="da-DK">  public void overf&oslash;r(Kontomodel til, double bel&oslash;b)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (bel&oslash;b&lt;=0) throw new IllegalArgumentException(&quot;Bel&oslash;b skal v&aelig;re positivt&quot;);</SPAN>
<SPAN LANG="da-DK">    if (bel&oslash;b&gt;saldo) throw new IllegalArgumentException(&quot;Der er ikke penge nok&quot;);</SPAN>
<SPAN LANG="da-DK">    saldo = saldo - bel&oslash;b;</SPAN>
<SPAN LANG="da-DK">    til.saldo = til.saldo + bel&oslash;b;<I>// privat variabel kan &aelig;ndres i samme klasse</I></SPAN>

<SPAN LANG="da-DK">    String &aelig;ndring = &quot;Overf&oslash;rt &quot;+bel&oslash;b+&quot; fra &quot;+ejer+&quot; til &quot;+til.ejer;</SPAN>
<SPAN LANG="da-DK">    bev&aelig;gelser.add(&aelig;ndring);</SPAN>
<SPAN LANG="da-DK">    til.bev&aelig;gelser.add(&aelig;ndring);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void h&aelig;v(double bel&oslash;b)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (bel&oslash;b&lt;=0) throw new IllegalArgumentException(&quot;Bel&oslash;b skal v&aelig;re positivt&quot;);</SPAN>
<SPAN LANG="da-DK">    if (bel&oslash;b&gt;saldo) throw new IllegalArgumentException(&quot;Der er ikke penge nok&quot;);</SPAN>
<SPAN LANG="da-DK">    saldo = saldo - bel&oslash;b;</SPAN>
<SPAN LANG="da-DK">    bev&aelig;gelser.add(&quot;H&aelig;vet &quot;+bel&oslash;b);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void inds&aelig;t(double bel&oslash;b)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    if (bel&oslash;b&lt;=0) throw new IllegalArgumentException(&quot;Bel&oslash;b skal v&aelig;re positivt&quot;);</SPAN>
<SPAN LANG="da-DK">    saldo = saldo + bel&oslash;b;</SPAN>
<SPAN LANG="da-DK">    bev&aelig;gelser.add(&quot;Indsat &quot;+bel&oslash;b);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
Bem&aelig;rk hvordan klassen kun koncentrerer sig om
forretningslogik. 
</P>
<P CLASS="western">Opst&aring;r der en fejlsituation i en metode,
kastes en undtagelse, der beskriver fejlen, s&aring;dan at kalderen
kan h&aring;ndtere den (se hvordan senere, i <a href='kapitel10.jsp#afsn10.4.5'>afsnit 10.4.5</a>, Fejlh&aring;ndtering).</P>

<H3 CLASS="western">10.4.2 <a name='afsn10.4.2'></a>Javab&oslash;nnen (Brugervalg.java)</H3>
<P CLASS="western">Her er Brugervalg-klassen. 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>Brugervalg.java</I></FONT></P>
<PRE CLASS="kode-western">package bank;
<SPAN LANG="da-DK">import java.util.*;</SPAN>
<SPAN LANG="da-DK">public class Brugervalg</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  <I>/** Egenskab 'bankmodel' s&aelig;ttes fra JSP-siden kontrol.jsp n&aring;r b&oslash;nnen oprettes */</I></SPAN>
<SPAN LANG="da-DK">  Bankmodel bank;</SPAN>
<SPAN LANG="da-DK">  public void <B>setBankmodel(Bankmodel b)</B> { bank = b; }</SPAN>

<SPAN LANG="da-DK">  <I>/** Liste over denne brugers konti */</I></SPAN>
<SPAN LANG="da-DK">  public ArrayList konti;</SPAN>

<SPAN LANG="da-DK">  <I>/** Den konto, brugeren har valgt at arbejde med lige nu */</I></SPAN>
<SPAN LANG="da-DK">  public Kontomodel konto;</SPAN>

<SPAN LANG="da-DK">  <I>/** Egenskab 'kontovalg' s&aelig;ttes fra JSP-side vaelg_konto.jsp*/</I></SPAN>
<SPAN LANG="da-DK">  public void <B>setKontovalg(int nr)</B> {</SPAN>
<SPAN LANG="da-DK">    konto = null;</SPAN>
<SPAN LANG="da-DK">    for (int i=0; i&lt;konti.size(); i++) {</SPAN>
<SPAN LANG="da-DK">      Kontomodel k = (Kontomodel) konti.get(i);</SPAN>
<SPAN LANG="da-DK">      if (k.getId() == nr) konto = k;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    if (konto==null)</SPAN> <SPAN LANG="da-DK">throw new IllegalArgumentException(&quot;Ukendt Konto-ID: &quot;+nr);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <I>/** Streng der beskriver en handling brugeren &oslash;nsker at udf&oslash;re */</I></SPAN>
<SPAN LANG="da-DK">  public String handling;</SPAN>
<SPAN LANG="da-DK">  public void <B>setHandling(String h)</B> { handling = h; }</SPAN>

<SPAN LANG="da-DK">  <I>/** Bel&oslash;bet handlingen (h&aelig;v/s&aelig;t ind/overf&oslash;r) drejer sig om */</I></SPAN>
<SPAN LANG="da-DK">  double handlBel&oslash;b;</SPAN>
<SPAN LANG="da-DK">  public void <B>setBeloeb(double b)</B> { handlBel&oslash;b = b; }</SPAN>

<SPAN LANG="da-DK">  <I>/** Hvis der skal foretages en overf&oslash;rsel, hvilken konto er det til */</I></SPAN>
<SPAN LANG="da-DK">  Kontomodel ovfTil;</SPAN>

<SPAN LANG="da-DK">  <I>/** Egenskab 'tilKontoId' s&aelig;ttes fra JSP-siden vis_konto.jsp */</I></SPAN>
<SPAN LANG="da-DK">  public void <B>setTilKontoId(int nr)</B> {</SPAN>
<SPAN LANG="da-DK">    ovfTil = null;</SPAN>
<SPAN LANG="da-DK">    for (int i=0; i&lt;bank.konti.size(); i++) {</SPAN>
<SPAN LANG="da-DK">      Kontomodel k = (Kontomodel) bank.konti.get(i);</SPAN>
<SPAN LANG="da-DK">      if (k.getId() == nr) ovfTil = k;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    if (ovfTil==null) throw new IllegalArgumentException(&quot;Ukendt Konto-ID: &quot;+nr);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void udf&oslash;rHandling()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    try {</SPAN>
<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">  </SPAN>    if (handling.equals(&quot;haev&quot;))          konto.h&aelig;v(handlBel&oslash;b);</SPAN>
<SPAN LANG="da-DK">      else if (handling.equals(&quot;saet_ind&quot;)) konto.inds&aelig;t(handlBel&oslash;b);</SPAN>
<SPAN LANG="da-DK">      else if (handling.equals(&quot;overfoer&quot;)) konto.overf&oslash;r(ovfTil, handlBel&oslash;b);</SPAN>
<SPAN LANG="da-DK">      else System.out.println(&quot;Ukendt handling: &quot;+handling);</SPAN>
<SPAN LANG="da-DK">    } finally {</SPAN>
<SPAN LANG="da-DK">      handling = null; <I>// selv hvis noget gik helt galt skal data nulstilles</I></SPAN>
<SPAN LANG="da-DK">      handlBel&oslash;b = 0;</SPAN>
<SPAN LANG="da-DK">      ovfTil = null;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
<SPAN LANG="da-DK">En udskrift af Login-b&oslash;nnen kan ses i
<a href='kapitel9.jsp#afsn9.5.2'>afsnit 9.5.2</a>.</SPAN></P>
<H3 CLASS="western">10.4.3 <a name='afsn10.4.3'></a>Pr&aelig;sentationen (JSP-siderne)</H3>
<P CLASS="western">F&oslash;rst log_ind.jsp, hvor brugeren kan logge
ind. Den genbruger Login-b&oslash;nnen fra <a href='kapitel9.jsp#afsn9.5'>afsnit 9.5</a>:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>log_ind.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;*&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;h1&gt;Log ind&lt;/h1&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form&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 name=&quot;brugernavn&quot; type=&quot;text&quot;</SPAN>
<SPAN LANG="da-DK">             value='&lt;jsp:getProperty name=&quot;login&quot; property=&quot;brugernavn&quot;/&gt;'&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;tr&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;/td&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;td&gt;&lt;input type=&quot;submit&quot; name=&quot;handling&quot; value=&quot;log ind&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;/form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;p&gt;&lt;font color=&quot;red&quot;&gt;&lt;%= login.getMeddelelse() %&gt;&lt;/font&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Vink: Brugere 'Jacob', 'Preben' og 'S&oslash;ren' har adgangskoden 'hemli'.&lt;/p&gt;</SPAN>

<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><P CLASS="western" ALIGN=CENTER>
<FONT SIZE=1 STYLE="font-size: 5pt"><BR><IMG SRC="bog11_html_m7dbb80c8.png" NAME="Grafik91" ALIGN=BOTTOM BORDER=0></FONT></P>
<P CLASS="western" STYLE="">N&aring;r
brugeren f&oslash;rst er logget ind skal han, hvis han har flere
konti, v&aelig;lge hvilken konto han vil arbejde med. Det sker i
vaelg_konto.jsp:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>vaelg_konto.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;valg&quot; class=&quot;bank.Brugervalg&quot; scope=&quot;session&quot; /&gt;
<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;V&aelig;lg konto&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;h1&gt;V&aelig;lg hvilken konto du vil bruge&lt;/h1&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  for (int i=0; i&lt;valg.konti.size(); i++) {</SPAN>
<SPAN LANG="da-DK">    bank.Kontomodel k = (bank.Kontomodel) valg.konti.get(i);</SPAN>
<SPAN LANG="da-DK">    %&gt;</SPAN>
<SPAN LANG="da-DK">      &lt;input type=&quot;radio&quot; name=&quot;kontovalg&quot; value=&quot;&lt;%= k.getId() %&gt;&quot;&gt;</SPAN>
<SPAN LANG="da-DK">      Konto &lt;%= k.getId() %&gt; med &lt;%= k.getSaldo() %&gt; kr.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;%</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;input type=&quot;submit&quot; value=&quot;V&aelig;lg konto&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;p&gt;&lt;a href=&quot;?handling=log_ud&quot;&gt;Log ud&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="bog11_html_680a85c5.png" NAME="Grafik92" ALIGN=BOTTOM BORDER=0></P>


<P CLASS="western">N&aring;r man har valgt en konto, kommer man
videre til vis_konto.jsp:</P>

<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>vis_konto.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;%@ page import=&quot;java.util.*&quot; %&gt;
<SPAN LANG="da-DK">&lt;jsp:useBean id=&quot;valg&quot; class=&quot;bank.Brugervalg&quot; scope=&quot;session&quot; /&gt;</SPAN>
<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Vis konto&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;h1&gt;Konto &lt;%= valg.konto.getId() %&gt; med ejer &lt;%= valg.konto.getEjer() %&gt;&lt;/h1&gt;</SPAN>
<SPAN LANG="da-DK">Saldo: &lt;%= valg.konto.getSaldo() %&gt;&lt;p&gt;</SPAN>
<SPAN LANG="da-DK">Bev&aelig;gelser:&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  List bev = <SPAN STYLE="font-weight: medium">valg.konto.getBev&aelig;gelser();</SPAN></SPAN>
<SPAN LANG="da-DK">  for (int i=0; i&lt;bev.size(); i++) {</SPAN>
<SPAN LANG="da-DK">    %&gt;</SPAN>
<SPAN LANG="da-DK">      &lt;%= bev.get(i) %&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;%</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;hr&gt;</SPAN>
<SPAN LANG="da-DK">Hvad vil du g&oslash;re:&lt;p&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;hidden&quot; name=&quot;handling&quot; value=&quot;haev&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  H&aelig;v &lt;input type=&quot;text&quot; name=&quot;beloeb&quot; size=&quot;4&quot;&gt; kr. fra kontoen.</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;submit&quot; value=&quot;H&aelig;v&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;p&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;hidden&quot; name=&quot;handling&quot; value=&quot;saet_ind&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  S&aelig;t &lt;input type=&quot;text&quot; name=&quot;beloeb&quot; size=&quot;4&quot;&gt; kr. ind p&aring; kontoen.</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;submit&quot; value=&quot;S&aelig;t ind&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>
<SPAN LANG="da-DK">&lt;p&gt;</SPAN>

<SPAN LANG="da-DK">&lt;form&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;hidden&quot; name=&quot;handling&quot; value=&quot;overfoer&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  Overf&oslash;r &lt;input type=&quot;text&quot; name=&quot;beloeb&quot; size=&quot;4&quot;&gt; kr. </SPAN>
<SPAN LANG="da-DK">  til konto nr. &lt;input type=&quot;text&quot; name=&quot;tilKontoId&quot; size=&quot;6&quot;&gt;.</SPAN>
<SPAN LANG="da-DK">  &lt;input type=&quot;submit&quot; value=&quot;Overf&oslash;r&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;p&gt;&lt;a href=&quot;?handling=log_ud&quot;&gt;Log ud&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="bog11_html_m7788068e.png" NAME="Grafik94" ALIGN=BOTTOM BORDER=0></P>

<P CLASS="western">Hvis brugeren ikke har nogen konti tilknyttet,
kommer han til ingen_konto.jsp i stedet for vaelg_konto.jsp:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>ingen_konto.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;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Ingen konto&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;Ingen konti fundet.&lt;/h1&gt;</SPAN>
<SPAN LANG="da-DK">Brugeren &lt;%= login.getBrugernavn() %&gt; har ingen konti tilknyttet.&lt;p&gt;</SPAN>
<SPAN LANG="da-DK">Kontakt venligst banken for at f&aring; oprettet en konto.</SPAN>

<SPAN LANG="da-DK">&lt;p&gt;&lt;a href=&quot;?handling=log_ud&quot;&gt;Log ud&lt;/a&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE>
<H3 CLASS="western">10.4.4 <a name='afsn10.4.4'></a>Kontroll&oslash;ren (kontrol.jsp)</H3>
<P CLASS="western">Her kommer kontrol.jsp, der s&oslash;rger for
kontroll&oslash;r-delen af applikationen: At manipulere med modellen
(b&oslash;nnernes egenskaber oftest) ud fra brugerens valg (den
indkomne formular) samt at beslutte, hvilken side der derefter skal
vises.</P>
<P CLASS="western">Den er lavet som en JSP-fil, men producerer ikke
selv noget output (den omdirigerer i stedet til
pr&aelig;sentations-JSP-filerne vist tidligere). 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm; ">
<FONT SIZE=2 STYLE="font-size: 9pt"><I>kontrol.jsp</I></FONT></P>
<PRE CLASS="kode-western"><I>&lt;%-- Hvis der opst&aring;r en undtagelse omdirigeres automatisk til fejl.jsp --%&gt;</I>
<SPAN LANG="da-DK">&lt;%@ page contentType=&quot;text/html; charset=iso-8859-1&quot; <B>errorPage=&quot;fejl.jsp&quot;</B> </SPAN>
<SPAN LANG="da-DK">         import=&quot;java.util.*, bank.*&quot; %&gt;</SPAN>

<SPAN LANG="da-DK">&lt;jsp:useBean id=&quot;login&quot; class=&quot;javabog.Login&quot; scope=&quot;session&quot;&gt;</SPAN>
<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>
&lt;jsp:setProperty name=&quot;login&quot; property=&quot;*&quot; /&gt;

&lt;%
<SPAN LANG="da-DK">  String handling = request.getParameter(&quot;handling&quot;);</SPAN>
<SPAN STYLE="font-weight: medium"><SPAN LANG="da-DK">  String brugernavn = login.getBrugernavn();</SPAN></SPAN>  <FONT COLOR="#d9d9d9"><FONT FACE="Courier, monospace"><FONT SIZE=1 STYLE="font-size: 2pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: transparent">//&lt;title&gt;kontrol&lt;/title&gt;</SPAN></SPAN></FONT></FONT></FONT>

  if (&quot;log ind&quot;.equals(handling)) login.tjekLogin();
  if (&quot;log_ud&quot;.equals(handling))  login.setAdgangskode(&quot;&quot;);
  
<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">  if (!login.isLoggetInd()) {</SPAN>            <SPAN STYLE="font-weight: medium"><I>// er brugeren logget korrekt ind?</I></SPAN></SPAN>
<SPAN LANG="da-DK">    application.log(&quot;Bruger &quot;+<SPAN STYLE="font-weight: medium">brugernavn</SPAN>+&quot; skal logge ind.&quot;);</SPAN>
<SPAN LANG="da-DK">    session.<B>removeAttribute</B>(&quot;valg&quot;);</SPAN>     <I>// eller evt: <SPAN LANG="da-DK">session.invalidate()</SPAN></I>
<SPAN LANG="da-DK">    request.getRequestDispatcher(<B>&quot;log_ind.jsp&quot;</B>).forward(request,response);</SPAN>
<SPAN LANG="da-DK">    return;                              <I>// afslut behandlingen af denne side</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>

<SPAN LANG="da-DK"><I>&lt;%-- Nedenst&aring;ende objekt har globalt virkefelt (svarer til en singleton) --%&gt;</I></SPAN>
<SPAN LANG="da-DK">&lt;jsp:useBean id=&quot;bank&quot; class=&quot;bank.Bankmodel&quot; <B>scope=&quot;application&quot;</B> /&gt;</SPAN>

<SPAN LANG="da-DK">&lt;jsp:useBean id=&quot;valg&quot; class=&quot;bank.Brugervalg&quot; scope=&quot;session&quot;&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;% valg.setBankmodel(bank); %&gt;</SPAN>  <I><SPAN LANG="da-DK">&lt;%-- s&aelig;t bankmodel f&oslash;rste gang --%&gt;</SPAN></I>
&lt;/jsp:useBean&gt;
&lt;jsp:setProperty name=&quot;valg&quot; property=&quot;*&quot; /&gt;

&lt;%
<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">  if (valg.konto == null) {</SPAN>              <I>// har han valgt en af sine konti?</I></SPAN>
<SPAN LANG="da-DK">    <I>// nej - find alle brugerens konti og l&aelig;g dem i valg.konti </I></SPAN>
<SPAN LANG="da-DK">    if (valg.konti == null) {</SPAN>
<SPAN LANG="da-DK">      valg.konti = new ArrayList();</SPAN>
<SPAN LANG="da-DK">      for (int i=0; i&lt;bank.konti.size(); i++) {</SPAN>
<SPAN LANG="da-DK">        Kontomodel k = (Kontomodel) bank.konti.get(i);</SPAN>
<SPAN LANG="da-DK">        if (k.getEjer().equalsIgnoreCase(<SPAN STYLE="font-weight: medium">brugernavn</SPAN>)) valg.konti.add(k);</SPAN>
<SPAN LANG="da-DK">      }</SPAN>
<SPAN LANG="da-DK">    }</SPAN>

<SPAN LANG="da-DK">    if (valg.konti.size() == 0) {</SPAN>
<SPAN LANG="da-DK">      application.log(<SPAN STYLE="font-weight: medium">brugernavn</SPAN>+&quot; skal oprette konto.&quot;);</SPAN>
<SPAN LANG="da-DK">      request.getRequestDispatcher(<B>&quot;ingen_konto.jsp&quot;</B>).forward(request,response);</SPAN>
<SPAN LANG="da-DK">    } else if (valg.konti.size() == 1) {</SPAN>
<SPAN LANG="da-DK">      application.log(<SPAN STYLE="font-weight: medium">brugernavn</SPAN>+&quot; har kun en konto, den v&aelig;lger vi!&quot;);</SPAN>
<SPAN LANG="da-DK">      valg.konto = (Kontomodel) valg.konti.get(0);</SPAN>
<SPAN LANG="da-DK">      request.getRequestDispatcher(<B>&quot;vis_konto.jsp&quot;</B>).forward(request,response);</SPAN>
<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">    } else </SPAN>{</SPAN>
<SPAN LANG="da-DK">      application.log(<SPAN STYLE="font-weight: medium">brugernavn</SPAN>+&quot; v&aelig;lger ml. &quot;+<SPAN STYLE="font-weight: medium">valg.konti.size()+&quot; konti&quot;);</SPAN></SPAN>
<SPAN LANG="da-DK">      request.getRequestDispatcher(<B>&quot;vaelg_konto.jsp&quot;</B>).forward(request,response);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    return;                              <I>// afslut behandlingen af denne side</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">  </SPAN>if (valg.handling != null)</SPAN> {           <SPAN STYLE="font-weight: medium"><I><SPAN LANG="da-DK">// konto er valgt - nogen handlinger?</SPAN></I></SPAN>
<SPAN LANG="da-DK">    application.log(<SPAN STYLE="font-weight: medium">brugernavn</SPAN>+&quot; udf&oslash;rer handling: &quot;+valg.handling);</SPAN>
<SPAN LANG="da-DK">    valg.udf&oslash;rHandling();</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">  request.getRequestDispatcher(<B>&quot;vis_konto.jsp&quot;</B>).forward(request,response);</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN></PRE><P CLASS="western">
Vi kunne ogs&aring; have lavet kontroll&oslash;ren som en servlet (se
<a href='kapitel7.jsp#afsn7.1'>afsnit 7.1</a>), men da kunne vi ikke udnytte &lt;jsp:setProperty ...
/&gt;-mekanismen til at s&aelig;tte b&oslash;nnernes egenskaber. 
</P>
<P CLASS="western">Derudover skal servletter ligge i en anden mappe,
adskilt fra JSP-siderne, hvilket ville g&oslash;re det mere
besv&aelig;rligt at pr&oslash;ve eksemplet.</P>
<P CLASS="western"><SPAN LANG="da-DK">N&aring;r brugervalg-b&oslash;nnen
oprettes, skal den initialiseres, ved at f&aring; kaldt
setBankmodel() med bank-objektet. Det g&oslash;r vi ved at l&aelig;gge
kode ind mellem &lt;jsp:useBean&gt; og &lt;/jsp:useBean&gt;, som
beskrevet i <a href='kapitel9.jsp#afsn9.2.7'>afsnit 9.2.7</a>, Initialisering af javab&oslash;nner:</SPAN></P>
<PRE CLASS="kode-western">&lt;jsp:useBean id=&quot;valg&quot; class=&quot;bank.Brugervalg&quot; scope=&quot;session&quot;&gt;
<SPAN LANG="da-DK">  &lt;% valg.setBankmodel(bank); %&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/jsp:useBean&gt;</SPAN></PRE>
<H3 CLASS="western">10.4.5 <a name='afsn10.4.5'></a>Fejlh&aring;ndtering (fejl.jsp)</H3>
<P CLASS="western">Indtaster brugeren noget forkert (f.eks. h&aelig;ve
et negativt bel&oslash;b), opst&aring;r der en undtagelse (eng.:
Exception) og siden fejl.jsp vises:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog11_html_mdadd7d1.png" NAME="Grafik93" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western"><SPAN LANG="da-DK">Dette sker fordi
sidedirektivet errorPage=&quot;fejl.jsp&quot; var sat i kontrol.jsp
hvor fejl (undtagelser) kunne opst&aring;:</SPAN></P>
<PRE CLASS="kode-western"><I>&lt;%-- Hvis der opst&aring;r en undtagelse omdirigeres automatisk til fejl.jsp --%&gt;</I>
<SPAN LANG="da-DK">&lt;%@ page <B>errorPage=&quot;fejl.jsp&quot;</B> %&gt;</SPAN></PRE><P CLASS="western">
Hvis en undtagelse opst&aring;r, vil anmodningen derfor automatisk
blive omdirigeret til siden fejl.jsp. Denne side skal have sat
sidedirektivet isErrorPage=&quot;true&quot; og har det implicitte
objekt exception defineret:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>fejl.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;%@ page contentType=&quot;text/html; charset=iso-8859-1&quot; <B>isErrorPage=&quot;true&quot;</B> %&gt;
<SPAN LANG="da-DK">&lt;jsp:useBean id=&quot;login&quot; class=&quot;javabog.Login&quot; scope=&quot;session&quot;/&gt;</SPAN>
<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Fejl&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>
<SPAN LANG="da-DK"><SPAN STYLE="font-weight: medium">Der skete en fejl: &lt;%= </SPAN><B>exception</B><SPAN STYLE="font-weight: medium">.getLocalizedMessage() %&gt;.</SPAN></SPAN>
<SPAN LANG="da-DK">&lt;p&gt;</SPAN>
<SPAN LANG="da-DK">G&aring; tilbage og pr&oslash;v igen.</SPAN>
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  application.log( (Exception)<B>exception</B>, &quot;Fejl for &quot;+<SPAN STYLE="font-weight: medium">login.getBrugernavn()</SPAN>);</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>

<SPAN LANG="da-DK">&lt;p&gt;&lt;a href=&quot;?handling=log_ud&quot;&gt;Log ud&lt;/a&gt;</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">Se ogs&aring; <a href='kapitel4.jsp#afsn4.4'>afsnit 4.4</a> og <a href='kapitel4.jsp#afsn4.5.8'>afsnit 4.5.8</a> for
information om fejlh&aring;ndtering.</SPAN></P>

<H3 CLASS="western">10.4.6 <a name='afsn10.4.6'></a>Hvordan pr&aelig;sentation henviser til
kontroll&oslash;r</H3>
<P CLASS="western">I pr&aelig;sentationssider har vi ikke angivet,
hvor formulardata skal sendes hen. Der st&aring;r blot:</P>
<PRE CLASS="kode-western">&lt;form&gt;</PRE><P CLASS="western">
og</P>
<PRE CLASS="kode-western">&lt;a href=&quot;?handling=log_ud&quot;&gt;Log ud&lt;/a&gt;</PRE>
<P CLASS="western"><SPAN LANG="da-DK">Vi <I>kunne</I> godt have
skrevet kontrol.jsp ind i alle formularer og henvisninger, da det jo
er den, der skal modtage data, f.eks.:</SPAN></P>
<PRE CLASS="kode-western">&lt;form action=&quot;kontrol.jsp&quot;&gt;</PRE><P CLASS="western">
og</P>
<PRE CLASS="kode-western">&lt;a href=&quot;kontrol.jsp?handling=log_ud&quot;&gt;</PRE><P CLASS="western">
<SPAN LANG="da-DK">men det er strengt taget overfl&oslash;digt, da vi
bruger <I>serverside</I>-omdirigering (beskrevet i <a href='kapitel4.jsp#afsn4.3.2'>afsnit 4.3.2</a>),
s&aring;dan at netl&aelig;seren slet ikke ved, at der er omdirigeret
til en anden side. Netl&aelig;seren indsender s&aring;ledes
formulardata til kontrol.jsp som den skal, selvom det i virkeligheden
er en anden side p&aring; serveren, der har skabt formularen.</SPAN></P>

<H2 CLASS="western">10.5 <a name='afsn10.5'></a>Designm&oslash;nster: Frontkontrol</SPAN></H2>
<P CLASS="western">En Frontkontrol (eng.: Front Controller) s&oslash;rger
for at dirigere brugeren hen til den rigtige side. Hvis brugeren m&aring;
navigere frit, vil frontkontrollen blot s&oslash;rge for, at brugeren
f&aring;r de anspurgte sider. Hvis brugeren skal f&oslash;lge en
bestemt vej gennem siderne, vil frontkontrollen tjekke brugerens
indtastninger og omdirigere brugeren, s&aring;dan at vejen gennem
siderne f&oslash;lges. Det kunne f.eks. v&aelig;re, at brugeren
skulle indtaste brugernavn og adgangskode, for at kunne se nogle
bestemte sider. Frontkontrollen ville da omdirigere brugere, der ikke
er logget ind, til login-siden.</P>
<P CLASS="western">En Frontkontrol er alts&aring; en central del af
webapplikationen, som alle anmodninger g&aring;r igennem.
Frontkontrollen beslutter, hvilken side der rent faktisk skal vises
og omdirigerer til den.</P>
<H4 CLASS="western">Bankkonto-eksemplet</H4>
<P CLASS="western"><SPAN LANG="da-DK">JSP-siden kontrol.jsp fra
<a href='kapitel10.jsp#afsn10.4.4'>afsnit 10.4.4</a> er <I>n&aelig;sten</I> en frontkontrol. Den er det ikke
helt, fordi man kan kan rette i URLen og p&aring; den f&aring; fat i
de andre sider uden om kontrol.jsp.</SPAN> Senere, i <a href='kapitel10.jsp#afsn10.5.3'>afsnit 10.5.3</a>,
vil vi se p&aring;, hvad der skulle g&oslash;res, for at brugeren
ikke kan g&aring; uden om den.</P>
<H3 CLASS="western">10.5.1 <a name='afsn10.5.1'></a>Variationer (til st&oslash;rre
applikationer)</H3>
<P CLASS="western">I en st&oslash;rre webapplikation bliver det
besv&aelig;rligt, hvis &eacute;n Frontkontrol skal st&aring; for al
omdirigering. Da kan man v&aelig;lge, at k&aelig;de flere
Frontkontroller, s&aring;dan at forskellige Frontkontroller kan st&aring;
for forskellige dele af applikationen. 
</P>
<P CLASS="western">Man kan ogs&aring; v&aelig;lge, at Frontkontrollen
kalder en eller flere eksterne klasser, der 'ekspederer' brugerens
anmodninger og beslutter, hvad der skal ske i forskellige situationer
(en ekspedit&oslash;r - eng.: Dispatcher).</P>

<P CLASS="western">Skal applikationen kunne anvendes p&aring; flere
forskellige sprog eller fra flere forskellige slags klienter, f.eks.
b&aring;de fra en almindelig netl&aelig;ser (s&aring;som
Netscape/Mozilla) og fra PDA'er og mobiltelefoner, kunne man v&aelig;lge
at lade Frontkontrollen kalde en ekstern klasse  (en 'View Mapper'),
der beslutter, om klienten skal have svaret tilsendt som HTML eller
som f.eks. WML.</P>
<H3 CLASS="western">10.5.2 <a name='afsn10.5.2'></a>Implementering af en Frontkontrol</H3>
<P CLASS="western">En Frontkontrol er ofte implementeret som en
servlet, men der er intet, der forhindrer en i at bruge en JSP-side
som Frontkontrol i stedet. Det kan g&oslash;res p&aring; flere m&aring;der:</P>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Manuel inklusion af
  JSP-side, der agerer Frontkontrol: En simpel implementering af en
  Frontkontrol som en JSP-side kunne v&aelig;re, at alle JSP-sider
  inkluderede en bestemt anden JSP-side, der derfor blev udf&oslash;rt
  som det f&oslash;rste p&aring; hver side. Denne side kunne f.eks.
  tjekke om brugeren var logget ind og lave en omdirigering af
  klienten (se <a href='kapitel4.jsp#afsn4.3.1'>afsnit 4.3.1</a>, Klient-omdirigering) til login-siden,
  hvis det ikke var tilf&aelig;ldet.</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Man redigerer web.xml
  s&aring;dan, at alle foresp&oslash;rgsler dirigeres til &eacute;n
  servlet eller JSP-side, der agerer Frontkontrol. Den v&aelig;lger
  derp&aring; hvilken JSP-side, foresp&oslash;rgslen skal dirigeres
  videre til.</SPAN> Siderne ligger skjult for klienten i
  WEB-INF/-mappen og omdirigering skal derfor ske internt i serveren
  (se <a href='kapitel4.jsp#afsn4.3.2'>afsnit <SPAN LANG="da-DK">4.3.2</a>, Server-omdirigering).</SPAN></P>
</UL>
<P CLASS="western">Lad os se p&aring; den anden mulighed.</P>
<H3 CLASS="western">10.5.3 <a name='afsn10.5.3'></a>Eksempel p&aring; en Frontkontrol</H3>
<P CLASS="western"><SPAN LANG="da-DK">Ved at rette i web.xml kan man
tvinge al trafikken til &eacute;n side (kontrol.jsp), der derp&aring;
v&aelig;lger hvilken JSP-side, der skal vises. <SPAN STYLE="font-weight: medium">Her
er den relevante del af web.xml:</SPAN></SPAN></P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>udsnit
af WEB-INF/web.xml</I></FONT></P>
<PRE CLASS="kode-western"><I>  &lt;!-- Frontkontrol: Alt der starter med /bank sendes til kontrol.jsp --&gt;</I>
<SPAN LANG="da-DK">  &lt;servlet&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;servlet-name&gt;Frontkontrol&lt;/servlet-name&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;jsp-file&gt;/WEB-INF/bank/kontrol.jsp&lt;/jsp-file&gt;</SPAN>
<SPAN LANG="da-DK">  &lt;/servlet&gt;</SPAN>

<SPAN LANG="da-DK">  &lt;servlet-mapping&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;servlet-name&gt;Frontkontrol&lt;/servlet-name&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;url-pattern&gt;/bank/*&lt;/url-pattern&gt;         <I>&lt;!-- Bem&aelig;rk: * i URL-m&oslash;nster --&gt;</I></SPAN>
<SPAN LANG="da-DK">  &lt;/servlet-mapping&gt;</SPAN></PRE><P CLASS="western">
Alle JSP-siderne flyttes nu ind i mappen WEB-INF/bank/, hvilket g&oslash;r
det umuligt for klienten at f&aring; fat i dem direkte. 
</P>
<P CLASS="western">Til geng&aelig;ld angives, at alle foresp&oslash;rgsler,
der passer med URL-m&oslash;nstret /bank/*, skal dirigeres til
frontkontrollen /WEB-INF/bank/kontrol.jsp, der dermed bliver den
eneste side, brugerne f&aring;r adgang til. 
</P>


<P CLASS="western">Lige meget hvilken URL brugeren skriver f&aring;r
han alts&aring; kontrol.jsp (her har en bruger fors&oslash;gt sig med
bank/xyz som URL):</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog11_html_4fb1d401.png" NAME="Grafik95" ALIGN=BOTTOM BORDER=0></P>

<P CLASS="western"><SPAN LANG="da-DK">I omdirigeringen i kontrol.jsp
skal den a</SPAN>bsolutte sti (/WEB-INF/bank/) nu angives, s&aring;:</P>
<PRE CLASS="kode-western">request.getRequestDispatcher(&quot;log_ind.jsp&quot;).forward(request,response);</PRE><P CLASS="western">
skal rettes til:</P>
<PRE CLASS="kode-western">request.getRequestDispatcher(&quot;<B>/WEB-INF/bank/</B>log_ind.jsp&quot;).forward(request,response);</PRE>
<H4 CLASS="western">&Oslash;velse</H4>
<UL>
  <LI><P CLASS="western">Afpr&oslash;v bankkonto-eksemplet. Tjek om du
  kan omg&aring; kontrol.jsp og se nogle af de andre sider ved at
  rette i URLen. <BR>Ret f.eks. kode/kapitel_10/ til
  kode/kapitel_10/vaelg_konto.jsp</P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Udf&oslash;r de
  ovenst&aring;ende &aelig;ndringer og tjek om du stadig kan omg&aring;
  kontrol.jsp. <BR>Ellers ret URLen fra kode/kapitel_10/ til bank/
  (her er rettelserne allerede foretaget).<BR>Du kan ogs&aring; pr&oslash;ve
  eksemplet fra: </SPAN><A CLASS="western" HREF="http://javabog.dk:8080/JSP/bank/">http://javabog.dk:8080/JSP/bank/</A></P>
</UL>


<H2 CLASS="western">10.6 <a name='afsn10.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/kapitel10.jsp#afsn10.6">
  <input type='checkbox' name='vis' value='10.6'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='10.6'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H2 CLASS="western">10.7 <a name='afsn10.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/kapitel10.jsp#afsn10.7">
  <input type='checkbox' name='vis' value='10.7'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='10.7'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H2 CLASS="western">10.8 <a name='afsn10.8'></a><SPAN LANG="da-DK">Rammer for webarkitekturer</SPAN></SPAN></H2>
<P CLASS="western"><SPAN LANG="da-DK">Der er rigtig mange rammer
(eng.: frameworks) og standarder for hvordan en webapplikation med
model 2-arkitektur skal bygges op. I det f&oslash;lgende vil de to
vigtigste blive ber&oslash;rt.</SPAN></P>

<H3 CLASS="western">10.8.1 <a name='afsn10.8.1'></a>Jakarta Struts</H3>
<P CLASS="western">Struts er et Open Source-projekt baseret p&aring;
JSP og servletter. Det underst&oslash;tter
Model-View-Controller-arkitekturen beskrevet i dette kapitel, p&aring;
den m&aring;de at Struts udg&oslash;r Frontkontrol (d.v.s.
kontroll&oslash;ren) og dele af pr&aelig;sentationen.</P>
<P CLASS="western">Der er under rammerne for Struts bl.a. mekanismer
til implementering af indsamlingen af brugerinput fra formularer,
validering af brugerinput, visning af meddelelser og fejltekster med
underst&oslash;ttelse for forskellige sprog, opbygning af websider ud
fra skabeloner m.v..</P>
<P CLASS="western">Struts er indenfor de seneste par &aring;r blevet
meget popul&aelig;rt og er nu en de facto standard inden for st&oslash;rre
webapplikationer. Alle udviklingsv&aelig;rkt&oslash;jerne n&aelig;vnt
i denne bog underst&oslash;tter s&aring;ledes Struts.</P>

<H3 CLASS="western">10.8.2 <a name='afsn10.8.2'></a>JSF - Java Server Faces</H3>
<P CLASS="western"><SPAN LANG="da-DK">Java Server Faces (JSF) er et
system til at designe web-baserede brugergr&aelig;nseflader i Java.
Det er samme id&eacute; som bruges i </SPAN>WebObjects fra Apple og
ASP.NET Web Forms fra Microsoft:<SPAN LANG="da-DK"> Ligesom med
almindelige grafiske brugergr&aelig;nseflader i AWT eller Swing har
man et s&aelig;t komponenter (knapper, indtastningsfelter,
afkrydsningsfelter e.t.c. og det er ogs&aring; muligt at definere
sine egne), som man bruger til at opbygge sin webside med. </SPAN>
</P>
<P CLASS="western"><SPAN LANG="da-DK">Opbygningen kan ske i en visuel
designer, som man kender det fra n&aring;r man designer i AWT/Swing:
</SPAN>Hver komponent er en javab&oslash;nne, hvis egenskaber kan
&aelig;ndres (d.v.s. som kan afl&aelig;ses/s&aelig;ttes med get- og
set-metoder) og n&aring;r brugeren foretager en handling, afsender
komponenterne h&aelig;ndelser (eng.: events), som kan aktivere netop
de stumper kode, der er brug for.</P>
<P CLASS="western">JSF giver en helt anden m&aring;de at g&aring; til
webprogrammering p&aring;: I stedet for at programmere JSP-sider, der
unders&oslash;ger request-objektet og producerer HTML, definerer man
alts&aring; en JSF-side ved hj&aelig;lp af komponenter og kan s&aring;
manipulere med komponenterne og definere kode, der bliver udf&oslash;rt
n&aring;r brugeren g&oslash;r bestemte med komponenterne, f.eks.
udfylder et indtastningsfelt. JSF s&oslash;rger for det
mellemliggende lag, med at unders&oslash;ge request-objektet og
producere den rigtige HTML.</P>
<P CLASS="western">JSFs arkitektur underst&oslash;tter at
komponenterne producerer forskellig HTML-kode afh&aelig;ngig af
klientens form&aring;en, s&aring;dan at samme JSF-applikation kan
bruges til PDA'er, mobiltelefoner, almindelige netl&aelig;sere etc..</P>


<H2 CLASS="western">10.9 <a name='afsn10.9'></a>Mere l&aelig;sning</SPAN></H2>
<H4 CLASS="western">Mere l&aelig;sning om model 2-arkitektur og MVC</H4>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Afsnit '4.3 Web-Tier
  Application Structure' og ' 11.1 J2EE Architecture Approaches' i
  <BR></SPAN><A CLASS="western" HREF="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/"><SPAN LANG="da-DK">http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/</SPAN></A><SPAN LANG="da-DK">
  </SPAN>
  </P>
</UL>

<H4 CLASS="western">Mere l&aelig;sning om Struts</H4>
<UL>
  <LI><P CLASS="western">Den officielle hjemmeside om  Jakarta
  Struts:<BR> p&aring; <A CLASS="western" HREF="http://struts.apache.org/">http://struts.apache.org</A>.</P>
</UL>

<H4 CLASS="western">Mere l&aelig;sning om Java Server Faces</H4>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Suns officielle side om
  Java Server Faces:</SPAN><BR><SPAN LANG="da-DK">
  </SPAN><A CLASS="western" HREF="http://java.sun.com/j2ee/javaserverfaces/"><SPAN LANG="da-DK">http://java.sun.com/j2ee/javaserverfaces/</SPAN></A><SPAN LANG="da-DK">
  </SPAN>
  </P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Om JSF i 'The J2EE
  Tutorial':</SPAN><BR><SPAN LANG="da-DK">
  </SPAN><A CLASS="western" HREF="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSFIntro.html"><SPAN LANG="da-DK">http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSFIntro.html</SPAN></A></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Portal om JSF:<BR>
  </SPAN><A CLASS="western" HREF="http://www.jsfcentral.com/"><SPAN LANG="da-DK">http://www.jsfcentral.com</SPAN></A><SPAN LANG="da-DK">
  </SPAN>
  </P>
  <LI><P CLASS="western">Artikel: 'Developing Web Applications with
  JavaServer Faces':<BR><SPAN LANG="da-DK">
  </SPAN><A CLASS="western" HREF="http://java.sun.com/developer/technicalArticles/GUI/JavaServerFaces/"><SPAN LANG="da-DK">http://java.sun.com/developer/technicalArticles/GUI/JavaServerFaces/</SPAN></A><SPAN LANG="da-DK">
  </SPAN>
  </P>
</UL>

<H4 CLASS="western">Mere l&aelig;sning om andre rammer for
webarkitekturer</H4>
<UL>
  <LI><P CLASS="western"><A CLASS="western" HREF="http://directory.google.com/Top/Computers/Programming/Languages/Java/Server-Side/Servlets/"><SPAN LANG="da-DK">Se
  under 'Servlets' og under '</SPAN></A><A CLASS="western" HREF="http://directory.google.com/Top/Computers/Programming/Languages/Java/Server-Side/Libraries_and_Frameworks/"><SPAN LANG="da-DK">Libraries_and_Frameworks'
  p&aring;</SPAN></A><SPAN LANG="da-DK"><BR></SPAN><A CLASS="western" HREF="http://directory.google.com/Top/Computers/Programming/Languages/Java/Server-Side/"><SPAN LANG="da-DK"><FONT SIZE=2 STYLE="font-size: 9pt">http://directory.google.com/Top/Computers/Programming/Languages/Java/Server-Side/</FONT></SPAN></A></P>
</UL>



<DIV ID="sdfootnote1">
  <P CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote1sym" HREF="#sdfootnote1anc">1</A>De
  kunne ogs&aring; opfattes som en del af kontroll&oslash;ren.</P>
</DIV>

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel9.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel11.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>
