Tagikirjaston
kuvaamistiedosto (Tag Library Descriptor)
Tagikirjaston
kuvaaminen web.xml sivulla
Attribuuttien
lisääminen tagiin
5.1.3 Parametrien lukeminen tagin
käsittelijässä
Tagin rungon käsitteleminen moneen kertaan
JSP spesifikaatiosta 1.1[1] lähtien ohjelmoijilla on ollut mahdollisuus tehdä omia JSP-tageja. Ohjelmoija määrittelee JSP uuden tagin sekä sen attribuutit, ja kaikki tagit kerätään yhteen muodostaen JSP-tagi kirjaston.
Perusidea omien tagien luomisessa on sama kuin jsp:useBean direktiivissä. Muodoltaan yksinkertaisella ja selkeällä komennolla saadaan piilotettua monimutkaisuus JSP sivulta.
Käyttääksesi omia tageja ohjelmoijan tarvitsee luoda kolme komponenttia
Ensimmäinen tehtävä luodessasi uutta tagia on luoda luokka, joka kertoo järjestelmälle mitä tehdään kun tällaiseen tagiin törmätään. Esimerkissä määritelty tagi korvataan tekstillä
<title>
Webapplication tutoriaali - selainversion testaaminen
</title>
kaikkien tagin esiintymien kohdalla.
package
tagit;
import
javax.servlet.jsp.*;
import
javax.servlet.jsp.tagext.*;
import
java.io.*;
public
class TitleTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print("<title>
Webapplication tutoriaali</title>");
} catch(IOException ioe) {
System.out.println("Error in ExampleTag: " + ioe);
}
return(SKIP_BODY);
}
}
Yksinkertaiset tagit käsitellään yleensä
luokalla, joka perii TagSupport[2]
luokan. Jos tagilla ei ole attribuutteja eikä varsinaista sisältöä, riittää
doStartTag-metodin ylikirjoittaminen (override). Tällöin kyseisen metodin
pitäisi lisäksi palauttaa SKIP_BODY vakio. Näin jätetään huomioimatta
mahdollinen tagin sisältö. Metodissa tulostetaan JSPWriter[3]
luokan oliolla.
Käännetty luokka sijoitetaan Tomcatissä
WEB-INF\classes\tagit hakemistoon.
Tehtyäsi tagin käsittelijä luokan,
seuraava tehtäväsi on luoda XML-tiedosto, jossa luokka yhdistetään määrättyihin
tageihin. Tätä koodia voit käyttää suoraan omissa sovelluksissasi. Ainoastaan
lihavoidut kohdat tarvitsevat muokkausta. Tiedostossa tutor_taglib.tld on
kuvattuna ainoastaan yksi tagi. Tomcatissä tiedosto sijoitetaan WEB-INF\lib
hakemistoon.
<?xml
version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE
taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD
JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>tutor</shortname>
<uri>/tutor</uri>
<info>
Tagi kirjasto webApplication
tutoriaaliin
</info>
<tag>
<name>title</name>
<tagclass>tagit.TitleTag</tagclass>
<info>tagi
korvataan puhtaalla tekstillä</info>
<bodycontent>EMPTY</bodycontent>
</tag>
</taglib>
Tagikirjaston kuvaamistiedosto on
muuttunut huomattavasti JSP spesifikaatioiden 1.1 ja 1.2 välillä. Erot huomaat vertailemalla vastaavia
DTD-dokumentteja:
http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd
http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd
Tomcatissä kaikki tagikirjastot kuvataan
sovelluksesi web.xml tiedostossa taglib elementtiä käyttäen seuraavasti:
<taglib>
<taglib-uri>/tutor</taglib-uri>
<taglib-location>/WEB-INF/lib/tutor_taglib.tld</taglib-location>
</taglib>
Esimerkki otettu tutor/web.xml tiedostosta.
Kun olet tehnyt tagin käsittelyyn
tarvittavan luokan ja tagikirjaston kuvaavan tld-tiedoston, voit käyttää
tagiasi JSP sivulla. Ennen ensimmäistä tagia kirjasto pitää ottaa käyttöön
seuraavasti
<%@ taglib uri=”tutor_taglib.tld” prefix=”tutor” %>
Tagin käyttöä demonstroidaan tagTest.jsp
sivulla
<%@
taglib uri="/tutor" prefix="tutor" %>
<html>
<head>
<tutor:title />
</head>
<body>
<h1> Tagia käytetty sivun
otsikon luomiseen </h1>
</body>
</html>
Edellisen esimerkki toimii kuten
symbolinen vakio. Ennalta määrätty teksti korvataan uudella arvolla.
Lisätäksemme toiminnallisuutta ”makro-tasolle” pitää tagimme pystyä käsittelemään
attribuutteja.
Attribuutin käyttö JSP sivulla aiheuttaa
vastaavan set_attribuutin_nimi kutsun. Tagin käsittelijä-luokkaan lisätään
jokaiselle attribuutille vastaavan niminen attribuutti sekä set-metodi[4]
(lisäksi on hyvä lisätä get-metodit[5],
mikäli muut luokat käyttävät tagin käsittelijää).
Tagin attribuutit pitää myös kuvata
tld-tiedostossa seuraavasti:
<attribute>
<name><!-- attribuutin
nimi --></name>
<required><!-- true/false. Onko attribuutti pakollinen--> <required>
<rtexprvalue><!-- true/false. Voidaanko attribuuttia käyttää JSP expression tagissa --></rtexprvalue>
</attribute>
<rtexprvalue> elementti ei ole pakollinen (oletus false).
Attribuutin käyttö JSP sivulla on suoraviivaista
<tutor:title attribuutin_nimi=arvo />
Attribuutit asetetaan ennen doStartTag
metodin suorittamista, joten attribuutit ovat käytettävissä metodissa.
Esimerkin vuoksi muokataan edellisiä
tiedostoja s.e sivun otsikkoon on mahdollista lisätä tarkennusta tagia
käytettäessä. Annetaan attribuutille nimeksi titleEnd. Tarvittavat muutokset
ovat:
Tagin
käsittelijä luokkaan:
public void setTitleEnd(String jono)
{
titleEnd = jono;
}
out.print("<title> Webapplication tutoriaali
");
if( titleEnd != null)
out.print("- " + titleEnd);
out.print("</title>");
…
<attribute>
<name>titleEnd</name>
<required>false</required>
</attribute>
</tag>
<tutor:title titleEnd="tagin attribuutille arvon asettaminen"/>
Lopputulos tagTest.jsp
Kuva 1. tagTEst.jsp. Oman tagin testaaminen.
Huomaa selaimen otsikko (title)
Seuraavaksi lisätään tagiin runko (body). Tagi kokonaisuudessaan on seuraavaa muotoa
<prefix:tagname
attribute1=”value1” attribute2=”value2” >
body </prefix:tagname>
Ainoa muutos bodyn sisällyttämiseksi tagin käsittelijään on muuttaa doStartTag() metodin paluuarvo olemaan EVAL_BODY_INCLUDE. Lisäksi tagin kuvaustiedostoon pitää muuttaa bodycontent elementti saamaan arvo JSP.
Yleensä rungon käsittelyn jälkeen halutaan tehdä jokin toimenpide. Tämä onnistuu ylikirjoittamalla doEndTag metodi. Ellei haluta lopettaa sivun suorittamista tagin käsittelyn jälkeen, doEndTag-metodin pitää palauttaa EVAL_PAGE. Mikäli halutaan lopettaa sivun suoritus jostain syystä, palauta SKIP_PAGE.
Huomaa, että tagin runko voi sisältää myös JSP skriptejä ja direktiivejä!
Koska tagin käsittelijäluokan metodit eivät saa parametreina HttpServletRequest eikä HttpServletResponse olioita, on pyynnön parametrien lukeminen hieman monimutkaisempaa. Seuraavassa luetaan parametrin useBody arvo, jonka mukaan päätetään otetaanko tagin runko mukaan tulostukseen vai ei.
public
int doStartTag() {
ServletRequest request =
pageContext.getRequest();
String value = request.getParameter(“useBody”);
If( value != null &&
value.equalsIgnoreCase(“true”) )
return (EVAL_BODY_INCLUDE);
return (SKIP_BODY);
}
TagSupport luokan periminen on riittänyt hyvin tähän asti käsitellyissä yksinkertaisissa tageissa. Mikäli kuitenkin tagin runkoa pitää muokata, on tagin käsittelijäluokan perittävä BodyTagSupport[6] luokka (joka puolestaan perii TagSupport[7] luokan).
BodyTagSupport luokassa määritellyt tärkeimmät metodit ovat:
BodyContent[8] luokassa on kolme oleellista metodia
·
getEnclosingWriter, palauttaa JspWriter olion jota voidaan käyttää doStartTag-
ja doEndTag- metodeissa.
·
getReader, palauttaa Reader luokan olion jolla tagin runko voidaan lukea
·
getString, palauttaa tagin koko rungon
Mikäli haluat käsitellä tagin rungon useasti, pitää doAfterBody metodin palauttaa EVAL_BODY_TAG arvo. Halutessasi lopettaa toiston palauta arvo SKIP_BODY.
[1] Ks.
http://java.sun.com/products/jsp/download.html
[2] Ks.
http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/TagSupport.html
[3] Ks.
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jspapi/javax/servlet/jsp/JspWriter.html
[4] Metodi, joka asettaa attribuutille arvon, esim. setNimi(String uusiArvo).
[5] get-metodi palauttaa vastaavan attribuutin arvon, esim. getNimi()-metodi.
[6] Ks.
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/BodyTagSupport.html
[7] Ks.
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/TagSupport.html
[8] Ks.
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/BodyContent.html