1.2. nodaļa: Javas servleti

Mērķi

  • Saprast Javas servletu arhitektūru
  • Saprast servleta programmēšanas pamatiezīmes
  • Prast veidot Web aplikācijām piemērotu direktoriju struktūru un būvēt tās ar Ant
  • Prast ar servletiem veidot datubāzu aplikācijas, apstrādāt failu augšupielādi un atgriezt binārus datus

Kas ir servlets

  • Servlets ir Javas programma, kura darbojas J2EE aplikāciju serverī; saņem un apstrādā HTTP pieprasījumus.
  • Servleti (jeb servsīklietotnes) domāti, lai modificētu Web servera standartuzvedību; tie tātad ir servera puses analogs Javas apletiem
  • Jakarta Tomcat satur servletu konteineru, kurš nodrošina servleta ieejas un izejas datu piesaisti Web servera portam (pēc noklusēšanas 8080)
  • JSP lapas pirms to izpildes arī tiek pārveidotas par servletiem
  • Servleti un JSP parasti ģenerē HTML vai XML dokumentus, tomēr servletus mēdz izmantot arī citu dokumentu tipu veidošanai. JSP toties ir piemērotāks tieši HTML dokumentu ģenerācijai servera pusē.

Servletu arhitektūra

Servleta galvenās metodes

Klasē javax.servlet.http.HttpServlet ir šādas metodes:

doGet(HttpServletRequest req, HttpServletResponse resp) 
doPost(HttpServletRequest req, HttpServletResponse resp) 
service(HttpServletRequest req, HttpServletResponse resp) 

Servleta programmētājam ieteicams pārdefinēt "doGet" un "doPost" metodi. "service" metode atpazīst HTTP pieprasījuma tipu un pārsūta (dispatches) to kādai no "doXxx()" metodēm. Nereti "doGet()" un "doPost()" dara vienu un to pašu:

doPost(HttpServletRequest req, HttpServletResponse resp) {
    doGet(req, resp); 
}

Izņēmumi Pēc "doGet()" prototipa:

doGet(...) throws ServletException, java.io.IOException

Tos var deklarēt, ka "doGet()" viņus met. Var arī noķert un apstrādāt.

Tipiska "doGet()" implementācija

Metodē parasti jāuzstāda "Content-type" hederis, jāinicializē rakstītājs un jādrukā uz tā lapas saturs:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

  public void doGet (HttpServletRequest request, 
        HttpServletResponse response)
        throws ServletException, IOException { 
    response.setContentType("text/html; charset=windows-1257"); 
    PrintWriter out = response.getWriter(); 
    out.println("<html>\n" +
                "<head><title>Sveicināts, Tomkaķi!</title></head>\n" +
                "<body>\n" +
                "<h1>Sveicināts, Tomkaķi!</h1>\n" +
                "</body></html>");
  }
}

Ir būtisks servleta atgriežamā dokumenta MIME tips "text/html" (HTML dokuments) un kodējums "windows-1257" (latviešu burti jeb Baltic Windows). Lai par to pārliecinātos, pamēģiniet šajā piemērā ierakstīt "text/plain" (TXT dokuments), vai, teiksim, "windows-1251" (Cyrillic Windows).

Konvencija: Lai servletu un JSP kodēšana iespējami maz atšķirtos, ieteicams lietot šādus mainīgo vārdus (JSP tie ir "iebūvēti"):

HttpServletRequest request
HttpServletResponse response
PrintWriter out

Inicializācijas mainīgie

Failā web.xml, kurš glabājas WEB-INF direktorijā norādām Web aplikācijai vajadzīgos parametrus. "web.xml" faila piemērs:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <display-name>VAJAVA Examples</display-name>
    <description>
      VAJAVA Examples apraksts
    </description>

   <context-param>
      <param-name>atslega1</param-name>
      <param-value>vertiba1</param-value>
   </context-param>
   <context-param>
      <param-name>atslega2</param-name>
      <param-value>vertiba2</param-value>
   </context-param>

	<servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>HelloWorld</servlet-class>
    </servlet>
	<servlet>
        <servlet-name>InitParams</servlet-name>
        <servlet-class>InitParams</servlet-class>
    </servlet>


    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/servlet/HelloWorld</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>InitParams</servlet-name>
        <url-pattern>/servlet/InitParams</url-pattern>
    </servlet-mapping>
