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

7 Inde i webserveren


7.1 Servletter 135

7.1.1 Anmodningsmetoder 137

7.1.2 Hvornår bruge JSP og hvornår bruge servletter 137

7.2 Installation af en servlet 138

7.2.1 Flere URLer til samme servlet 138

7.2.2 Avanceret: Automatisk binding af servletter 139

7.3 Avanceret: JSP-siders interne virkemåde 139

7.3.1 Kigge i de genererede servletter 139

7.3.2 Eksempel 139

7.3.3 JSP-siders livscyklus 141

7.4 Webapplikationer 142

7.4.1 Pakkede webapplikationer (WAR-filer) 142

7.5 Samlet driftsbeskrivelse (web.xml) 143

7.6 Test dig selv 146

7.7 Resumé 146

Dette kapitel er frivillig læsning; det forudsættes ikke i resten af bogen.

Det forudsætter kapitel 3, Interaktive sider, og kapitel 5, Brug af databaser.

Dette kapitel handler om konfiguration af webserveren og nogle af de ting, der sker "under motorhjelmen", inde i webserveren.

7.1 Servletter

En servlet er en Java-klasse, der bliver brugt af en webserver. Den har noget programkode, der opbygger et HTML-dokument, som bliver sendt til klienten.

Her er en servlet, der udskriver det samme som JSP-siden syvtabellen.jsp (fra afsnit 2.2.1, Indlejrede java-udtryk):

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpelServlet extends HttpServlet
{
  public void doGet(HttpServletRequest request, 
                    HttpServletResponse response) throws IOException
  {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head><title>Syvtabellen - fra en servlet</title></head>");
    out.println("<body>");
    out.println("<p>Her er syv-tabellen:<br>");
 
    for (int i=1; i<=10; i++)
    {
      out.println("Syv gange "+ i +" er: "+ 7*i +".<br>");
    } 
    out.println("</body>");
    out.println("</html>");
  }
}

Læg mærke til:

Uddata fra en servlet er som regel HTML, men kan egentlig være af enhver slags. Servletten kan sende andre slags data, e.v.t. binære, eller viderestille til en anden adresse.

Når webserveren får en anmodning om en URL, der svarer til servlettens navn2, kalder den metoden doGet() på servletten (allerførste gang opretter serveren et objekt af den pågældende klasse). Denne metode får overført alle relevante oplysninger om anmodningen i et request-objekt og skal så udfylde et response-objekt med svaret til klienten.

For at afprøve servletten (forudsat vi har oversat til binær kode og installeret det i en webserver) kalder vi f.eks. adressen http://localhost:8080/JSP/servlet/SimpelServlet op i en netlæser (man ser at servlettens navn normalt indgår i URLen).

7.1.1 Anmodningsmetoder

Som diskuteret i afsnit 3.6.4, Skjule parametrene (POST-metoden), findes der flere metoder en netlæser kan tage i anvendelse, når den skal foretage en forespørgsel (GET og POST).

GET-anmodninger forårsager at servlettens doGet(request, response)-metode bliver kaldt.

Tilsvarende forårsager POST-anmodninger, at metoden doPost(request, response) kaldes.

Ofte er man dog ligeglad med, om anmodninger kommer med den ene eller anden metode og så lader man blot doPost() kalde doGet(), som så gør arbejdet:

  public void doPost(HttpServletRequest request, 
                    HttpServletResponse response) throws IOException
  {
    doGet(request, response);
  }

Hvilken anmodningsmetode, der bruges, kan altid ses med request.getMethod().

7.1.2 Hvornår bruge JSP og hvornår bruge servletter

Servletter er som sagt javakode (Java-klasser), der genererer HTML-kode.

JSP er på en måde det omvendte: HTML-kode med indlejret Javakode.

Er du i tvivl om du skal bruge JSP-sider eller servletter til en given opgave, så er her et par betragtninger, du kan tage med i dine overvejelser:

Alt i alt er servletter mest velegnede til indviklet programlogik, mens JSP-sider er velegnede, hvis der skal produceres meget HTML til klienten. Er du begynder, bør du nok vælge JSP-sider, da de er lettest at komme i gang med.

7.2 Installation af en servlet

Før du kan køre en servlet, skal du angive servlet-klassen, der svarer til en URL på webserveren. Det gøres i filen web.xml (der skal ligge i mappen WEB-INF), hvor der skal stå:

  1. Navnet på servletten i <servlet-name>

  2. Klassenavnet (incl. pakkenavn) i <servlet-class>

  3. Hvilke(n) URL(er) på serveren der skal omdirigeres til servletten i <url-pattern> i en <servlet-mapping>

Her er et uddrag af web.xml. Gennem navnet "En simpel servlet" bindes klassen SimpelServlet til URLen /servlet/SimpelServlet:

<web-app>
  ...
  <servlet>
    <servlet-name>En simpel servlet</servlet-name>
    <servlet-class>SimpelServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>En simpel servlet</servlet-name>
    <url-pattern>/servlet/SimpelServlet</url-pattern>
  </servlet-mapping>
  ...
</web-app>

7.2.1 Flere URLer til samme servlet

