%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% :JSP
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Java Server Pages} \label{JSP}

Programování velkých webových stránek pomocí servletů se může snadno stát velice obtížné a~nepřehledné. Kvůli tomu byla vyvinuta nová technologie s~názvem \emph{Java Server Pages}, která má za úkol programování dynamických webových stránek zjednodušit. V~podstatě se jedná o~šablony pro generování servletů. Každá JSP stránka kombinuje HTML kód s~kódem v~jazyce Java. Na rozdíl od běžných (statických) HTML stránek však server neposílá klientovi JSP stránku v~podobě zdrojového kódu, ale dochází k~její interpretaci na serveru. Výsledkem je čistý HTML kód (podobně jako by ji sestavil servlet), který se následně klientovi vrátí v~odpovědi serveru.



\subsection{JSP Kontejner}

Pro technologii JSP a~všechny technologie z~ní odvozené je potřeba, aby měl server vestavěný tzv. \emph{JSP kontejner} (JSP container). To je pouze vylepšená verze klasického servlet kontejneru. Servery Tomcat a~JBoss ho mají zabudovaný. Je ovšem důležité si uvědomit, že bez JSP kontejneru nedokáže server JSP stránky interpretovat.



\subsection{JSP Syntaxe}

Syntaxe JSP stránek je poměrně jednoduchá. Každá stránka se sestává z~běžného HTML kódu doplněného zdrojovým kódem v~jazyce Java. Aby servlet kontejner rozeznal obyčejný text od kódu, který se má interpretovat, bylo nutné do syntaxe ještě dodat oddělovací značky. Navíc JSP syntaxe zahrnuje i~tzv. \emph{direktivy stránky}, které obsahují dodatečné informace o~zdrojovém kódu.




\subsection{Kurzovní lístek v~JSP}

V~této kapitole budeme v~dalším textu řešit příklad kurzovního lístku. Přestože povaha JSP umožňuje zapsat celý zdrojový kód přímo do JSP stránky, budeme se snažit o~co nejdůslednější oddělení logiky aplikace od prezentace. Proto předpokládejme, že máme k~dispozici již naprogramovaný soubor tříd z~projektu \emph{Exchange List} (na přiloženém CD). Z~nich budeme využívat dvě třídy --- \texttt{ExchangeList}, která slouží jako fasáda pro komunikaci s~logickou vrstvou (návrhový vzor Fasáda je popsán v~\cite{Navrhove vzory}). Další třídou bude výčtový typ \texttt{Currency}. 

Pro celou (zjednodušenou) aplikaci budeme potřebovat dvě JSP stránky. Nazvěme je \emph{index.jsp} a~\emph{result.jsp}. Stránka \emph{index.jsp} bude obsahovat formulář pro zadání částky a~vstupní a~výstupní měny, stránka \emph{result.jsp} pak výsledek převodu. Jako první vytvoříme stránku \emph{index.jsp}. Zdrojový kód obou stránek spolu s~konfiguračními soubory naleznete na přiloženém CD v~adresáři \emph{Exchange List JSP/web}.




\subsection{Direktivy stránky}

Direktivy stránky jsou speciální konstrukce, kterými začínají JSP stránky. Je to podobné, jako u~běžného programování v~jazyce Java, kde zdrojový kód tříd začíná konstrukcemi \texttt{package} a~\texttt{import}. Direktivy stránky radí JSP kontejneru, jak se stránkou pracovat. Obecná syntaxe direktivy je:

\begin{Verbatim}
<\%@ page [název="hodnota"] \%>
\end{Verbatim}

Položka \texttt{název} obsahuje název direktivy, položka \texttt{hodnota} pak její hodnotu. Princip je stejný, jako u~atributů elementu v~jazyce XML. Asi nejčastěji používanou direktivou je direktiva \texttt{import}, která má stejný význam, jako konstrukce \texttt{import} ve zdrojovém kódu jazyka Java. Příklad ukazuje, jak na JSP stránce zpřístupnit třídy \emph{Exchange List} a~\texttt{Currency}.

\begin{Verbatim}
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>
\end{Verbatim}

