Java Server Pages
Jedná se o
vmícháníJavy přímo do HTML kódu, což vede k výrazně snazší tvorbě webových aplikacích psaných v Javě. Javovský kód je ohraničen speciálními značkami
<%
a %>
. Přijde-li serveru požadavek
na takovouto stránku, ten ji přeloží na obyčejný servlet, jenž pak vykoná.
<%= expression %>
Způsobí vyhodnocení výrazu expression, jeho převedení na řetězec a vytisknutí tohoto řetězce. Ekvivalentně je možno použít
zápis
<jsp:expression>expression</jsp:expression>
.
Current time: <%= new java.util.Date() %>
<% code %>
code
je libovolný javovský kód, který je třeba vykonat (bude vložen dovnitř těla metody
service
). Evivalentně: <jsp:scriptlet>code</jsp:scriptlet>
.
<% String queryData = request.getQueryString(); out.println("Attached GET data: " + queryData); %>Kde se vzaly proměnné
request
a out
- viz níže.
Jednotlivé scriptlety nemusejí obsahovat celé javovské bloky, je možné (a mnohdy vhodné) používat i takovéto
zápisy:
<% if (Math.random() < 0.5) { %> Have a <strong>nice</strong> day! <% } else { %> Have a <strong>lousy</strong> day! <% } %>Takový kód bude převeden na něco podobného tomuto:
if (Math.random() < 0.5) { out.println("Have a <strong>nice</strong> day!"); } else { out.println("Have a <strong>lousy</strong> day!"); }
<%! code %>
Kód
code
bude vložen do vnitřku servletu, avšak mimo metodu service
, používá se tedy pro
deklarace (metod, proměnných, konstant, podtříd, …). Ekvivalentně:
<jsp:declaration>code</jsp:declaration>
.
<%! private int accessCount = 0; %> Accesses to page since server reboot: <%= ++accessCount %>
<%@ directive attribute="value" %>
Přesněji
<%@ directive attribute1="value1" attribute2="value2" … attributeN="valueN"
%>
. Direktivy nějakým způsobem ovlivňují celou produkovanou stránku. Ekvivalentně:
<jsp:directive.directiveType attribute="value"/>
.
-
Direktiva
page
import="package.class"
contentType="MIME-Type[; charset=Character-Set]"
session="true|false"
buffer="size|none"
errorPage="url"
- …
-
Direktiva
include
file="relative_url"
<jsp:include page="relative_url" flush="true"/>
Narozdíl od vložení pomocí direktivy
page
, která soubory vkládá už při překladu na servlet, toto vložení se
provede až ve chvíli, kdy je potřeba.
<jsp:useBean … />
Tato konstrukce umožňuje ve stránce načíst JavaBean. Nejjednodušší použití vypadá takto:
<jsp:useBean id="name"
class="package.class" />
. V takovém případě bude vytvořena instance dané třídy a bude přiřazena proměnné určené
atributem id
. Vytvořené beany je ovšem možné sdílet mezi jednotlivými stránkami, k tomuto účelu slouží
atribut scope
, který může nabívat těchto čtyř hodnot: page
(defaultní hodnota),
request
, session
, application
. Pokud použijeme atributy id
i
scope
a už jsme předtím vytvořili bean se stejným id
i scope
, znamená to, že se
nevytvoří nová bean, ale bude použita existující. Dále je možné použít atributy type
a beanName
- první vyjadřuje typ vytvářené proměnné, druhý by měl obsahovat totéž, co bychom jinak předávali Beans
metodě instantiate
; je povoleno místo atributu class
zadat atributy type
a
beanName
.
Nastavování datových položek bean a jejich načítání se děje konstukcemi
<jsp:setProperty … />
a
<jsp:getProperty … />
. U obou se používají atributy name
a property
,
kde první znamená jméno, které jsme bean přiřadili při jejím vytvoření atributem id
, a druhý značí položku,
kterou chceme upravit (nebo načíst). Při nastavování ještě použijeme atribut value
, jehož obsahem je nová
hodnota (je chápána jako řetězec, který je v případě potřeby standardním způsobem zkonvertován na daný typ).
Element
jsp:useBean
není nutné použít jako prázdný, je možné v jeho vnitřku použít nějaké množství elementů
jsp:setProperty
. Taková konstrukce znamená, že tyto hodnoty budou nastaveny pouze při vytváření nové bean;
pokud je však použita již existující bean, je nastavování ignorováno.
Jednoduchý příklad.
SimpleBean.java
:
package hall; public class SimpleBean { private String message = "No message specified"; public String getMessage() { return(message); } public void setMessage(String message) { this.message = message; } }
BeanTest.jsp
:
… <jsp:useBean id="test" class="hall.SimpleBean"/> <jsp:setProperty name="test" property="message" value="Hello WWW"/> <h1>Message: <jsp:getProperty name="test" property="message"/></h1> …
<jsp:forward page="relative_url" />
Tato konstrukce způsobí přesměrování momentálního požadavku na nějakou jinou stránku. Obsah atributu je možné dodat i za
běhu:
<jsp:forward page="<%= expression %>"/>
.
Předdefinované proměnné
HttpServletRequest request
HttpServletResponse response
JspWriter out
(bufferovaná verzePrintWriter
u)HttpSession session
- …
Komentáře a escape sekvence
JSP komentář má tvar
<%-- comment --%>
, od HTML komentáře <!-- comment -->
se liší
tím, že nebude vůbec součástí HTML souboru odeslaného ze serveru. Pokud by někdo chtěl použít sekvence <%
(resp. %>
), aniž by se jí Java začala zabývat, je možný zápis <\%
(resp. %\>
).
Oddělení formy a obsahu
Technologie JSP značně usnadňuje a zpřehledňuje tvorbu servletů (oproti přímému psaní servletů), JSP soubory se obvykle
vyznačují delšími bloky čistého HTML kódu střídanými bloky javovského kódu. Pro větší webové aplikace však ani toto nemusí
postačovat, je potřeba něčeho ještě robustnějšího. Například modelová situace, kdy dvě různé stránky obsahují určitou část
stejného nebo podobného HTML kódu, který se liší jenom obsaženými daty, se čistě pomocí JSP řeší poměrně špatně. Hodil by
se nějaký systém šablon, kterým pouze podstrčíme data a ony už se postarají o jejich obalení patřičným HTML kódem. Jako
jedno řešení se nabízí generování XML (podle předem stanoveného DTD nebo Schema) s patřičnými daty (místo generování
celého HTML výstupu) a následně jeho transformace pomocí XSL šablony do libovolného požadovaného formátu
(např. HTML). Kromě značné flexibility tohoto řešení tkví výhoda i v tom, že Java standardně implementuje obě API pro
snadnou práci s XML dokumenty - SAX a DOM.