%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% :Deployement on Server
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Nasazení na serveru} \label{Deployement}

V~následující kapitole si krátce popíšeme jak připravit webovou aplikaci pro nasazení na serveru. K~úplnému nasazení je potřeba ještě alespoň zběžně prostudovat dokumentaci serveru, jelikož rozhraní pro nasazení se u~jednotlivých serverů liší. Nasazení hotové aplikace na serveru Tomcat je popsáno v~příloze \ref{Tomcat} Nasazení na severu JBoss v~příloze \ref{JBoss}



\subsection{Struktura webové aplikace}

Kořenový adresář webové aplikace musí obsahovat dva podadresáře --- \emph{WEB-INF} a~\emph{META-INF}. Dále může obsahovat libovolné další soubory a~adresáře. Obrázek ukazuje strukturu adresáře aplikace kurzovního lístku. Kromě dvou povinných adresářů obsahuje i~soubory \emph{index.jsp} a~\emph{result.jsp}.

\begin{figure}[ht]
  \centerline{\includegraphics[height=90mm]{images/deployement_root_directory.png}}
  \caption{Kořenový adresář webové aplikace.}
\end{figure}




\subsection{Kontextová cesta aplikace}

Kontextová cesta aplikace (context path) je cesta ukazující na webovou aplikaci. Pokud chceme aplikaci nasadit na adrese \emph{http://www.piggybank.com/}, pak je kontextová cesta \emph{/} (lomítko --- cesta ke kořenovému zdroji, viz. kapitola \ref{HTTP}) V~případě, že je aplikace nasazena na \emph{http://localhost:8080/piggybank}, je kontextová cesta \emph{/piggybank}. Nastavení kontextové cesty aplikace se na každém serveru liší, je proto potřeba si přečíst dokumentaci serveru.





\subsection{WEB-INF}

Adresář \emph{WEB-INF} je zajímavý hned ze dvou důvodů. Tím prvním je, že obsahuje konfigurační soubor webové aplikace \emph{web.xml}, který je standardizovaný podle specifikace Java EE. Druhým důvodem je fakt, že adresář \emph{WEB-INF} je zvenku nepřístupný. Pokud uživatel pošle požadavek na něj, nebo na nějaký soubor, který je jeho součástí, vrátí server odpověď \texttt{404 Not Found}. Kromě toho, že to chrání konfigurační soubor i~jiná citlivá nastavení před zneužitím, to lze také využít pro ochranu některých webových stránek před přímým přístupem. Pokud například máme stránku která předpokládá, že před jejím zpracováním máme k~dispozici výsledek nějaké operace, vedlo by přímé zavolání takovéto stránky k~chybě. Pokud je ale uložena v~adresáři \emph{WEB-INF}, pak ji přímo zavolat nemůžeme. Přitom webová aplikace sama s~ní může kdykoliv pracovat a~rámci přeposlání (viz. kapitola \ref{JSP}) ji vrátit.



\subsection{Konfigurační soubor}

Konfigurační soubor pro webové aplikace se jmenuje \emph{web.xml} a~je uložen v~adresáři \emph{WEB-INF}. V~dalším textu si popíšeme některé jeho základní body. Kořenový element dokumentu se jmenuje \texttt{web-app} a~ve svých parametrech má nastavené bohaté informace o~jmenných prostorech. Ideální je nechat celý soubor vygenerovat prostředím IDE a~pak jen upravovat některá místa. Příklad ukazuje konfigurační soubor bez dalšího nastavení (pozn. hodnota atributu \texttt{schemaLocation} byla rozdělena na dva řádky, v~XML souboru ovšem musí být na jednom řádku).

\begin{Verbatim}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

</web-app>
\end{Verbatim}



\subsubsection{Nastavení servletu}

Každou webovou aplikaci v~jazyce Java řídí nějaký servlet. Tomuto servletu odpovídá XML element \texttt{servlet}, který má dva dceřiné elementy. Element \texttt{servlet-name} zavádí jméno pro tento serlvet (můžeme si ho vymyslet), element \texttt{servlet-class} obsahuje plně kvantifikovanou třídu servletu. Ta musí být součástí JVM nebo musí být v~aplikaci zahrnuta. Navíc musí tato třída být potomkem (i~nepřímým) třídy \texttt{HttpServlet} probírané v~kapitole \ref{Servlets} V~příkladu jsou doplněny informace o~servletu.

\begin{Verbatim}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  \codeHighlight{<servlet>}
  \codeHighlight{  <servlet-name>PiggyServlet</servlet-name>}
  \codeHighlight{  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>}
  \codeHighlight{</servlet>}

</web-app>
\end{Verbatim}

\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
Obyčejné JSP stránky jsou spravovány výlučně JSP kontejnerem. V~takových aplikacích v~souboru \emph{web.xml} neuvádíme žádný servlet.
}}



\subsubsection{Přidělení adresy servletu}

Aby servlet kontejner poznal, které požadavky posílat na servlet, musíme každému jednoznačně určit adresu. Jelikož adresa serveru je jednoznačně určena, stačí se zabývat pouze cestou v~adrese. Ta se servletu přiřadí v~XML elementu \texttt{servlet-mapping}. V~jeho dceřiném elementu \texttt{servlet-name} uvedeme jméno servletu, kterému přiřazujeme adresu (pozn. musí se shodovat se jménem výše). V~elementu \texttt{url-pattern} pak uvedeme cestu kterou chceme přiřadit k~servletu.

\begin{Verbatim}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <servlet>
    <servlet-name>PiggyServlet</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  </servlet>

  \codeHighlight{<servlet-mapping>}
  \codeHighlight{  <servlet-name>PiggyServlet</servlet-name>}
  \codeHighlight{  <url-pattern>/</url-pattern>}
  \codeHighlight{</servlet-mapping>}