Není v~tom nic těžkého, vše funguje jako v~normálním programování v~Javě. Existují ještě další direktivy, ale nejsou zase až tak běžně používané, proto se tu jimi nebudeme zabývat. Podrobný seznam s~vysvětlením můžete nalézt v~\cite{Java Server Pages}.




\subsection{Deklarace typu dokumentu}

Po direktivách stránky následuje deklarace typu HTML dokumentu. Všechny tři možné typy jsou popsány v~\cite{HTML Document Types}. Vybrat si můžeme zcela volně, stačí pouze dodržovat při psaní kódu jejich pravidla.  V~příkladu použijeme typ dokumentu \emph{loose} (volný).

\begin{Verbatim}
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

\codeHighlight{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"}
\codeHighlight{    "http://www.w3.org/TR/html4/loose.dtd">}
\end{Verbatim}

Ohledně deklarace typu je třeba si uvědomit, se vztahuje až na výslednou (přeloženou) HTML stránku. Neplatí tedy, že JSP stránka je validní HTML. Už jenom kvůli direktivám ani být nemůže. Naštěstí HTML elementy na stránce jsou pevně v~rukou programátora, takže není těžké vybrat si typ dokumentu a~držet se ho.






\subsection{Kód v~HTML}

Po té, co máme vybraný typ dokumentu, můžeme začít psát samotnou stránku. Jak jsme si řekli dříve, JSP stránka se skládá z~HTML kódu a~zdrojového kódu v~jazyce Java. Na stránce \emph{index.jsp} budeme potřebovat vytvořit formulář pro zadávání údajů pro přepočet měn. Prozatím ho zapíšeme kompletně jako HTML kód, jak uvádí příklad.

\begin{Verbatim}
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

\codeHighlight{<html>}
\codeHighlight{    <head>}
\codeHighlight{        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">}
\codeHighlight{        <title>Kurzovní lístek</title>}
\codeHighlight{    </head>}
\codeHighlight{    <body>}
\codeHighlight{        <h1>Kurzovní lístek</h1>}
\codeHighlight{        <form method="GET" action="result.jsp">}
\codeHighlight{            <input type="text" name="amount">}
\codeHighlight{            <select name="from">}
\codeHighlight{            </select>}
\codeHighlight{            <select name="to">}
\codeHighlight{            </select>}
\codeHighlight{            <input type="submit" value="Spočítat">}
\codeHighlight{        </form>}
\codeHighlight{    </body>}
\codeHighlight{</html>}
\end{Verbatim} 





\subsection{Kód v jazyce Java}

Hlavním důvodem proč se zabýváme JSP stránkami je jejich dynamický obsah. U~námi vytvořeného formuláře nám chybí jedna zásadní věc --- nabídka dostupných měn. Samozřejmě by ji v~takto jednoduché aplikaci bylo možné napevno zabudovat do HTML kódu, ale jak jistě chápete, jde nám o~sofistikovanější řešení. Tím je vložený zdrojový kód v~jazyce Java, který se na serveru přeloží a~vytáhne si seznam měn přímo z~třídy modelu \texttt{ExchangeList}. Pokud později nějakou měnu přidáme, nebudeme si muset pamatovat, že je potřeba ještě změnit nabídku v~HTML kódu. Kód v~Javě je vždy od ostatního textu (včetně HTML kódu) oddělen sekcemi \texttt{$<$\%} a~\texttt{\%$>$}. Veškerý text mezi těmito oddělovači je interpretován pomocí JVM. V~příkladu doplníme získání pole všech měn z~třídy modelu \texttt{ExchangeList}. Jak brzy uvidíte, budeme ho potřebovat hned dvakrát, proto si ho uložíme do proměnné \texttt{currencies}.

\begin{Verbatim}
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kurzovní lístek</title>
    </head>
\codeHighlight{    <\%}
\codeHighlight{        ExchangeList exchange = new ExchangeList();}
\codeHighlight{        Currency[] currencies = exchange.getAvailableCurrencies();}
\codeHighlight{    \%>}
    <body>
        <h1>Kurzovní lístek</h1>
        <form method="GET" action="result.jsp">
            <input type="text" name="amount">
            <select name="from">
            </select>
            <select name="to">
            </select>
            <input type="submit" value="Spočítat">
        </form>
    </body>
</html>
\end{Verbatim}

Není důležité, kde přesně na JSP stránce zdrojový kód zapíšeme. Dobré místo je mezi elementy \texttt{head} a~\texttt{body}. Element \texttt{head} zpravidla neobsahuje pro programátora příliš zajímavé informace, zatímco element \texttt{body} ano. Napojení zdrojového kódu právě na \texttt{body} tak vytvoří souvislý blok zajímavého kódu, který si navíc zachovává přehlednost.




\subsection{Vestavěné objekty}

Ve zdrojovém kódu jazyka Java na JSP stránce můžeme používat vestavěné objekty. Konkrétně se jedná o~objekty \texttt{out} (typ \texttt{OutputStream}, představuje výstupní proud), \texttt{request} (typ \texttt{HttpServletRequest}, stejný jako v~kapitole \ref{Servlets}) a~některé další. 




\subsection{Vytisknutí hodnoty proměnné}

Prozatím jsme výčet všech dostupných měn uložili pouze do proměnné. Zbývá hodnotu této proměnné vytisknout do HTML stránky.  V~příkladu doplníme nabídku o~výčet dostupných měn tak, že je v~cyklu vytiskneme uvnitř HTML elementu \texttt{select}. Jelikož podle HTML musí být každá položka výčtu uvnitř elementu \texttt{option}, vytiskneme kolem hodnoty i~otevírací a~uzavírací tag tohoto elementu. Všimněte si, že to celé musíme udělat dvakrát --- jednou pro vstupní a~podruhé pro výstupní měnu.


\begin{Verbatim}
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kurzovní lístek</title>
    </head>
    <\%
        ExchangeList exchange = new ExchangeList();
        Currency[] currencies = exchange.getAvailableCurrencies();
    \%>
    <body>
        <h1>Kurzovní lístek</h1>
        <form method="GET" action="result.jsp">
            <input type="text" name="amount">
            <select name="from">
\codeHighlight{                <\%}
\codeHighlight{                    for (Currency currency : currencies) \{}
\codeHighlight{                        out.println("<option>" + currency + "</option>");}
\codeHighlight{                    \}}
\codeHighlight{                \%>}
            </select>
            <select name="to">
\codeHighlight{                <\%}
\codeHighlight{                    for (Currency currency : currencies) \{}
\codeHighlight{                        out.println("<option>" + currency + "</option>");}
\codeHighlight{                    \}}
\codeHighlight{                \%>}
            </select>
            <input type="submit" value="Spočítat">
        </form>
    </body>
</html>
\end{Verbatim}





\subsection{Získání query parametrů požadavku}

Stránku \emph{index.jsp} máme hotovou. Až bude aplikace hotová, vybere si uživatel vstupní~výstupní měnu, zadá částku a~klikne na tlačítko \emph{Spočítat}. HTML formulář je nastaven tak, že prohlížeč po kliknutí na odesílací tlačítko sestaví HTTP požadavek na adresu uvedenou v~atributu \texttt{action} a~hodnoty vyplněné do formuláře připojí jako HTTP query. Na stránce \emph{result.jsp}, kterou naprogramujeme za chvíli, si query parametry můžeme přečíst skrz vestavěný objekt \texttt{request} pomocí metody \texttt{getParameter}. Ta bere jeden argument a~to název query parametru. Jeho hodnotu vrací jako řetězec. Použití v~příkladu si ukážeme za chvíli.




\subsection{Stránka result.jsp}

Stránku \emph{result.jsp} vytvoříme obdobným postupem jako stránku \emph{index.jsp}. Ve zdrojovém kódu z~vestavěného objektu \texttt{request} vytáhneme query parametry \texttt{amount}, \texttt{from} a~\texttt{to} a~z~nich pak spočítáme částku ve výstupní měně. Tuto částku prozatím uložíme do proměnné \texttt{result}.

\begin{Verbatim}
<\%@ page contentType="text/html" pageEncoding="UTF-8" \%>
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kurzovní lístek</title>
    </head>
    <\%
        \codeHighlight{ExchangeList exchange = new ExchangeList();}
        \codeHighlight{double amount = 0;}
        \codeHighlight{String from = null;}
        \codeHighlight{String to = null;}
        \codeHighlight{double result = 0;}

        try \{
            \codeHighlight{amount = Double.parseDouble(request.getParameter("amount"));}
            \codeHighlight{from = request.getParameter("from");}
            \codeHighlight{to = request.getParameter("to");}

            \codeHighlight{result = exchange.calculate(amount, from, to);}
        \}
        catch (NumberFormatException ex) \{
            ex.printStackTrace();
        \}
        catch (IllegalArgumentException ex) \{
            ex.printStackTrace();
        \}

    \%>
    <body>
    </body>
</html>
\end{Verbatim}




\subsection{Alternativní vytisknutí proměnné nebo výrazu}

K~vytisknutí hodnoty proměnné není nutné používat vestavěný objekt \texttt{out}. Pokud chceme vytisknout hodnotu jednoduché proměnné (nikoliv pole nebo kolekce), můžeme použít kód ohraničený sekvencemi \texttt{$<$\%$=$} a~\texttt{\%$>$}. Mezi nimi musí následovat název proměnné nebo výraz v~jazyce Java, který vrátí hodnotu. Ani název proměnné, ani výraz nesmí být ukončen středníkem. Příklad ukazuje, jak na stránce \emph{result.jsp} v~části \texttt{body} vytisknout postupně hodnoty všech čtyřech proměnných --- \texttt{amount}, \texttt{from}, \texttt{to} a~\texttt{result}.

\begin{Verbatim}
<\%@ page contentType="text/html" pageEncoding="UTF-8" \%>
<\%@ page import="netukar.exchange.Currency" \%>
<\%@ page import="netukar.exchange.ExchangeList" \%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kurzovní lístek</title>
    </head>
    <\%
        ExchangeList exchange = new ExchangeList();
        double amount = 0;
        String from = null;
        String to = null;
        double result = 0;

        try \{
            amount = Double.parseDouble(request.getParameter("amount"));
            from = request.getParameter("from");
            to = request.getParameter("to");

            result = exchange.calculate(amount, from, to);
        \}
        catch (NumberFormatException ex) \{
            ex.printStackTrace();
        \}
        catch (IllegalArgumentException ex) \{
            ex.printStackTrace();
        \}

    \%>
    <body>
\codeHighlight{        <\%= amount \%> <\%= from \%> je podle kurzovního lístku: <br>}
\codeHighlight{        <\%= exchange.format(result) \%> <\%= to \%>}
    </body>
</html>
\end{Verbatim}




\subsection{Překlad JSP na servlet}

Jak již bylo řečeno dříve, JSP stránky se překládají na servlety. Nejprve se vybuduje kostra třídy \texttt{HttpServlet} s~metodou \texttt{doGet} s~předgenerovaným tělem. Příklad ukazuje, jak vypadá kostra generovaného servletu.

\begin{Verbatim}
public class GeneratedServlet extends HttpServlet \{

    @Override
    protected void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
            throws ServletException, IOException \{

        PrintWriter out = response.getWriter();
        try \{

        \} finally \{
            out.close();
        \}
    \}

\}
\end{Verbatim}

Všechen další kód se bude zapisovat do bloku \texttt{try--finally}, který vidíte v~příkladu. Z~toho je hned patrný důvod existence vestavěných objektů \texttt{out}, \texttt{request} a~\texttt{response}. Jakmile je tato kostra vygenerována, začne samotný překlad. Při tom se JSP stránka prochází shora dolů, a~platí pro něj následující pravidla:

\begin{itemize}
\item Direktiva stránky \texttt{import} se převede na konstrukci \texttt{import}, která se pak předsadí deklaraci třídy servletu.

\item Všechen HTML text a~všechen obyčejný text je tisknut pomocí objektu \texttt{out} jeho metodou \texttt{println}.

\item Všechen zdrojový kód v~jazyce Java je přímo vložen do těla servletu.

\item Všechen kód ohraničený konstrukcemi \texttt{$<$\%$=$} a~\texttt{\%$>$} je vložen do volání metody \texttt{out.println}. Poté je volání této metody vloženo do těla servletu. Z~toho je patrné, proč názvy proměnných nebo výrazy uvnitř konstrukce \texttt{$<$\%$=$ \%$>$} nesmí být ukončeny středníkem.
\end{itemize}

Celý vygenerovaný servlet má velký počet řádků, proto si v~příkladu ukážeme pouze jeho část. Bude se jednat o~servlet ke stránce \emph{result.jsp}. Na místech označených \texttt{...} byl kód z~důvodu přehlednosti a~úspory místa vypuštěn.

\begin{Verbatim}
\codeHighlight{import netukar.exchange.Currency;}
\codeHighlight{import netukar.exchange.ExchangeList;}
\codeHighlight{...}

public class GeneratedServlet extends HttpServlet \{

    @Override
    protected void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
            throws ServletException, IOException \{

        PrintWriter out = response.getWriter();
        try \{
            \codeHighlight{...}
            \codeHighlight{out.println("<title>Kurzovní lístek</title>");}
            \codeHighlight{...}
            \codeHighlight{amount = Double.parseDouble(request.getParameter("amount"));}
            \codeHighlight{from = request.getParameter("from");}
            \codeHighlight{...}
            \codeHighlight{out.println(exchange.format(result));}
            \codeHighlight{...}
        \} finally \{
            out.close();
        \}
    \}

\}
\end{Verbatim}





\subsection{Cyklus JSP stránky}

Cyklus JSP stránky začíná okamžikem, kdy uživatel pošle HTTP požadavek na server. Běžící JSP kontejner požadavek zachytí a~přečte si cestu k~webové stránce, kterou žádáme. Podle této cesty vybere JSP stránku a~přeloží ji na servlet. Vzniklý servlet pak interpretuje a~do výstupního proudu průběžně tiskne HTML kód. Jakmile je HTML kód celý, proud uzavře a~server vrací klientovi odpověď s~přiloženým HTML kódem. Tím cyklus končí. Klient si pak kód například zobrazí ve webovém prohlížeči. Cyklus je vidět na obrázku \ref{JSP Cycle Figure}

Ukažme si ještě, jak vypadá HTTP požadavek na JSP stránku a~jak vypadá vrácená odpověď.

\begin{Verbatim}
GET /index.jsp HTTP/1.1
Host: www.example.com
Accept: text/html

\end{Verbatim}

\begin{Verbatim}
HTTP/1.1 200 OK
Content-Type: text/html

<html>
  <head>
    <title>Kurzovní lístek</title>
    ...
  </head>
  <body>
    ...
  </body>
</html>

\end{Verbatim}

\begin{figure}[ht]
  \centerline{\includegraphics[height=70mm]{images/jsp_cycle.png}}
  \caption{Cyklus požadavku a~odpovědi v~JSP.}
  \label{JSP Cycle Figure}
\end{figure}



\subsection{Rozsahy objektů na serveru}

Téměř každá webová aplikace která nabízí interaktivitu s~uživatelem obsahuje objekty patřící právě k~tomuto uživateli. Vzniká problém, kdy má objekt vzniknout a~kdy ho již nepotřebujeme. Teorie JSP stránek nabízí tři tzv. rozsahy platnosti objektu, tedy dobu po kterou je objekt uchováván v~paměti.

\subsubsection{Rozsah stránky}

Rozsah stránky značí, že objekt je přístupný pouze v~rámci jedné JSP stránky. Jakmile je stránka přeložena a~vrácena klientovi, takovéto objekty jsou předány garbage collectoru. Rozsah stránky neumožňuje řešit některé problémy, pro svou jednoduchost a~nenáročnost na režii by však měl být brát v~potaz vždy jako první.

\subsubsection{Rozsah požadavku}

Rozsah požadavku je časový úsek vzniklý přijetím HTTP požadavku na serveru a~končící zasláním HTTP odpovědi. Jedná se o~rozsah plně odpovídající návrhu HTTP. Objekty spojené s~tímto rozsahem jsou přenechány garbage collectoru ihned poté, co je odpověď odeslána klientovi. Pokud na stránce nepoužijeme konstrukci pro přeposlání, má tento rozsah stejný efekt jako rozsah stránky.

\subsubsection{Rozsah sezení}

\emph{Sezení} (session) je doba začínající prvním zasláním HTTP požadavku na server a~končící uzavřením webového prohlížeče nebo vypršením časového limitu (nastaveného na serveru -- tzv. session timeout, většinou okolo 20 minut). Všechny objekty vytvořené během sezení zůstávají uloženy v~paměti a~jsou jednoznačně přiřazeny k~sezení. Zároveň sezení je jednoznačně přiřazeno ke klientovi. To umožňuje udržovat informaci o~stavu komunikace mezi serverem a~klientem (pozn. tento koncept porušuje pravidlo bezestavovosti protokolu HTTP, v~praxi se však jeví jako užitečný a~je velmi často využíván). Máme například možnost vytvořit pro každého klienta objekt v~podobě nákupního košíku a~ukládat do něj zboží. Jednoznačné přiřazení ke klientovi za nás zajišťuje JSP kontejner, není tedy potřeba nic doprogramovávat. Navíc jakmile sezení vyprší, jsou všechny objekty v~něm vytvořené uvolněny pro smazání garbage collectorem.


\subsubsection{Rozsah aplikace}

Rozsah aplikace vzniká spuštěním webové aplikace a~zaniká jejím ukončením. Jedná se tedy o~rozsah jaký známe z~obyčejných desktopových aplikací v~jazyce Java s~tím že reference na objekty vzniklé v~tomto rozsahu se uchovává po celý běh aplikace. Tento koncept může být někdy výhodný, narážíme ale na to, že vytvořené objekty zabírají místo v~paměti i~dlouho potom co jejich funkcionalita skončila (např. zákazník si objednal zboží a~jeho nákupní košík stále zůstává v~paměti). Když si uvědomíme, že webové aplikace předpokládají obecně velké množství klientů a~také že jsou navrženy zpravidla tak, aby běžely bez přestání řádově v~týdnech, vzniká zde zásadní problém s~možným přeplněním paměti. Proto je potřeba k~rozsahu aplikace přistupovat s~obezřetností a~pokud je to možné, zvolit raději rozsah sezení.





\subsection{Knihovna tagů JSP}

JSP stránky přinášejí oproti programování na úrovni servletů značné zjednodušení. Jedním z~nich je i~možnost používat předpřipravené JSP tagy. Ty mají podobu XML tagů a~píšeme je do neinterpretované části JSP stránky, tedy takové, která není uzavřena do bloku \texttt{$<$\%} a~\texttt{\%$>$}. JSP tagy představují zkratky za některé často používané konstrukce a~dají se doporučit pro zpřehlednění kódu a~šetření práce. Nemusíme je nikde deklarovat, všechny jsou od začátku přístupné. Pro JSP kontejner představují JSP tagy pouze příkazy. Je proto možné je uzavírat už v~otevíracím tagu pomocí lomítka uvedeného na konci (např. \texttt{$<$jsp:useBean /$>$}) a~to bez ohledu na deklaraci typu dokumentu, Ve výsledném HTML se totiž vůbec neobjeví, validita tak není ohrožena. Za poznámku také stojí, že všechny JSP tagy začínají prefixem \texttt{jsp:}. 



\subsubsection{JSP tag useBean}

Velmi užitečným tagem je \texttt{jsp:useBean}, který nám připraví objekt typu JavaBean. Tento objekt je identifikován pomocí své třídy a~identifikačního řetězce, který mu přidělíme. Přitom pokud objekt ještě neexistuje, založí se nový. Pokud ale již existoval, zpřístupní se přes odkaz. To je velmi výhodné. Pokud máme takovýto objekt deklarovaný v~rozsahu sezení, umožňuje nám to s~ním pracovat na různých JSP stránkách. Pokud je objekt v~rozsahu požadavku, získáme alespoň zpřehlednění kódu a~odstranění zbytečného kódu v~jazyce Java. Tag \texttt{jsp:useBean} má tři atributy. Atribut \texttt{id} udává zmíněný identifikační řetězec, atribut \texttt{class} zase třídu tohoto JavaBeanu. Atribut \texttt{scope} udává rozsah objektu. Implicitní rozsah je rozsah stránky (hodnota \texttt{page}). Následující příklad ukazuje, jak deklarovat objekt typu \texttt{Exchange} (viz. projekt Exchange List) v~rozsahu \texttt{session}.

\begin{Verbatim}
<jsp:useBean id="exchange" 
             class="netukar.exchange.Exchange"
             scope="session" />
\end{Verbatim}

Následující konstrukci uvedeme právě jednou na každé stránce, na které chceme pracovat s~přepočtem měny. Při prvním použití nám JSP kontejner vytvoří instanci třídy \texttt{Exchange} z~balíčku \texttt{netukar.exchange} pomocí konstruktoru bez parametrů. V~dalších případech pak tento již vytvořený objekt najde a~zpřístupní na stránce. Přitom je dodržen princip sezení, takže klientovi je přidělen vždy správný objekt. Pro zpřehlednění situace budeme v~dalším výkladu JSP tagů o~atributech JavaBeanu hovořit jako o~vlastnostech (properties).



\subsubsection{JSP tag setProperty}

Pokud použijeme tag \texttt{jsp:useBean} zajisté taky budeme potřebovat manipulovat s~vlastnostmi získaného objektu. To zařídíme pomocí JSP tagu \texttt{jsp:setProperty}, který má tři atributy. Atribut \texttt{name} odkazuje na identifikační řetězec požadovaného objektu. Atribut \texttt{property} udává název vlastnosti JavaBeanu, kterou chceme nastavovat. Poslední, atribut \texttt{value} pak udává hodnotu, na kterou chceme vlastnost nastavit. Hodnota se převede na správný datový typ automaticky. V~příkladu nastavíme vlastnost \texttt{amount} na hodnotu \texttt{100} a~vlastnost \texttt{from} na hodnotu \texttt{CZK}.

\begin{Verbatim}
<jsp:useBean id="exchange" 
             class="netukar.exchange.Exchange"
             scope="session" />

\codeHighlight{<jsp:setProperty name="exchange"}
\codeHighlight{                 property="amount"}
\codeHighlight{                 value="100" />}

\codeHighlight{<jsp:setProperty name="exchange"}
\codeHighlight{                 property="from"}
\codeHighlight{                 value="CZK" />}
\end{Verbatim}

\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
JSP kontejner pro nastavení vlastnosti \texttt{amount} zavolá na JavaBeanu metodu \texttt{setAmount} a~jako parametr jí předá hodnotu vlastnosti. Hodnoty vlastností se automaticky převádí z~řetězce na typ parametru metodu. Pokud převod nelze provést, dojde k~výjimce.
}}