</web-app>

Servletā tos var nolasīt ar šādu kodu:

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class InitParams extends HttpServlet {

  public void doGet (HttpServletRequest request, 
        HttpServletResponse response)
        throws ServletException, IOException { 
    response.setContentType("text/html; charset=windows-1257"); 
    PrintWriter out = response.getWriter(); 
    ServletContext scontext = getServletContext();
    Enumeration en = scontext.getInitParameterNames();
    out.println("<table border='1'><tr><th>Key</th><th>Value</th></tr>");
	while (en.hasMoreElements()) {
        String k = (String)(en.nextElement()); 
        String v = scontext.getInitParameter(k); 
		out.println("<tr><td>"+k + "</td><td>"+ v + "</td></tr>"); 
    }
	out.println("</table>"); 
  }
}

Servletu aplikāciju uzlikšana uz servera

Uzlikšana uz servera (deployment) notiek ar sekojošām komandām, kuras izpilda aplikācijas saknes direktorijā, kurā ir fails build.xml (t.s. Ant'a skripts):

ant install      // pirmo reizi
ant reload

Web aplikāciju struktūras organizēšana

http://jakarta.apache.org/tomcat/tomcat-5.0-doc/appdev/source.html

Galvenais ieteikums - atdalīt direktorijas, kuras satur programmu izejas tekstus no direktorijām, kuras satur izpildāmo aplikāciju. Galvenie argumenti:

  • "Tīras" izejas teksta direktorijas var vieglāk administrēt, pārvietot, veidot tām rezerves kopijas, lietot versiju pārvaldības rīkus
  • Izpildāmu aplikāciju vieglāk savākt tad, ja tā ir atdalīta no izejas teksta direktorijām

Galvenās izstrādes laika direktorijas

Visas te minētās direktorijas atrodas zem projekta_vards - projekta saknes direktorijas

  • docs/ - cilvēku rakstītā dokumentācija
  • src/ - Javas programmas - t.sk. bean'i, servleti, u.c. Ja lietojam pakotnes, tad izveidojam zem "src" atbilstošu direktoriju koku.
  • web/ - HTML, JSP, bildes, u.c. Web aplikācijas resursi
  • web/WEB-INF/ - speciāli konfigurācijas faili, piemēram web.xml - šī direktorija nav redzama izpildes laikā

Automātiski var izveidoties vēl šādas direktorijas:

  • build/ - satur kopijas dažādiem aplikācijas failiem, no kuriem pēc tam veido distribūcijas arhīvu
  • javadoc/ - ģenerētā Javas klašu dokumentācija
  • dist/ - distribūcija pati

Šīs 3 direktorijas nav jāglabā ar versiju vadības sistēmu un tur nav jēgas neko rediģēt, jo visi faili tur ik pa brīdim tiks dzēsti un radīti no jauna.

Ārējās bibliotēkas

Likt ārējās bibliotēkas (piemēram, JAR'us) katras aplikācijas "source code control" sistēmā ir slikti:

  • Lielas bibliotēkas daudzos eksemplāros CVSā aizņem daudz vietas
  • Ir grūti mainīt visās aplikācijās, ja bibliotēkas versija mainās

Risinājums - iekļaut bibliotēkas distribūcijā tikai pārbūves laikā. Bibliotēku jaunākās versijas glabājas common/lib direktorijā. Daži servletu konteineri ļauj ielikt bieži izmantojamas bibliotēkas konteinera koplietošanas apgabalā. Citi JARi ir katrai aplikācijai savi.

exercise44: Aplikācijas veidošana ar Ant

Mērķis:

  • Iepazīties ar statisko Web resursu (piemēram, HTML failu) veidošanu
  • Iepazīties ar Javas aplikāciju būvēšanas rīka "Ant" iespējām
  • Pievienot bildītes servletu, kurš klientam piegādā GIF failu

Darbības īsumā:

  • Uzbūvēt (sakompilēt un saarhivēt) servletu aplikāciju dotajā direktorijā
  • Pievienot index.html jaunu linku uz servletu
  • Pievienot jaunu servletu no dotā koda - tādu, kurš atgriež konkrētu GIF bildīti

Detalizēts darbību izklāsts:

  • Izveidot pareizu direktoriju struktūru - pārkopējiet savā apakšdirektorijā exercise44 piedāvātos failus
  • Izpildiet DOS komandrindā - direktorijā "exercise44" sekojošas darbības:
    ant clean
    ant ear
    deploy
    bind
    
  • Failam index.html (no izstrādes direktorijas "web") pievienot jaunu linku - uz servletu ImageServlet. Izstrādes direktorijā "src" iekopēt apmēram šādu "ImageServlet" izejas tekstu:
    import java.io.*;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class ImageServlet extends HttpServlet { 
        public void doGet (HttpServletRequest request, 
                HttpServletResponse response)
                throws ServletException, IOException { 
    
            response.setContentType("image/gif"); 
    		ServletContext scontext = getServletContext();
    		String faila_vards = scontext.getInitParameter("bildes_fails"); 
    		OutputStream out = response.getOutputStream(); 
    
    		byte[] buffer = new byte[1024];
    		FileInputStream fis = new FileInputStream(faila_vards); 
    		int len; 
    		while ((len = fis.read(buffer)) != -1) {
    			out.write(buffer,0,len); 
    		}
    		fis.close(); 
    		out.close(); 
        }
    }
    

    Konfigurācijas failā web.xml (no izstrādes direktorijas "web/WEB-INF") izveidot jaunu atslēgas-vērtības pāri, kurā norādīts ceļš uz kādu GIF failu Jūsu datora failu sistēmā (pēc savas izvēles ierakstiet tur reāli eksistējošu failu). Sintakse failā "web.xml" ir šāda:

       <context-param>
          <param-name>atslega1</param-name>
          <param-value>vertiba1</param-value>
       </context-param>
       <context-param>
          <param-name>bildes_fails</param-name>
          <param-value>c:/direktorijas/bilde.gif</param-value>
       </context-param>
    
    Pievienot web/index.html failam savu vakardienas mājasdarbu - login.html failu un JSP lapu, kura pārbauda paroli un redirektē nereģistrētos lietotājus citur, bet reģistrētos nosūta uz index.html
  • Pārveidot JSP lapu par ekvivalentu servletu Login.java, kurš tāpat apstrādā "login.html" formu un redirektē lietotāju vai nu uz lapu "index.html", kurā var darboties tālāk, vai arī atkārtoti uz "login.html", ja tas ir nereģistrēts lietotājs
  • Izveidot jaunu - "ImageServlet", kurš no "web.xml" nolasa parametru "bildes_fails" un atbilstošo GIF failu nosūta Servleta klientam. Uzstādīt atbilstošu "Content-type: image/gif". Lietot baitu izvades plūsmu, nevis PrintWriter, lai veiktu izvadi.

exercise45: Sesijas uzturēšana

  • Pārveidot index.html par servletu Index.java, kurš pārbauda, vai ir uzstādīta sesija. Ja nav, tad redirektē lietotāju uz "login.html". Sesiju uzstāda servlets Login.java
  • Sesijas veidošanā izmantot Sesijas API

exercise46: Paroļu skatīšanās datubāzē

  • Izveidot savā Oracle shēmā tabulu "users", kurai ir divas tekstveida kolonnas "logins" un "pwd" - katra ar tipu VARCHAR(30). Šo darbību var veikt ar SQL Plus.
  • Pievienot šai tabulai dažus lietotājus ar parolēm
  • Modificēt Login.java programmu tā, lai tā skatītos datubāzē un pārbaudītu, vai login/pwd pāris tur ir.
  • Datubāzes draiveri pievienot build.xml failam kā ārēju "dependency", lai tas tiktu iekļauts EAR failā.

Lapa mainīta 2004-11-15 22:37:53