JavaSvet - otvorena java zajednica

 
glavna stranica arr2javasvet  english version arr2java.net

JSP v2.0

Igor Spasić
24 Feb 2005

Nova verzija JSP specifikacije, JSP v2.0, se pojavila u okviru specifikacije za J2EE v1.4. JSP v2.0 postoji već neko vreme i svi JSP kontejneri koji drže do sebe implementiraju ovu specifikaciju. Međutim, čini se da se developeri po navici drže starih stvari i da nisu dovoljno upoznati sa novinama koje donosi JSP v2.0 specifikacija. Što je u ovom slučaju šteta, jer JSP v2.0 donosi puno toga što može da značajno ubrza i olakša svakodnevni rad sa JSPom. Ovaj članak je upravo namenjen developerima koji već imaju iskustva u radu sa dosadašnjim verzijama JSP i Servlet specifikacijama.

Sadržaj:
Linkovi:

Zbog obimnosti i velikog broja detalja, ovaj pregled JSP v2.0 specifikacije neće moći da se temeljno bavi i objasni baš sve pojedinosti nove specifikacije. Umesto toga, fokus i cilj članka je da pruži pregled što više novosti.

Expression Language (EL)

Expression Language (EL) je specifikacija koja definiše kako se pristupa atributima objekata u run-time okruženju. EL je prvi put predstavljen u okviru JSTL v1.0 specifikacije. U JSP v2.0 je sam JSP kontejner zadužen da 'razume' i da izvršava EL izraze, tako da nije potrebno nikakvo dodatno podešavanje.

EL specifikacija konačno oslobađa programera od zamornog i nepraktičnog pisanja dugačkih izraza samo da bi se pristupilo nekom atributu, tj. propertiju objekta. EL uvodi novu i elegantnu sintaksu, koja je logična, kraća za pisanje i laka za upotrebu.

Svaki EL izraz se zadaje u obliku: ${izraz}. Izraz uključuje literale, varijable i operatore. Literali su brojevi, tekst (pod jednostrukim ili dvostrukim navodnicima), Boolean vrednosti i null. Varijable uglavnom predstavljaju vrednosti atributa beanova ili atributi/parametri JSP scopeova. Svaki bean iz bilo kog JSP scopea može biti iskorišćen kao varijabla. EL dodatno specificira sledeće predefinisane varijable:

Ime varijableOpis
pageScopejava.util.Map kolekcija svih atributa iz page scopea.
requestScopejava.util.Map kolekcija svih atributa iz request scopea.
sessionScopejava.util.Map kolekcija svih atributa iz session scopea.
applicationScopejava.util.Map kolekcija svih atributa iz application scopea.
paramjava.util.Map kolekcija svih request parametara predstavljenih kao jedan String po parametru.
paramValuesjava.util.Map kolekcija svih request parametara predstavljenih kao String[] niz po jednom parametru.
headerjava.util.Map kolekcija svih header parametara predstavljenih kao jedan String po parametru.
headerValuesjava.util.Map kolekcija svih header parametara predstavljenih kao String[] niz po jednom parametru.
cookiejava.util.Map kolekcija svih cookie vrednosti datih kao jedan javax.servlet.http.Cookie value po cookie-ju.
initParamjava.util.Map kolekcija svih init parametara aplikacije, datih kao jedan String vrednost po parametru.
pageContextinstanca javax.servlet.jsp.PageContext klase, omogućava pristup raznim podacima iz request-a.

Od operatora, EL podržava sledeće, od kojih je većina sama po sebi jasna:

OperatorOpis
.Pristup propertiju beana ili elementu Mape.
[]Pristup elementu niza ili Liste.
()Grupisanje izraza.
? :Kondicionalini test.
+Sabiranje.
-Oduzimanje ili negacija vrednosti.
*Množenje.
EEksponent.
/ ili divDeljenje.
% ili modModuo (ostatak).
== ili eqTest jednakosti.
!= ili neTest nejednakosti.
< ili ltTest za manje.
> ili gtTest za veće.
<= ili leTest za manje ili jednako.
>>= ili geTest za veće ili jednako.
&& ili andTest za logičko I (AND).
|| ili orTest za logičko ILI (OR).
! ili notKomplement.
emptyTest da li je varijabla prazna: null, prazan String ili niz, Mapa, ili Collection bez elemenata.
foo(args)Poziv funkcije foo sa odgovarajućim argumentima (0, 1 ili više).