\subsubsection{JSP tag getProperty}

Tak jako můžeme hodnotu vlastnosti nastavit ji můžeme také přečíst. K~tomu slouží JSP tag \texttt{jsp:getProperty}. Atribut tagu \texttt{name} odkazuje na identifikátor JavaBeanu, atribut \texttt{property} na název vlastnosti. Výsledkem tagu je vytištění získané hodnoty, tento tag se tedy používá většinou uvnitř nějakého HTML elementu. V~příkladu přečteme vlastnosti \texttt{amount} a~\texttt{from} na jiné stránce, než na které jsme je nastavovali. Jejich hodnoty bude vytištěny.

\begin{Verbatim}
<jsp:useBean id="exchange" 
             class="netukar.exchange.Exchange"
             scope="session" />

<html>
  <body>
    <span>Částka 
        \codeHighlight{<jsp:getProperty name="exchange"}
        \codeHighlight{                 property="amount" />}
        \codeHighlight{<jsp:getProperty name="exchange"}
        \codeHighlight{                 property="from" />}
        je podle kurzovního lístku...
    </span>
  </body>
</html>
\end{Verbatim}




\subsection{Přesměrování a~přeposlání}

Ve webové aplikaci je někdy zapotřebí vrátit uživateli jinou stránku, něž o~kterou žádal. Typickým příkladem je, pokud se aplikace nebo její část přestěhovala na jiný server. Časté využití je však i~ve formě kdy po vzoru objektově orientovaného programování delegujeme výsledek zpracování na jinou stránku. JSP proto nabízejí dva přístupy, jak toto vyřešit.