</web-app>
\end{Verbatim}

Příklad ukazuje, jak servletu \texttt{PiggyServlet} přiřadit cestu \emph{/}, tedy na něj směrovat všechny požadavky. Pokud bychom na tomto místě uvedli cestu \emph{/servlet}, dostával by \texttt{PiggyServlet} pouze požadavky na zdroje začínající cestou \emph{/servlet}. Zde je potřeba dát pozor. Zadávaná cesta je absolutní, ale napojuje se až za kontextovou cestu aplikace. Pokud by aplikace měla kontextovou cestu \emph{/piggybank} a~cestu k~servletu bychom nastavili jako \emph{/servlet}, budou se na něj posílat všechny požadavku, u~kterých adresa začíná cestou \emph{/piggybank/servlet} (nikoliv \emph{/servlet}). Toto chování je intuitivní, i~když odporuje definici absolutních adres.



\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
Přiřazení cesty jedinému servletu se může zdát na první pohled zbytečné. Tento zobecněný přístup se ale hodí pokud si chceme ve webové aplikaci (většinou webové službě) ponechat možnost implicitního chování serveru. Pokud bychom opravdu každý požadavek předali našemu servletu, museli bychom ručně naprogramovat vracení HTML stránek, obrázků a~ostatních souborů, které jsou součástí aplikace. To by bylo velmi složité a~přitom to už server umí. 
\\
\\
Ve frameworku Struts se proto používá mapování \emph{*.do}, které značí, že servletu se předají pouze požadavky na~adresu končící na \emph{.do}. Pokud bude uživatel požadovat obrázek (adresa končí například \emph{.png}), bude tento požadavek zpracován servlet kontejnerem, který obrázek najde, načte a~vrátí. Obdobné je i~použití v~RESTful webových službách.
}}





\subsubsection{Implicitní domovská stránka}

Protokol HTTP umožňuje uživateli poslat požadavek na kořenový zdroj aplikace (v~cestě je pouze znak \texttt{/}). Ve webových aplikacích se většinou jedná o~domovskou stránku, často pojmenovanou \texttt{index.html} (resp. \emph{index.jsp}). Aby servlet kontejner věděl, jak se domovská stránka jmenuje, musíme mu to nastavit v~konfiguračním souboru. XML element určený pro tento účel se jmenuje \texttt{welcome-file-list}. Obsahuje obecně více dceřiných elementů \texttt{welcome-file}. V~těch je uložen samotný název domovské stránky. Příklad ukazuje, jak nastavit jméno domovské stránky na \emph{main.jsp}.


\begin{Verbatim}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <servlet>
    <servlet-name>PiggyServlet</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>PiggyServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  \codeHighlight{<welcome-file-list>}
  \codeHighlight{  <welcome-file>main.jsp</welcome-file>}
  \codeHighlight{</welcome-file-list>}

</web-app>
\end{Verbatim}

Servlet kontejner pak při požadavku na kořenový zdroj prohledá konfigurační soubor a~přečte si jméno domovské stránky. Následně prohledá kořenový adresář aplikace pro soubor se stejným jménem. Jestliže ho najde, zpracuje ho a~vrátí odpověď. V~opačném případě vrací odpověď \texttt{404 Not Found}.


\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
Elementů \texttt{welcome-file} může být i~více. To využijeme ve chvíli, kdy si nejsme jistí finálním jménem domovské stránky. Nemusíme například vědět, jestli budeme ve výsledku pracovat s~obyčejnými HTML stránkami, nebo nasadíme technologii JSP (nebo jinou). Konfigurační soubor je pak obvykle místo, na které programátoři zapomenou. Výsledkem pak může být zdlouhavé ladění zdánlivě nepochopitelné chyby, kdy server odmítá vrátit domovskou stránku aplikace. Proto je někdy lepší nastavit potencionálních jmen v~konfiguračním souboru více.
}}




\subsection{META-INF}

Adresář \emph{META-INF} je určený pro konfigurační soubory aplikace z~pohledu jednotlivých serverů. Specifikace Java EE neuvádí, jak například zadávat kontextovou cestu nebo definovat databázové zdroje. Každého server tyto nastavení řeší po svém, většinou se však jedná o~nějaký XML konfigurační soubor, který bude uložen právě v~\emph{META-INF}.




\subsection{Knihovny}

Knihovny, které v~aplikaci chceme používat přidáme jednoduše. Stačí nahrát všechny jejich \emph{jar} soubory do adresáře \emph{lib}, který je součástí adresáře \emph{WEB-INF}. Server si je tam sám najde a~načte do paměti.



\subsection{Soubor WAR}

Aplikaci musíme před nasazením zabalit do archivu WAR (Web Archive --- přípona souboru je \emph{.war}). Jedná se o~stejný formát jako archiv JAR. Rozdíl v~názvu přípony je čistě z~důvodu, aby bylo na první pohled poznat, že se jedná o~webovou aplikaci. Archiv WAR lze tedy vyrobit pomocí příkazu \texttt{jar}. Následující příklad ukazuje, jak v~příkazové řádce operačního systému zabalit aplikaci do archivu WAR. Předpokládejme, že se nacházíme v~kořenovém adresáři aplikace Piggy Bank. Pak stačí zavolat:

\begin{Verbatim}
> jar -cvf piggybank.war *
\end{Verbatim}

Výsledkem bude soubor \emph{piggybank.war}, který můžeme následně nasadit na serveru. Konkrétní postup, jak to udělat se na každém serveru liší a~je popsán v~dodatcích \ref{Tomcat} a~\ref{JBoss}