EL parser je zadužen da ispravno protumači izraz i da poštuje tipove elemenata izraza. Znači, ako se izraz sastoji od sabiranja dve brojčane varijable i/ili literala, rezultat će biti njihova brojčana suma. Tip rezultata matematičkog izraza zavisi od tipova brojčanih vrednosti, na primer: rezultat delenja je uvek realan broj, pri čemu se vodi računa i o delenju s nulom. Operatori za poređenje rade i sa brojčanim vrednostima i sa stringovima. Korisno je i postojanje alternativnih 'tekstualnih' operatora za poređenje kako uobičajeni znaci ne bi remetili strukturu ili smanjivali čitljivost JSP/HTML strane.

Rad sa varijablama

Velika prednost EL je lak pristup atributima bean-ova. Dosadašnji način pristupa atributima u raznim scope-ovima je glomazan. Primer sa skripletima:

<%=pageContext.getAttribute("pagevar")%>
<%=request.getAttribute("requestvar")%>
<%=session.getAttribute("sessionvar")%>
<%=application.getAttribute("appvar")%>

Korišćenjem predefinisanih varijabli (tipa java.util.Map) u EL je ovaj blok moguće napisati na dva načina. Prvi je nešto kraći i koristi 'tačka' operator (.):

${pageScope.pagevar}
${requestScope.requestvar}
${sessionScope.sessionvar}
${applicationScope.appvar}

Drugi, ekvivalentan način, koristi operator 'srednje zagrade' ([]):

${pageScope['pagevar']}
${requestScope['requestvar']}
${sessionScope['sessionvar']}
${applicationScope['appvar']}

To nije sve: EL donosi mogućnost 'skraćenog' pisanja varijabli. Ako se navede samo ime beana, bez predefinisane varijable koja bi određivala scope, onda EL pretražuje redom page, request, session i application scope dok ne nađe traženi element. Prethodni primer se zato može pisati i na sledeći način, mnogo kraće:

${pagevar}
${requestvar}
${sessionvar}
${appvar}

Jasno, ako postoje 2 atributa sa istim imenom u različitim scope-ovima, EL će vratiti prvi na koji naiđe, prema navedenom redosledu traženja.

JSTL v1.1

Nova verzija JSTL-a ne donosi mnogo novina i više služi da se bolje uklopi u JSP v2.0 specifikaciju. Pored 4 postojeće biblioteke tagova, dodata je još jedna, pod imenom "Functions". Ona ima veze s pozivanjem JSTL funkcija iz EL izraza i biće objašnjena nešto kasnije. Važno je da se URI za JSTL v1.1 biblioteke izmenio (sadrži '/jsp'), o čemu treba voditi računa. Prefiks tagova je ostao isti:

BibliotekaURIPrefiks
Corehttp://java.sun.com/jsp/jstl/corec
XMLhttp://java.sun.com/jsp/jstl/xmlx
I18Nhttp://java.sun.com/jsp/jstl/fmtfmt
Databasehttp://java.sun.com/jsp/jstl/sqlsql
Functionshttp://java.sun.com/jsp/jstl/functionsfn

Instalacija JSTL v1.1 je jednostavna: najčešće sve što treba uraditi je staviti jstl.jar i standard.jar u WEB-INF/lib folder. JSP stranica koja koristi JSTL na stadardni način uključuje biblioteke @taglib direktivom, koristeći nove vrednosti za URI.

Primeri EL i JSTL

Evo čestog primera u JSP v1.x, iteriranje liste elemenata, s puno skriptleta:

<ul>
<%
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object elem = iterator.next();
if (elem == null) elem = "";
%>
<li> <%=elem%> </li>
<%
}
%>
</ul>

Ne može se reći da je gornji kod preterano elegantan:) Ista logike, napisana u duhu JSP v2.0 izgleda ovako:

<ul>
<c:forEach var="elem" items="${list}">
<li> ${elem} </li>
</c:forEach>
</ul>

EL Funkcije