\subsubsection{Přesměrování}

Přesměrování (redirect) uživatele probíhá podle pravidel protokolu HTTP. Uživateli na jeho požadavek vrátíte HTTP odpověď \texttt{301 Moved Permanently} spolu s~vyplněnou položkou hlavičky \texttt{Location}. Zde bude jako hodnota uvedena adresu, na kterou ho chceme přesměrovat. Uživatel si sám rozhodne, jestli chce novou adresu navštívit. Moderní webové prohlížeče to za něj udělají automaticky a~pošlou \texttt{GET} požadavek na novou adresu. Uživateli ve webovém prohlížeči problikne pole na zadávání URL adres a~nastaví se na novou hodnotu. Přesměrování na úrovni JSP kódu dosáhnete následující konstrukcí uvedenou kdekoliv v~interpretované části stránky:

\begin{Verbatim}
response.sendRedirect("/other.jsp");
\end{Verbatim}


\subsubsection{Přeposlání}

Přeposlání (forward) je mechanismus, kterým převedeme obdržený HTTP požadavek na jinou adresu. Na rozdíl od přesměrování, probíhá přeposlání celé výhradně na straně serveru. JSP kontejner jednoduše přepošle HTTP požadavek sám sobě, pouze s~novou URL adresou. Klient se o~případném přeposílání vůbec nedozví. Přeposlání na úrovni JSP kódu můžeme dosáhnout dvěma způsoby. Prvním je zavolání následující konstrukce kdekoliv v~interpretované části JSP stránky:

