IPRO - PC Magazine Romania, Martie 2004
SOLUŢII PENTRU PROGRAMATORII ŞI DESIGNERII WEB
JSP: Definirea unor tag-uri de către programator
Mircea Scărlătescu
În numărul trecut discutam despre necesitatea de a putea defini pentru o aplicaţie
o serie de unelte de scripting customizate pentru o anumită aplicaţie. Am descris
exemplul unui tag care să se numească email_form şi care odată introdus într-o
pagină JSP să genereze automat un formular HTML care să cuprindă adresa de reply,
subiect şi conţinut pentru un mesaj electronic care să ajungă către email-ul
specificat.
Şi mai spuneam că tehnologia JSP a ajutat la dezvoltarea unor astfel de elemente de scripting, prin introducerea bibliotecilor de tag-uri customizate. Astfel, aşa cum într-un limbaj clasic (C++, Java,etc) pentru a folosi funcţii dintr-o clasă trebuie să declarăm mai întâi utilizarea acestei clase, după care putem să trecem la a scrie cod cu metodele clasei fără să ne intereseze structura internă a acestora, aşa şi JSP oferă şansa de a implementa aplicaţii mult mai rapid şi mai eficient, prin tag-urile customizate.
Pentru a putea folosi o bibliotecă de astfel de tag-uri sunt două etape pe care un programator trebuie să le parcurgă:
- declararea bibliotecii în cadrul aplicaţiei
- introducerea în cadrul aplicaţiei a surselor bibliotecii
Declararea bibliotecii
Înainte de utilizarea unor tag-uri din biblioteca dorită în pagina JSP, se va utiliza următoarea linie de cod:
<%@ taglib uri="/WEB-INF/library.tld" prefix="tt" %>
Linia de mai sus necesită o scurtă explicaţie. ´uri´ reprezintă identificatorul (numele) bibliotecii noastre. ´prefix´ reprezintă prefixul din cadrul numelui tag-urilor, şi arată că un anume tag face parte din biblioteca curentă, în exemplul nostru library.tld.
URI-ul de mai sus poate să fie referit direct sau indirect. În exemplul de mai sus, uri-ul este definit în mod direct. Există şi a doua variantă, care se va realiza în felul următor:
<%@ taglib uri="/tutorial-template" prefix="tt" %>
(referinţă indirectă). A doua metodă însă presupune maparea în cadrul WADD (Web Application Deployment Descriptor) calea absolută. Ambele metode sunt folosite, aici depinde exclusiv de programator alegerea uneia din cele două variante.Pentru exemplul de mai sus, descirerea pentru uri ar trebui facută dupa cum urmează:
<taglib> <taglib-uri>/tutorial-template</taglib-uri> <taglib-location> /WEB-INF/tutorial-template.tld </taglib-location> </taglib>
Introducerea codului sursă în aplicaţie
Şi în acest caz există două variante mari de lucru pentru această etapă. Clasele care implementează tag-urile pot fi stocate în cadrul aplicaţiei în directorul /classes. În mod alternativ, ele pot să fie şi arhivate (format JAR) şi stocate în directorul /lib al aplicaţiei, în cazul în care mai multe aplicaţii vor folosi biblioteca.
Tipuri de tag-uri
Tag-urile customizate sunt scrise în XML. Ele vor avea un marcaj de început, unul de sfârşit şi un ´corp´ (conţinut). Iată un exemplu:
<tt:tag> corp tag </tt:tag>
Un tag care nu are corp se va declara după cum urmează:
<tt:tag />
Tagurile pot avea atribute, într-un mod oarecum similar cu tag-urile HTML.
Declaraţia unui atribut se face prin sintaxa attr="value" Scopul acestor
atribute este de a face tag-ul cât mai independent de aplicaţia unde va fi folosit,
cât mai general. Folosirea acestor atribute este încurajată în sensul de a realiza
aplicaţii modulare, care să nu necesite modificarea codului pentru tag-uri existente
deja. Iată un exemplu de atribut:
<tt:tag parameter="Test" />
Tagurile cu corp (body în literatura de specialitate) sunt în general mai complexe, dar şi mult mai utilizate şi folositoare. Iată în cele ce urmează un exemplu simplu:
<tt:test parameter="Test"> <font color="#ff0000" size="+2"><strong>
Doar un test pentru un tag cu body
</strong></font> </logic:present>
De asemenea tag-urile pot să fie (asemeni XML) imbricate, existând posibilitatea de a defini tag-uri în tag-uri (întregi ierarhii de astfel de structuri). Iată mai jos o posibilitate:
<tt:tagMare> <tt:tagMic /> </tt:tagMare>
Am vazut până acum ce sunt de fapt aceste tag-uri customizate. Să vedem acum de ce este nevoie pentru a scrie. Pentru a defini un tag, veţi urma etapele:
- dezvoltarea unui handler pentru tag
- declararea unui descriptor pentru acest tag
Un handler definit pentru un tag reprezintă un obiect invocat în timpul execuţiei paginii JSP care conţine tag-ul,
atunci când este parsată. O clasă de tip tag handler trebuie să implementeze una din interfeţele Tag sau BodyTag. Puteţi folosi şi clasele de bază create în acest sens de dezvoltatorii Java, TagSupport sau BodyTagSupport Clasele de mai sus sunt conţinute în pachetul javax.servlet.jsp.tagext. Documentaţia aferentă este recomandată pentru a înţelege mai bine modul de utilizare. Metodele ce sunt scrise în handlere sunt apelate în diferite momente ale evaluării şi utilizării tag-urilor.
Astfel, atunci când un început de tag este descoperit, se realizează apelul metodei doStartTag din handlerul tag-ului. Similar, la întâlnirea marcajului de final, se apelează metoda doEndTag Nu sunt singurele metode ce trebuie să fie implementate, iată o listă cu evenimentele ce se tratează, şi numele metodelor:
Acest tabel (sursă: java.sun.com) vă prezintă în coloana stangă tipul handler-ului care este tratat cu una din metodele din coloana dreaptă. De remarcat cazul tag-urilor imbricate, acolo unde un handler pentru un tag intern are acces la tag-ul ´părinte´.
În general după scrierea mai multor handlere care vor fi folosite într-o aplicaţie, acestea se pot arhiva (format JAR) şi se folosesc în această formă de către programatori.
Descriptori de biblioteci
TLD (Tag Library Descriptior) reprezintă de fapt un document XML care conţine informaţii standardizate despre fiecare tag conţinut în biblioteca descrisă. Aceste fişiere trebuie să aibă extensia .tld; de asemena un document tld este obligatoriu să înceapă cu un prolog XML care specifică versiunea XML folosită şi de asemenea data type definition (DTD) (vezi documentaţia XML). Despre conţinutul acestor fişiere vă lăsăm să descoperiţi singuri ce trebuie să conţină. Probabil că cel mai lejer este să luaţi un exemplu gata facut pe care să-l prelucraţi.
Câteva exemple
Dacă tot a venit vorba de exemple, iată câteva care să vă ajute să înţelegeţi ceva mai bine ceea ce am descris până acum; Menţionăm că aceste exemple sunt preluate de pe
site-uri web care se ocupă cu prezentarea tutorialelor despre JSP (www.java.sun.com www.javaworld.com etc).
1. Tag-uri simple
<tt:tag />
se va implementa:
public SimpleTag extends TagSupport { public int doStartTag() throws JspException { try { pageContext.getOut().print("Hello."); } catch (Exception ex) { throw new JspTagException("SimpleTag: " + ex.getMessage()); } return SKIP_BODY; } public int doEndTag() { return EVAL_PAGE; } }
2. Tag-uri cu atribute
Pentru fiecare atribut pe care-l definiţi în cadrul tag-ului, trebuie să fie implementate metode de tip get şi set în cadrul handler-ului. Iată şi un exemplu de acest fel:
<tt:tag parameter="Clear">
şi metodele aferente
protected String parameter = null; public String getParameter() { return (this.parameter); } public void setParameter(String parameter) { this.parameter = parameter; }
Pentru fiecare atribut pe care dorim să-l folosim într-un tag, sunt necesare precizări de genul: acest atribut trebuie este obligatoriu, ce tip are, etc.
Iată un exemplu de definire a unul atribut într-un tld
<attribute> <name>attr1</name> <required>true|false|yes|no</required> <rtexprvalue>true|false|yes|no</ rtexprvalue> <type>fully_qualified_type</type> </attribute>
Aceste declaraţii permit o validare a atributelor, foarte necesară pentru aplicaţiile profesionale.
3. Tag-uri cu body-uri
Implementarea handlerelor pentru acest tip de tag-uri presupune luarea în considerare a necesitătii (sau nu) a handlerului de a interacţiona cu corpul tag-ului. În cazul în care nu există interacţiune, atunci handlerul ar trebui să implementeze fie interfaţa Tag fie să deriveze clasa TagSupport. În al doi-lea caz, se va realiza implementarea interfeţei BodyTag, sau se va deriva clasa BodyTagSupport
În cazul interacţiunii cu body-ul tag-ului, sunt puse la dispoziţie o serie de metode speciale, precum
doInitBody: apelată după ce se detectează body-ul, dar înainte de a fi citit.
doAfterBody: se apelează dupa evaluarea body-ului.
Cum folosim JSTL (Java Standard Tag Library)
JSTL este o colecţie de tag-uri variate care oferă după cum vorbeam şi în numărul trecut o serie de marcaje foarte folositoare şi performante. Pentru a folosi JSTL într-o pagină JSP, trebuie să declarati acest lucru, după cum urmează:
<%@ taglib uri="/jstl-core" prefix="c" %>
Detalii despre JSTL găsiţi în documentaţiile disponibile pe site-urile dedicate
java, sau în materialele tipărite la noi în ţară. XML sau Conexiuni la bazele
de date sunt domenii tratate foarte bine de JSTL, şi multitudinea de tag-uri
disponibile are şanse mari să fie tot ce aveţi nevoie pentru a scrie cât mai
repede aplicaţii performante.
|