EL i JSTL v1.1 uvode novi koncept EL funkcija. Funkcije su definisane u okviru standardne JSTL biblioteke i koriste se iz EL izraza:

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<%
int[] array = new int[3]; array[0] = 7; array[1] = 8; array[2] = 9;
pageContext.setAttribute("arr", array);
%>
...
${fn:length(arr)}

Smisao EL funkcija je da budu globalne statičke pomoćne funkcije. Njihova prednost je, na primer, to što ispravno tumače tipove argumenata. Tako funkcija fn:length() vraća dužinu niza ili broj elemenata kolekcije, ili dužinu Stringa, ili broj elemenata Mape, ili ako je argument Iterator ili Enumeration ukupan broj elemenata u iteraciji, tj. enumeraciji.

Od ostalih predefinisanih JSTL v1.1 funkcija, tu su uglavnom razne standardne funkcije za rad sa stringovima. Možda je interesantno pomenuti funkciju: fn:escapeXml() koja enkodira argument u 'bezbedan' XML/HTML sadržaj koji ne narušava strukturu dokumenta.

Moguće je praviti i biblioteke sa custom funkcijama. Pored Java koda same funkcije, potrebno je i definisati je u TLD deskriptoru.

JSP Fragmenti

Skoro svaka web aplikacija koristi fragmente JSP koda koji se uključuju na velikom broju stranica. Uobičajeni sajt ima zaglavlje, meni sa leve strane, centralni deo... Zaglavlje se, na primer, pojavlje na svim stranama bez izmena. Jasno, bilo bi glupo pisati iste delove koda na svim stranama. Zato se ovakvi fragmenti JSP koda stavljaju u zasebne fajlove koji se zatim uključuju (include) na stranama.

Sve ovo je već moguće bilo raditi u JSP v1.x. JSP v2.0 donosi i preporučenu ekstenziju za fajlove koji predstavljaju JSP segmente: .jspf.

Važno je uočiti da specifikacija nalaže da se extenzija ".jspf" koristi samo za statičke fragmente. Za dinamičke fragmente, treba nastaviti koristiti dosadašnju ekstenziju ".jsp". Dalje, po specifikaciji, preporuka je da se statički fragmenti drže u folderu "WEB-INF/jspf".

Primer uključivanja fragmenata:

<%@ include file="WEB-INF/jspf/header.jspf" %>
<jsp:include page="<%= pageBody %>" />
<%@ include file="WEB-INF/jspf/footer.jspf" %>

Uočiti da se za jsp:include ne koristi više flush="true". Ovo važi i za JSP v1.2, ali nije loše pomenuti ponovo, jer se čini da se i dalje po navici (nepotrebno) koristi. Inače, JSP v2.0 predlaže da se ovakvi statički delovi JSP koda zovu "JSP segmenti", pošto se izraz "fragment" koristi već za puno stvari.

JSP Tag fajlovi

JSP v2.0 uvodi mogućnost postojanja custom tag handlera definisanih u JSP fajlovima, a ne samo u Javi. Ovo je zanimljiv koncept, koji je praktično sve vreme bio "tu negde", dok ga nisu sada konačno definisali i uvrstili u specifikaciju. O JSP tag fajlovima može puno da se priča, ali se zbog prirode članka neće ići u sve detalje.

Čest je slučaj da custom JSP tagovi jednostavno moraju da manipulišu sa HTML kodom. Dosadašnje rešenje bi zahtevalo pisanje custom JSP taga kao Java klase, što bi značilo da se rad sa HTML-om obavlja ili u Java kodu, ili na komplikovani način u telu taga, koji dodatno usložnjava upotrebu taga. Dodatnu komplikaciju predstavlja čunjenica da se svaki Java custom tag mora pisati prema možda ne baš intuitivnim pravilima, poštojući odgovarajući life-cycle izvršavanja taga.

JSP tag fajlovi omogućuju jednostavno definisanje custom tag handlera u JSP fajlovima. Sve je, dakle, u JSP fajlovima, pa je lako raditi izmene tagova. Evo primera jednog JSP tag fajla:

<%@ tag body-content="scriptless" %>
<%@ attribute name="alienId" required="true" %>
<%@ attribute name="namesMap" required="true" type="java.lang.Object" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<p>
<jsp:doBody/>
</p>
<c:forEach items="${namesMap}" var="name">
	${name.value} ${name.key == alienId ? 'alien:)' : ''}<br>
</c:forEach>

Definicija JSP tag fajla bi trebalo (mada nije obavezno) da počne s odgovarajućom direktivom (@tag). Može se specifirati i tip JSP tag fajla prema tome da li i kako uključuje telo taga:

Ostatak JSP taga je manje-više jasan: sledi definicija njegovih atributa, a zatim i samo telo tag handlera. Gornji JSP tag fajl se poziva na sledeći način:

<%@ taglib prefix="foot" tagdir="/WEB-INF/tags" %>
...
<foot:foo alienID="1" namesMap="${whoismap}">
	Who is the alien?
</foot:foo>

Uključivanje custom JSP tag fajla se može obaviti direktnim pokazivanjem na folder koji sadrži '.tag' fajlove (direktiva @taglib, atribut tagdir), kao u primeru. Ime '.tag' fajla je ujedno i ime taga. Inače, ovde je 'whoismap' page scope atribut, tipa java.util.Map.

Alternativno, JSP tag fajlovi se mogu definisati i u deskriptoru, na sličan načina kao i uobičajeni JSP Java tagovi. Tada se na JSP strani umesto tagdir koristi atribut taglib u okviru @taglib direktive. Tako definisane JSP tag fajlove je moguće uključiti i u distribucioni jar, zajedno sa TLD-ovima.

Dinamički atributi taga

JSP tag fajlovi imaju mogućnost da koriste tkzv. dinamičke atribute, koji se koriste u slučajevima kada nije unapred poznat broj atributa taga. Tada se svi atributi navedeni u pozivu JSP taga, a koji nisu konkretno specificirani u njegovoj definiciji, smatraju dinamičkim. Dinamički atributi se jednostavno prenose kao java.util.Map objekat.

Da bi JSP tag fajl koristio dinamičke atribute, treba jednostavno dopuniti definiciju taga:

<%@ tag body-content="scriptless" dynamic-attributes="attrMap" %>

U attrMap mapi se sada nalaze svi dinamički atributi. Kako je u pitanju mapa, dinamičkim atributima se u handleru taga pristupa na uobičajen način:

<c:forEach var="attr" items="${attrMap}">
	${attr.key} = ${attr.value}
</c:forEach>

Varijable iz JSP Taga i sa JSP strane

JSP tagovi i strana odakle su pozvani dele sve scopeove osim page scopea. Da bi JSP tag setovao neku varijablu koja će biti vidljiva na strani odakle je tag pozvan, a posle poziva i izvršavanja taga, treba je samo uključiti u neki od preostala tri vidljiva scopea, recimo u request scope:

<c:set var="vlocal" value="Local Troll"/>
<c:set var="vglobal" value="Global Troll" scope="request"/>

vlocal je u page scopeu i vidi se samo u handleru taga, dok se vglobal vidi i posle izvršavanja taga.

Postoji još jedan način kako se prenose varijable između taga i JSP strane: korišćenjem direktive variable. Ovom direktivom se jednostavno definišu varijable koje će se videti i posle taga, bez potrebe da se one implicitno smeštaju u neki scope. Ovako definisane varijable moraju da imaju jedan od tri scopea varijabli (ne treba ih mešati sa JSP scopeovima!), a označavaju kada će varijabla u tagu biti setovana:

U pitanju su nijanse koje je najbolje razumeti kroz primer, dat na kraju članka.

Postoji još i mogućnost da se ova imena varijabli setuju dinamički, pomoću atributa taga.

Pozivanje JSP tag fragmenata

Rečeno je da atributi taga mogu biti obični i dinamički. Postoji još jedan tip: tkzv. fragment atributi. Fragment atribut predstavlja JSP fragment (smisleni isečak JSP koda) koji se može izvršiti u JSP tag fajl handleru, a definisan je pri pozivu taga.

Primer jednog JSP tag fajl handlera:

<%@ attribute name="voodoo" required="true" %>
<%@ attribute name="template" fragment="true" %>
<%@ variable name-given="data" scope="NESTED" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:set var="data" value="${voodoo}"/<
<jsp:invoke fragment="template"/>
<c:set var="data" value="${voodoo} #1"/>
<jsp:doBody/>
<c:set var="data" value="${voodoo}"/>
<jsp:invoke fragment="template"/>
<c:set var="data" value="${voodoo} #2"/>
<jsp:doBody/>

i njegove upotrebe:

<example:doo voodoo="zulu">
	<jsp:attribute name="template">
		hello from template: ${data}
	</jsp:attribute>
	<jsp:body>
		hello from body: ${data}
	</jsp:body>
</example:doo>

Ovde je pravo mesto da se uoče <jsp:doBody> i <jsp:invoke>. Oba mogu da se koriste samo u JSP tag fajlovima. Oba taga rade vrlo slično: invokuju odgovarajući specificirani JSP fragment. <jsp:doBody> invokuje telo taga, dok <jsp:invoke> invokuje neki specificirani JSP tag fragment. Oba imaju i tri ista neobavezna atributa kojima se dodatno upravlja izvršavanjem.

SimpleTag interfejs

Još jedna novina JSP v2.0 se tiče custom tagova. Ovaj put je reč o Java implementaciji tag handlera i o novom javax.servlet.jsp.tagext.SimpleTag interfejsu. Dosadašnji način razvoja custom tagova zahteva poštovanje nešto složenijeg life-cyclea tagova i interfejsa (doStartTag(), doAfterBody(), doEndTag()). JSP v2.0 specifikacija donosi novi interfejs za razvoj custom tagova, čiji life-cycle zahteva da se u samo jednoj metodi handlera odradi sva logika. Evo kako bi izgledao kostur jednog ovakvog taga:

public class FooCustomTag extends SimpleTagSupport {

   
/* get/set metode za sve atribute taga */

    /* definicija tag handlera */
   
public void doTag() throws JspException, IOException {
       
JspWriter out = getJspContext().getOut();
        out.println
("....");
        JspFragment body = getJspBody
();
       
if (body != null) {
           
body.invoke(null);
       
}
       
out.print("....");
       
//...
   
}
}

Od novih stvari tu je getJspBody() koji vraća telo taga, a koje se ispisuje u JspWriter output stream metodom JspFragment.invoke(). Ostatak handlera može da na standardan način ispisuje sadržaj, koristeći print() i println() metode. Dalje, SimpleTagSupport podržava i dinamičke atribute, slično JSP tagovima.

Ovaj način jeste lakši za razvoj, ali navodi programera da koristi HTML unutar Java klase, što, po mišljenju autora, nije baš dobra praksa. Zato treba biti pažljiv u korišćenju ovog interfejsa. Njegova primena bi imala više smisla na mestima gde custom tag treba da izmeni postojeći HTML kod, pre nego tamo gde treba da ga generiše.

Stranice za greške

Stranice za greške su stranice koje će JSP kontejner vratiti u slučaju neke HTTP ili sistemske greške (404, 405, 500...). JSP specifikacija odavno pruža mogućnost da programer sam definiše koje će se stranice prikazati u slučaju grešaka (web.xml tag error-code). Međutim, problem je bio prikazivanje informacija o exception-u koji je prouzrokovao grešku.

JSP v2.0 koristi isti javax.servlet.error.exception atribut. Pored njega, uvedena je pageContext.errorData varijabla, koja sadrži sleće propertije:

Način korišćenja je trivijalan i dat je u primeru.

Servlets v2.4

I Servlet API je doživeo promene. Evo pregleda nekih najznačajnijih.

Novi listeneri

Dodati su novi listeneri: ServletRequestListener i ServletRequestAttributeListener. Prvi listener se aktivira svaki put kada aplikacija primi novi request. Drugi listener se aktivira svaki put kada se objekat smešta, uklanja ili zamenjuje u requestu.

Filteri i Request Dispatcher

Filteri se sada mogu koristiti i pri upotrebi Request Dispatchera. Sledeća definicija filtra:

<filter>
	<filter-name>FooFilter</filter-name>
	<filter-class>com.doe.john</filter-class>
</filter>

<filter-mapping>
	<filter-name>FooFilter</filter-name>
	<url-pattern>/doo</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