\begin{Verbatim}
request.getRequestDispatcher("/other.jsp").forward(request, response);
\end{Verbatim}

Hodnotami parametrů metody \texttt{forward} jsou zde vestavěné objekty typu \texttt{HttpServletRequest} a~\texttt{HttpServletResponse}. Toto řešení lze použít i~na úrovni servletů. Pokud vám přijde celá konstrukce složitá, je možné použít zkratku v~podobě JSP tagu \texttt{forward} s~atributem \texttt{page}. Nezapomeňte, že JSP tagy se píší do neinterpretované části JSP stránky. Alternativní zápis přeposlání vypadá takto:

\begin{Verbatim}
<jsp:forward page="/other.jsp" />
\end{Verbatim}




\subsection{Předávání parametrů mezi stránkami}

Mezi stránkami je možné přenášet data uložená v~JavaBeanech. Pokud použijeme mechanismus přeposlání, je často potřeba předat pouze hodnoty nějakých parametrů. Přitom zavedení JavaBeanů s~jedním atributem, který by uchovával hodnotu takovéhoto parametru je nepraktické. Lepší je proto v~takovémto případě využít předávání parametrů přes vestavěný objekt \texttt{request}. To zařídí metoda \texttt{setAttribute}, která bere dva parametry. Prvním je název nastavovaného atributu a~druhým je jeho hodnota. Názvy atributů požadavku si můžeme vymyslet --- objekt \texttt{request} si je ukládá do tabulky typu \texttt{Map}. Příklad ukazuje, jak do objektu požadavku uložit výslednou částku po přepočtu do výstupní měny. Předpokládejme, že výsledná částku máme uloženou ve zdrojovém kódu v~proměnné \texttt{result}.

