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"/>.
  1. Direktiva page
    • import="package.class"
    • contentType="MIME-Type[; charset=Character-Set]"
    • session="true|false"
    • buffer="size|none"
    • errorPage="url"
  2. 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á verze PrintWriteru)
  • 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.