definiše filter koji se izvršava na svaki '/doo' request, ali i na svaki javax.servlet.RequestDispatcher objekat koji sadrži pomenutu putanju.

Slično, ako treba izvršavati filter pri nekom forwardu, u gornjoj definiciji treba koristiti ključnu reč FORWARD umesto INCLUDE.

Request Dispatcher i Request atributi

Kada se pomoću Request Dispatcher uradi forward, takav request objekat će sadržati i još neke dodatne atribute. Ovi atributi, dakle, postoje samo posle forwarda:

Iz imena atributa se može zaključiti čemu služe.

Nove metode ServletRequest interfejsa

Interfejs javax.servlet.ServletRequest je dobio četiri nove metode:

Postojeće metode getServerName() i getServerPort() u v2.4 vraćaju drugačije vrednosti, pošto su u v2.3 vraćali ono što sada vraćaju getLocalName() i getLocalPort().

Unapređeno korišćenje i18n

U Servlet v2.3 specifikaciji nije postojao direktan način kako naznačiti klijentskom browseru koji karakter enkoding treba da koristi. Da bi se postavio željeni enkoding, trebalo ga je setovati korišćenjem instance java.util.Locale, ili da se koristeći setContentType() setuje u isto vreme i tip kontenta i karakter set.

U Servlet v2.4 specifikaciji, javax.servlet.ServletResponse ima novi metod: setCharacterEncoding() kome se jednostavno prosleđuje ime karakter enkodinga kao string. Važno: da bi ovaj metodu funkcionisao, mora biti pozvan pre prvog poziva getWriter() metode! Paralelno sa ovim, ubačen je i getContextType() metod, koji vraća tip kontenta responsea.

Pored ovih metoda, postoji način da se definiše veza locale - karakter enkoding, pa programer sada ne mora da to ručno radi u servletima, već samo u 'web.xml'-u:

<locale-encoding-mapping-list>
	<locale-encoding-mapping>
		<locale>ja</locale>
		<encoding>ISO-2022-JP</encoding>
	</locale-encoding-mapping>
</locale-encoding-mapping-list>

Razno

I jos ponešto:

JSP i XML

JSP specifikacija definiše 2 tipa JSP dokumenata: standardne, koji mogu da sadrže bilo kakav markup jezik ili tekst, i tkzv. JSP dokumente - čiste XML dokumente. JSP dokumenta se u osnovi sastoje od XHTML i JSP elemenata.

Uobičajeno je da se JSP dokumenta pišu u fajlovima sa ekstenzijom '.jspx'. Kontejner za fajlove sa '.jspx' ekstenzijom automatski podrazumeva da su XML. Postoji i drugi, eksplicitni, način naznačavanja koji će JSP fajlovi biti JSP dokumenti: u 'web.xml' deskriptoru se za jsp-property-group definiše <is-xml>true</is-xml> (o JSP setovanjima će biti više reči kasnije). Na ovaj način je moguće setovati da se, na primer, svi '.html' fajlovi posmatraju kao JSP dokumenta, tj. XHTML. Za razliku od običnog HTMLa, XHTML mora da počne sa:

<html
	xmlns="http://www.w3c.org/1999/xhtml"
	xmlns:jsp="http://java.sun.com/JSP/Page"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xml:lang="en" lang="en">

Rezultujuća stranica koja se vraća klijentu je XML sadržaj. Kontejner sam uključuje default <?xml version="1.0" encoding="..."?> liniju na početak dokumenta, na koju se može uticati korišćenjem <jsp:root> taga (nije obavezan). Inače, automatsko generisanje ove XML deklarativne linije se može eksplicitno zabraniti (<jsp:output omit-xml-declaration="true" />). Dalje, u JSP v2.0 sadržaj dokumenta (konačno:) ne mora da se nalazi ispod <jsp:root> taga, kao što je to do sada bio slučaj, već može da se jednostavno piše kao svaki uobičajeni XHTML.

Kako je i dalje u pitanju JSP, postoji način kako koristiti skriplete, deklaracije, direktive, itd. pošto njihov uobičajen način korišćenja nije moguć zbog narušavanja XHTML strukture. Zato su uvedeni odgovarajući tagovi:

JSP stranaJSP dokument
<%@ page attribute list %><jsp:directive.page attribute list />
<%@ include file="path" %><jsp:directive.include file="path" />
<%! declaration %><jsp:declaration>declaration
<%= expression %><jsp:expression>expression
<% scriptlet %><jsp:scriptlet>scriptlet

Generisanje XML elemenata

Veliki problem do sada je bio dinamičko setovanje vrednosti atributa XHTML tagova. Sledeće dve linije su primeri koje nisu primenjljive u JSP dokumentima:

<table class="%= foo.getTableClass() %">
<table class="<c:out value="${foo.tableClass}" />">

Rešenje bi bilo korišćenje CDATA sekcija, što zahteva mnogo više koda samo radi jedne jednostavne stvari. U JSP v2.0 su te stvari unapređene, pa je moguće jednostavno koristiti EL:

<table class="${user.tableClass}">

Za zahtevnije dinamičke operacije, postoje tagovi za kreiranje celih XML elemenata: <jsp:element>, <jsp:body>, <jsp:attribute> itd.

Ostale izmene

JSP v2.0 donosi i mnogo manjih izmena koje mogu biti interesantne. Evo nekih od njih.

Struktura web.xml

'web.xml' fajl je pretrpeo izmene. Najvažnija je da se u JSP v2.0 on validira prema šemi (schema), a ne kao do sada prema DTD fajlu. Korišćenje šema za validiranje ima značajne prednosti u odnostu na DTD. Jedna od korisnih prednosti je i ta da sada svi top-level elementi mogu biti navedeni u bilo kojem redosledu, što doprinosi znatno većoj čitljivosti deskriptora (za početak je sada moguće grupisati servlet i servlet-mapping definicije:). Redosled unutar top-level elemenata i dalje mora da se poštuje, ali to ne predstavlja problem.

Svi elementi 'web.xml' koji se tiču JSP konfiguracija se sada nalaze ispod top-level elementa: <jsp-config>. On može da sadrži samo: <taglib> i <jsp-property-group> pod-elemente. Prvi se koriste kao i do sada, a drugi su novi i definišu neke osobenosti JSP stranica (pogledati primere koji slede).

Na kraju, 'web-app' tag sada izgleda ovako:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">

Isključivanje EL i skripleta

U JSP v2.0 postoji mogućnost da se zabrani korišćenja skripleta na JSP strani:

<%@ page isScriptingEnabled="false" %>

Drugi, ekonomičniji način je njihova zabrana u 'web.xml' fajlu:

<jsp-property-group>
	<url-pattern>/template/*.jsp</url-pattern>
	scripting-invalid>true</scripting-invalid>
</jsp-property-group>

Slično (i jedino tako) se može zabraniti i korišćenje EL, ako je to već potrebno iz nekog razloga:

<jsp-property-group>
	<url-pattern>/template/*.jsp</url-pattern>
	<el-ignored>true</el-ignored>
</jsp-property-group>

Definisanje enkodinga JSP strana

Sada je moguće odjednom setovati enkoding za grupu JSP stranica:

<jsp-property-group>
	<url-pattern>*.jsp</url-pattern>
	<page-encoding>UTF-8</page-encoding>
</jsp-property-group>

Implicitni include

Slično je moguće implicitno setovati statički header i footer za grupu JSP stranica, odjednom:

<jsp-property-group>
	<url-pattern>/*.jsp</url-pattern>
	<include-prelude>/template/prelude.jspf</include-prelude>
	<include-coda>/template/coda.jspf</include-coda>
</jsp-property-group>

Na kraju

JSP v2.0 definitivno donosi stvari koje mogu da olakšaju razvoj web aplikacija, tako da vredi posvetiti pažnju novim mogućnostima.

Inače, u pripremi je JSP v2.1 koji će se baviti i lakšem integrisanju JSF i JSP.

Primer

Primer je namenjen za Tomcat 5.x, pošto tek od verzije 5 potpuno podržava JSP v2.0 standard.

Download primera

Napomena: Tomcat kontejner zna da ignoriše izmene u 'web.xml' koje se tiču JSP setovanja, pa nekada pomaže samo brisanje celog keša.