Hlavní navigace

S Javou na webovém serveru (2)

Lukáš Zapletal

Že má Tomcat budoucnost, dokazuje i to, že si jej vybraly přední IDE prostředí jako svůj engine pro JSP/Servlety - například Forte for Java 2.0 od Sun Microsystems nebo JBuilder 4.0 od společnosti Borland. Dnes se naučíme vytvářet nové servlety a konfigurovat Tomcat tak, aby vše servíroval hladce a bezpečně.

Hned ze začátku bych si dovolil malou erratu. V prvním díle jsem zapomněl uvést jednu důležitou skutečnost a to odkaz na Tomcat. Myslím, že to není vůbec nutné, ale pro klid duše ho tu raději uvedu: http://jakarta­.apache.org/tom­cat.

Nejdříve si popíšeme, jak vypadá struktura hotové webové aplikace. Nejdůležitější je adresář WEB-INF/, ve kterém se nalézá soubor web.xml. V tomto souboru (který je jak jste si jistě všimli ve formátu XML) jsou popsány všechny komponenty celé aplikace jako například servlety a bezpečnostní pravidla. Adresář WEB-INF/classes obsahuje vlastní třídy a servlety (v bytecodu). Všechny vaše knihovny či JDBC ovladače jsou pak umístěny v adresáři WEB-INF/lib. Všude jinde jsou pak vlastní html stránky a JSP skripty. V Tomcatu se všechny webové aplikace umísťují většinou do adresáře $TOMCAT_HOME/we­bapps/ – tam je také Tomcat po svém restartu hledá a automaticky vytváří jednotlivé kontexty. Pokud chcete svůj projekt mít na jiném místě, je to možné, ale musíte ručně editovat soubor server.xml

Vývoj vlastní webové aplikace ale probíhá v jiném adresáři. Pomocí utility Ant, což je obdoba makefile, se projekt zkompiluje a správně umístí do adresáře webapps/. Struktura pracovního adresáře se doporučuje:

  • etc/ – zde se udržují speciální soubory jako je web.xml. Budou nakopírovány do WEB-INF/ adresáře.
  • lib/ – adresář obsahující knihovny (JARy). Ty budou při změně nakopírovány do WEB-INF/lib/.
  • src/ – zdrojové kódy servletů a beansů.
  • web/ – vlastní web (HTML, JSP, CSS…).

S Tomcatem se dodává příklad, který naleznete v adresáři doc/tomcat-appdev/sample/. Je zde jak vlastní build skript (build.sh nebo build.bat), tak build.xml, který určuje vlastní proces sestavení. Build.xml je jakousi obdobou makefile. Popis jednotlivých parametrů tohoto souboru naleznete v dokumentaci k Antu, která se ale s Tomcatem nedodává a musíte si ji stáhnout samostatně. Rád bych však upozornil, že v příkladu z Tomcatu 3.2.1 je malá chybička, která neumožňuje spustit servlet, pokud používáte Apache. Ten se totiž nachází správně na URL http://localhos­t/myapp/servlet/He­llo (s velkým „H“) a nikoli na http://localhos­t/myapp/hello.

Po spuštění skriptu Ant nejdříve zkontroluje kde všude byly udělány změny a podle definic závislostí překompiluje a obnoví celý projekt v adresáři webapps/ (nebo kdekoli jinde, to si samozřejmě můžete nastavit). Teprve až poté můžete aplikaci otestovat. Pokud webová aplikace ještě neexistovala (v adresáři webapps/ nebyl podadresář se jménem projektu), musíte restartovat Tomcat a Apache (v tomto pořadí!), aby se projevily změny. Tomcat totiž při startu prohledá adresář webapps/ a nastaví konfiguraci automaticky. Poté vygeneruje conf soubor pro Apache, který bude požadavky na daný adresář posílat Tomcatovi.