Denne syntaks løsriver klassenavnet fra URLen og giver dermed mulighed for mange fikse måder at sætte sin webapplikation op på.

Vi kunne f.eks. sende alle forespørgsler til /simpel/* til vores SimpelServlet ved at tilføje:

  <servlet-mapping>
    <servlet-name>En simpel servlet</servlet-name>
    <url-pattern>/simpel/*</url-pattern>
  </servlet-mapping>

Herefter ville f.eks. http://localhost:8080/JSP/simpel/hvad.som.helst få webserveren til at kalde SimpelServlet.

Et praktisk eksempel på, hvor dette kunne være nyttigt, findes i afsnit 10.5.3, Eksempel på en Frontkontrol.

7.2.2 Avanceret: Automatisk binding af servletter

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

7.3 Avanceret: JSP-siders interne virkemåde

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

7.3.1 Kigge i de genererede servletter

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

7.3.2 Eksempel

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

7.3.3 JSP-siders livscyklus

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

7.4 Webapplikationer

En webapplikation er en gruppe websider, der hører sammen. En webserver kan godt have flere webapplikationer kørende samtidig og oprette/installere, fjerne og opdatere webapplikationer uafhængigt af hinanden.

På harddisken har serveren normalt hver webapplikation liggende i en separat mappe. I Tomcat ligger disse mapper under webapps/.

På billedet til højre kan man på mappestrukturen se, at der er installeret 5 webapplikationer, nemlig "JSP", "jsp-examples", "ROOT", "servlet-examples" og "tomcat-docs".

Disse kan findes under en URL, der svarer til navnet. F.eks. ligger webapplikationen "jsp-examples" på http://localhost:8080/jsp-examples/ (eneste undtagelse er ROOT som ligger i roden, på http://localhost:8080 ).

HTML- og JSP-sider, billeder etc. ligger som filer i webapplikationens mappe. I den specielle undermappe WEB-INF/ ligger alle andre filer:

I WEB-INF/classes skal dine egne klasser ligge.

I WEB-INF/lib skal du lægge JAR-filer med funktioner, der bruges i dine JSP-sider.

I WEB-INF/web.xml skal driftsbeskrivelsen til serveren ligge (se afsnit 7.5).

Nogen gange kan filstrukturen afvige fra, hvad man forventer ud fra URLen, fordi det står angivet i WEB-INF/web.xml (se afsnit 7.2). Det gælder især servletter. Således kunne SimpelServlet, der ligger webapplikationen "JSP" i filen WEB-INF/classes/SimpelServlet.class, være afbildet over på URL-adressen http://localhost:8080/JSP/servlet/SimpelServlet .

7.4.1 Pakkede webapplikationer (WAR-filer)

En webapplikation kan være pakket ned i en WAR-fil (Web ARchive), der er en ZIP-fil med en mappestruktur, der svarer til, hvordan filerne skal ligge på serveren.

Installere en WAR-fil

En WAR-fil kan kopieres ind i mappen webapps i Tomcat. Derefter vil webserveren selv pakke den ud og idriftsætte den.

På billedet ovenfor kan man nederst se hvordan WAR-filen JSP.war er blevet kopieret til webapps/JSP.war, hvorefter webserveren har pakket ud i webapps/JSP/ , så den er tilgængelig på adressen http://localhost:8080/JSP/.

Lave en WAR-fil

Selvom princippet i WAR-filer egentlig er enkelt nok, er der mange, der til at starte med, har problemer med at lave WAR-filer. Bruger du et udviklingsværktøj, bør du se, om det kan hjælpe dig med at generere WAR-filen. Ellers er det nemmeste ofte, at tage en eksisterende WAR-fil (tjek at den virker!) og erstatte filerne i den med dine egne.

Filstrukturen og mappestrukturen i en WAR-fil skal være præcist som den på harddisken, især skal man huske at WEB-INF/ skal ligge i roden af ZIP-filen. Her er et eksempel:

7.5 Samlet driftsbeskrivelse (web.xml)

Det er i webapplikationens WEB-INF/web.xml man beskriver, hvordan serveren skal køre ens webapplikation i drift.

Her ses hvordan driftsbeskrivelsen web.xml samlet ser ud for eksemplerne til denne bog.

web.xml - driftsbeskrivelse for webapplikationen

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

  <!-- Samlet eksempel på konfigurationsfil for en webapplikation.
       Filnavn: /WEB-INF/web.xml
    -->

  <display-name>Eksempler fra javabog.dk</display-name>
  <description>Alle eksemplerne fra bogen "Webprogrammering med Java Server Pages",
    der også kan læses på http://javabog.dk/JSP</description>

  <!-- ================================================================
       Eksempler på initialiseringsparametre - se afsnit 4.5.5 i bogen
       Aflæs med f.eks: application.getInitParameter("dbDriver")
       ================================================================ --> 
  <context-param>
    <description>Driveren til databasen</description>
    <param-name>dbDriver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
  </context-param>

  <context-param>
    <description>Adressen (URLen) på databasen</description>
    <param-name>dbUrl</param-name>
    <param-value>jdbc:mysql:///test</param-value>
  </context-param>

  <context-param>
    <description>Brugernavnet til databasen</description>
    <param-name>dbBruger</param-name>
    <param-value>root</param-value>
  </context-param>

  <context-param>
    <description>Adgangskoden til databasen</description>
    <param-name>dbAdgangskode</param-name>
    <param-value></param-value>
  </context-param>
 
  <!-- Denne initialiseringsparameter er til JSTLs databasetags i afsnit 6.3 -->
  <context-param>
    <param-name>javax.servlet.jsp.jstl.sql.dataSource</param-name>
    <param-value>jdbc:mysql:///test,com.mysql.jdbc.Driver</param-value>
  </context-param>

  <!-- Disse initialiseringsparametre er til Login-bønnen i afsnit 9.5 -->
  <context-param>
    <description>SMTP-server for epost fra Login-bønnen i afsnit 9.5</description>
    <param-name>postserver</param-name>
    <param-value>post.tele.dk</param-value>  <!-- TDC som internetudbyder -->
  </context-param>

  <context-param>
    <description>Afsenderadressen for Login-bønnen i afsnit 9.5</description>
    <param-name>postafsender</param-name>
    <param-value>din@adresse.dk</param-value>
  </context-param>

  <!-- ================================================================
       Indstillinger til afsnit 7.1, Servletter
       ================================================================ --> 
  <servlet>
    <servlet-name>En simpel servlet</servlet-name>
    <servlet-class>SimpelServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>En simpel servlet</servlet-name>
    <url-pattern>/servlet/SimpelServlet</url-pattern>
  </servlet-mapping>
 
  <!-- Alle forespørgsler til /simpel/* sendes til vores SimpelServlet --> 
  <servlet-mapping>
    <servlet-name>En simpel servlet</servlet-name>
    <url-pattern>/simpel/*</url-pattern>
  </servlet-mapping>

  <!-- Bind alle klasser (herunder også servletter) til /servlet/Klassenavn -->
  <!-- Kommenteret bort af sikkerhedshensyn
  <servlet>
    <servlet-name>invoker</servlet-name>
    <servlet-class>org.apache.catalina.servlets.InvokerServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
     <servlet-name>invoker</servlet-name>
     <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
  -->


  <!-- ================================================================
       Indstillinger til afsnit 8.2, Adgangskontrol
       ================================================================ --> 
  <!-- De roller, der er aktuelle for webapplikationen -->
  <security-role>
    <role-name>kunde</role-name>
    <role-name>administrator</role-name>
  </security-role>

  <!-- En gruppe sider med adgangbegrænsning -->
  <security-constraint>
    <display-name>Sikkerhedsbegraensning i kapitel 8</display-name>

    <!-- Præcist hvilke sider, der er omfattet af adgangbegrænsningen -->
    <web-resource-collection>
      <url-pattern>/kode/kapitel_08/beskyttet_side.jsp</url-pattern>
    </web-resource-collection>

    <!-- Hvilke brugerroller har adgang til de pågældende sider -->
    <auth-constraint>
      <role-name>kunde</role-name>
    <role-name>administrator</role-name>
    </auth-constraint>

    <!-- Hvordan skal data sendes over netværket -->
    <!-- Mulighederne er: NONE, INTEGRAL og CONFIDENTIAL (kræver SSL)
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>   
    -->
  </security-constraint>  

  <!-- Brugeren skal identificeres med en login-formular -->
  <login-config>
    <auth-method>FORM</auth-method> 
    <form-login-config>
      <form-login-page>/kode/kapitel_08/loginside.jsp</form-login-page>     
      <form-error-page>/kode/kapitel_08/fejlagtig_login.jsp</form-error-page>  
    </form-login-config>
    <!-- Andre muligheder er (giver et loginvindue i stedet for login-formular)
    <auth-method>BASIC</auth-method> 
    <auth-method>DIGEST</auth-method> 
    <auth-method>CLIENT-CERT</auth-method> 
    -->
  </login-config>  


  <!-- ================================================================
       Indstillinger til kapitel 10, Arkitekturer i webprogrammering
       ================================================================ --> 

  <!-- Forespørgsler til /kode/kapitel_10/ sendes til kontrol.jsp --> 
  <servlet>
    <servlet-name>Kontrolloer</servlet-name>
    <jsp-file>/kode/kapitel_10/kontrol.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
    <servlet-name>Kontrolloer</servlet-name>
    <url-pattern>/kode/kapitel_10/</url-pattern>
  </servlet-mapping>

  <!-- Frontkontrol: Alt der starter med /bank sendes til kontrol.jsp -->
  <servlet>
    <servlet-name>Frontkontrol</servlet-name>
    <jsp-file>/WEB-INF/bank/kontrol.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
    <servlet-name>Frontkontrol</servlet-name>
    <url-pattern>/bank/*</url-pattern>         <!-- Bemærk: * i URL-mønster -->
  </servlet-mapping>

</web-app>

7.6 Test dig selv

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

7.7 Resumé

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

1Man kan også definere andre metoder, se senere.

2I afsnit 7.2 vil vi se, hvordan man binder en servlet til en URL.

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

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