\begin{Verbatim}
request.setAttribute("result", result);
\end{Verbatim}

Po předání na další stránku si můžeme parametry vyzvednout pomocí metody \texttt{getAttribute}. Té jako parametr zadáme identifikátor, pod kterým jsme parametr uložili. V~příkladu získáme přepočítanou částku z~objektu \texttt{request}.

\begin{Verbatim}
Object obj = request.getAttribute("result");
\end{Verbatim}

\fcolorbox{boxout}{boxin}{
\parbox{0.98\linewidth}{
Vzhledem k~principu celého postupu je předávání parametrů mezi stránkami tímto způsobem možné pouze při přeposlání. U~přesměrování dojde ke ztrátě objektu \texttt{request} a~tím i~ke ztrátě všech jeho nastavených atributů.
}}




\subsection{Závěr}

Technologie JSP představuje významný posun oproti servletům v~pohodlnosti a~přehlednosti programování. Zároveň si zachovává jednoduchost a~je snadno pochopitelná. Dá se kombinovat s~již existujícím HTML kódem a~také s~již existujícím kódem v~Javě. Je ideální pro menší dynamické webové stránky na úrovni osobních stránek nebo studentských aplikací. Pro větší projekty, jako je třeba internetový obchod se hodí spíše překročit k~nějakému modernějšímu frameworku.

Použitá literatura:\\
\cite{Java Server Pages} \emph{Java Server Pages}\\
\cite{Programujeme Jakarta Struts} \emph{Programujeme Jakarta Struts}\\