Stejně jako Makefile má i Ant mnoho možností. Pokud spustíte skript s parametrem „javadoc“, vygeneruje ke všem beansům a servletům ant dokumentaci, pokud použijete například „dist“, vytvoří ant tzv. WAR soubor. WAR soubory (Web archive) jsou obdobou JAR souborů u appletů a aplikací. Slouží tedy k finální distribuci produktu ke koncovému uživateli (v tomto případě administrátorovi webového serveru). Ten je prostě nakopíruje do webapps/ adresáře a Tomcat po startu aplikaci rozbalí, zinicializuje a zprovozní. Výhodou WAR archívů je i to, že jim rozumí i jiné javové servery (IBM Websphere či Allaire JRun), takže případný upgrade do „první ligy“ by měl být o něco lehčí. Bližší informace naleznete v dokumentaci. A nyní si něco konečně řekneme o servletech, jak fungují a pokusíme se sesmolit nějaký ten příklad.

Servlet je komponenta určená pro web, která generuje dynamický obsah. Přeložený servlet se nahraje za pomoci Javy do webového serveru (dědí tedy všechny vlastnosti Javy) a s uživatelem komunikuje pomocí RR (request-response) paradigmata. Technicky vzato se jedná o obyčejný interface (jménem Servlet), který definuje metodu service. Tato metoda je volána při každém http požadavku na servlet. Dále je deklarována abstraktní třída HttpServlet, která implementuje tento interface a přidává výkoný kód, který se bude vykonávat, pokud metodu neimplementujeme. Metoda service rozebere dotaz a zavolá jednu z metod doGet, doPost, doPut, doDelete, doHead nebo doTrace podle typu požadavku (PUT, HEAD, TRACE a DELETE požadavky jsou specialitou protokolu HTTP verze 1.1 a příliš často se nevyužívají). Při prvním načtení servletu se zavolá metoda init, ve které si můžeme provést inicializační nastavení servletu, otevřít spojení s databází apod. Opakem je metoda destroy, která je volána, když webový server odehrává servlet z paměti. Všechny metody, které zpracovávají vstup a výstup mají v parametrech třídy ServletRequest a ServletResponse, pomocí nichž probíhá interakce mezi uživatelem. Servlety samozřejmě umí cookies (metoda HttpServletRe­quest.getCooki­es()) a i když jsou poměrně nízkoúrovňové (programátor musí dávat pozor na více vláken, protože servlet bude používat více dotazů najednou) mají přímo v sobě zabudován mocný nástroj – sessions (interface HttpSession). Takže s těmito znalostmi můžeme sestavit příklad, který vás navnadí. Pokud se chcete dozvědět víc, odkážu vás na stránky Sunu, kde je opravdu pěkná specifikace ve formátu PDF, dokumentace a nějaké ty příklady.

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

public final class Hello extends HttpServlet {

    public void init(ServletConfig config) {
        config.getServletContext()
        .log("HELLO SERVLET - initialization
");
    }

    public void doGet(HttpServletRequest request,
        HttpServletResponse response)
        throws IOException, ServletException {

        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();

        writer.println("<html>");
        writer.println("<head>");
        writer.println("<title>HELLO</title>");
        writer.println("</head>");
        writer.println("<body>HELLO " +
        "SERVLETS!</body>");
        writer.println("</html>");
    }
}

Rád bych vás ještě upozornil na jednu skutečnost. Pokud chcete servlety vyvíjet, nepoužívejte Tomcat ve spojení s Apache, protože v tomto případě byste museli Tomcat restartovat po každé změně servletu. Doporučuji Tomcat proto spouštět ve standalone režimu. Tomcat automaticky pozná, že byl servlet změněn a znovu ho načte a inicializuje. V příštím a posledním dílu tohoto mikroseriálu si pohrajeme s Java Server Pages neboli JSP.

Specifikace Servletů
Online Javadoc dokumentace

Našli jste v článku chybu?