Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00803 010452 11035546 na godz. na dobę w sumie
JavaServer Pages. Leksykon kieszonkowy - książka
JavaServer Pages. Leksykon kieszonkowy - książka
Autor: Liczba stron: 120
Wydawca: Helion Język publikacji: polski
ISBN: 83-7197-674-7 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> jsp i javaservlet - programowanie
Porównaj ceny (książka, ebook, audiobook).
Java Server Pages (JSP) służy do tworzenia dynamicznych stron WWW, umożliwiając harmonijne połączenie dokonań projektantów i programistów. Wykorzystuje wielkie możliwości serwletów Javy do tworzenia efektywnych, uniwersalnych aplikacji sieciowych. JSP pozwala na projektowanie prężnie działających stron WWW o dużych możliwościach i -- co najważniejsze -- nie wymaga zaawansowanych umiejętności w dziedzinie programowania w Javie.

JavaServer Pages. Leksykon kieszonkowy stanowi dodatek do bestsellera wydawnictwa O'Reilly JavaServer Pages, również autorstwa Hansa Bergstena. Książka zawiera szczegółowe informacje na temat składni i przetwarzania JSP, elementów dyrektyw, elementów standardowych akcji, elementów skryptowych, obiektów niejawnych, akcji specjalizowanych, plików TLD i archiwów WAR.

Autor jest założycielem firmy Gefion Software. Hans Bergsten był również aktywnym uczestnikiem grup roboczych opracowujących specyfikacje serwletów Javy i JSP. Jako członek komitetu kierującego projektem Apache Jakarta wniósł istotny wkład w implementację wzorcową Apache Tomcat.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TRE(cid:140)CI SPIS TRE(cid:140)CI KATALOG KSI¥flEK KATALOG KSI¥flEK KATALOG ONLINE KATALOG ONLINE ZAM(cid:211)W DRUKOWANY KATALOG ZAM(cid:211)W DRUKOWANY KATALOG TW(cid:211)J KOSZYK TW(cid:211)J KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAM(cid:211)W INFORMACJE ZAM(cid:211)W INFORMACJE O NOWO(cid:140)CIACH O NOWO(cid:140)CIACH ZAM(cid:211)W CENNIK ZAM(cid:211)W CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥flEK ONLINE FRAGMENTY KSI¥flEK ONLINE Java Server Pages. Leksykon kieszonkowy Autor: Hans Bergsten T‡umaczenie: Adrian Nowak ISBN: 83-7197-674-7 Tytu‡ orygina‡u: JavaServer Pages. Pocket Reference Liczba stron: 118 Java Server Pages (JSP) s‡u¿y do tworzenia dynamicznych stron WWW, umo¿liwiaj„c harmonijne po‡„czenie dokonaæ projektant(cid:243)w i programist(cid:243)w. Wykorzystuje wielkie mo¿liwo(cid:156)ci serwlet(cid:243)w Javy do tworzenia efektywnych, uniwersalnych aplikacji sieciowych. JSP pozwala na projektowanie prŒ¿nie dzia‡aj„cych stron WWW o du¿ych mo¿liwo(cid:156)ciach i (cid:151) conajwa¿niejsze (cid:151) nie wymaga zaawansowanych umiejŒtno(cid:156)ci w(cid:160) dziedzinie programowania w Javie. JavaServer Pages. Leksykon kieszonkowy stanowi dodatek do bestsellera wydawnictwa O(cid:146)Reilly JavaServer Pages, r(cid:243)wnie¿ autorstwa Hansa Bergstena. Ksi„¿ka(cid:160) zawiera szczeg(cid:243)‡owe informacje na temat sk‡adni i przetwarzania JSP, element(cid:243)w dyrektyw, element(cid:243)w standardowych akcji, element(cid:243)w skryptowych, obiekt(cid:243)w niejawnych, akcji specjalizowanych, plik(cid:243)w TLD i archiw(cid:243)w WAR. Autor jest za‡o¿ycielem firmy Gefion Software. Hans Bergsten by‡ r(cid:243)wnie¿ aktywnym uczestnikiem grup roboczych opracowuj„cych specyfikacje serwlet(cid:243)w Javy i JSP. Jako(cid:160) cz‡onek komitetu kieruj„cego projektem Apache Jakarta wni(cid:243)s‡ istotny wk‡ad w(cid:160) implementacjŒ wzorcow„ Apache Tomcat. Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Przetwarzanie JSP ...................................................................... 6 Dyrektywy .................................................................................. 9 Elementy akcji standardowych................................................. 14 Komentarze............................................................................... 29 Blokowanie interpretacji znaków............................................. 30 Elementy skryptowe ................................................................. 31 Obiekty niejawne...................................................................... 36 Akcje specjalizowane ............................................................... 71 Tworzenie pliku opisu biblioteki znaczników (TLD) ............ 107 Pakowanie i instalacja biblioteki znaczników........................ 112 Pliki archiwów WWW (WAR) .............................................. 115  public void putValue(String name, Object value) Począwszy od specyfikacji Servlet 2.2 API metoda ta jest zastąpiona przez setAttribute(String, Object). public void removeValue(String name) Począwszy od specyfikacji Servlet 2.2 API metoda ta jest zastąpiona przez setAttribute(String, Object). -/74/-+3;+2/ Programista może rozszerzyć możliwości języka JSP, definiując akcje specjalizowane (ang. custom actions). Sposób ten pozwala na wykonanie dowolnych zadań nie przewidzianych w standar- dowych akcjach JSP, takich jak sprawdzenie poprawności da- nych lub zmiana sposobu ich prezentacji i lokalizacji. Składnia stosowana do wykorzystania akcji specjalizowanej jest taka sama jak dla akcji standardowych: otwarcie znacznika (opcjonalnie z atrybutami), ciało znacznika i zamknięcie znacz- nika. Inne elementy oraz treść szablonowa mogą być zagnież- dżone w ciele. A oto przykład: prefiks:nazwaAkcji atr1= value1 atr2= value2 Ciało znacznika /prefiks:nazwaAkcji Jeżeli znacznik nie ma ciała, zamiast pełnego otwarcia i za- mknięcia można zastosować notację skrótową: prefiks:nazwaAkcji atr1= value1 atr2= value2 / Zanim jednak wykorzystamy akcję specjalizowaną na stronie JSP, musimy zadeklarować, w jakiej bibliotece znaczników jest -/74/-+3;+2/  ona zawarta. W tym celu używamy dyrektywy taglib, wska- zując bibliotekę i przypisując jej prefiks, za pomocą którego będziemy identyfikować akcje w obrębie strony. $;36/2/+-74/-+3;+2- Akcja specjalizowana — a właściwie klasa obsługi znacznika (ang. tag handler class) dla akcji specjalizowanej — jest, ogól- nie rzecz biorąc, komponentem JavaBean. Jego metody usta- wiające właściwości odpowiadają atrybutom elementu akcji specjalizowanej. Ponadto klasa obsługi znacznika musi imple- mentować jeden z dwóch interfejsów Javy zdefiniowanych w specyfikacji JSP. Wszystkie interfejsy i klasy potrzebne do implementacji obsługi znacznika są zdefiniowane w pakiecie javax.servlet. jsp.tagext. Dwa podstawowe interfejsy to Tag i Body- Tag. Interfejs Tag określa metody konieczne do implementacji dla dowolnej akcji. Interfejs BodyTag natomiast rozszerza Tag, dodając do niego metody wykorzystywane w celu uzyskania dostępu do ciała znacznika. Aby ułatwić utworzenie klasy ob- sługi znacznika, w API zdefiniowano dwie klasy pomocnicze: TagSupport i BodyTagSupport (relacje między nimi uka- zuje rysunek 4.). Klasy te dostarczają domyślnej implementacji dla metod należących do odpowiednich interfejsów. Specyfikacja definiuje zarówno interfejsy, jak też wyczerpujące ich implementację klasy pomocnicze. Jeżeli mamy już klasę oferującą pewien zestaw funkcji i chcielibyśmy udostępnić ją jako akcję specjalizowaną, możemy zaznaczyć, że klasa imple- mentuje stosowny interfejs, i uzupełnić ją o metody określone w tym interfejsie. W praktyce jednak zalecane jest implemen- towanie własnych klas obsługi znaczników jako rozszerzeń klas  +:+#/6:/6 +1/7 /732/7323; 792/  3.78+;3;/28/60/7637/6+2+2+-2(cid:23); +73,7o91 pomocniczych. W ten sposób otrzymujemy większość metod „za darmo”, a istniejące klasy możemy wykorzystać, wywołu- jąc je z wnętrza klasy obsługi znacznika. Biblioteka znaczników (ang. tag library) jest zbiorem akcji specjalizowanych. Oprócz plików klas obsługi znaczników musi ona zawierać plik opisu biblioteki znaczników (Tag Library Descriptor, TLD). Jest to plik XML definiujący odwzorowanie między nazwami specjalizowanych akcji a odpowiednimi kla- sami obsługi znaczników oraz opisujący atrybuty obsługiwane przez każdą ze specjalizowanych akcji. Pliki klas oraz plik TLD mogą być spakowane do archiwum JAR, co ułatwia instalację biblioteki. -/74/-+3;+2/  Zanim zagłębimy się w zawiłe szczegóły, ustalmy, czego po- trzeba, aby stworzyć, zainstalować i wykorzystać akcję specja- lizowaną. Przede wszystkim musimy zaimplementować klasę obsługi znacznika, podobnie jak w przykładzie: package com.mycompany; import java.io.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class HelloTag extends TagSupport { private String name = World ; public void setName(String name) { this.name = name; } public int doEndTag() { try { pageContext.getOut().println( Hello + name); } catch (IOException e) {} // Ignore it return EVAL_PAGE; } } Klasa obsługi znacznika zawiera metodę ustawiającą wartość atrybutu o nazwie name. Metoda doEndTag() (zdefiniowana w interfejsie Tag) podaje jako odpowiedź tekst „Hello” oraz wartość atrybutu name. Klasę tę należy skompilować i umie- ścić plik wynikowy w katalogu WEB-INF/classes omawianej aplikacji. Następnie tworzymy plik TLD. Poniżej znajduje się minimalny plik TLD dla biblioteki zawierającej tylko jedną akcję specjali- zowaną: ?xml version= 1.0 encoding= ISO-8859-1 ?  +:+#/6:/6 +1/7 /732/7323; !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 test /shortname tag name hello /name tagclass com.mycompany.HelloTag /tagclass bodycontent empty /bodycontent attribute name name /name /attribute /tag /tablib Plik TLD przyporządkowuje nazwę akcji specjalizowanej hello klasie obsługi znacznika com.mycompany.HelloTag i defi- niuje atrybut name. Plik ten umieszczamy w katalogu WEB- INF/tlds aplikacji, nadając mu nazwę taką jak mylib.tld. Teraz możemy już wykorzystać akcję specjalizowaną na stronie JSP, na przykład w taki sposób: @ taglib uri= /WEB-INF/mylib.tld prefix= test html body bgcolor= white test:hello name= Hans / /body /html Dyrektywa taglib wiąże plik TLD z prefiksem nazwy ele- mentu test, użytego na naszej stronie do wywołania akcji spe- cjalizowanej. Kiedy pojawia się żądanie strony, kontener sieciowy wykorzystuje TLD, aby stwierdzić, którą klasę należy -/74/-+3;+2/  wykonać dla akcji specjalizowanej. Następnie wywołuje sto- sowne metody, co skutkuje włączeniem do odpowiedzi tekstu „Hello Hans”. -/74/-+3;+2/(cid:20) 8(cid:22)6/2/46/8;+6+-+o+2+-2+ Klasa obsługi znacznika jest przywoływana przez kontener sieciowy, ilekroć na stronie JSP występuje akcja specjalizowana. Wymaga ona dostępu do wszystkich informacji o żądaniu i o stro- nie, a także o wartościach atrybutów elementu akcji (jeżeli takie istnieją). Jako minimum klasa ta musi implementować interfejs Tag, który zawiera metody umożliwiające jej dostęp do infor- macji o stronie i o żądaniu, jak również metody wywoływane przez kontener w momencie napotkania otwarcia znacznika i zamknięcia znacznika. Jeśli chodzi o wartości atrybutów, to kontener sieciowy traktuje klasę obsługi znacznika jako komponent bean i wywołuje metody ustawiające właściwości, które odpowia- dają atrybutom elementu akcji, co pokazano na rysunku 5. 792/ /83.28/60/79$+1/83.978+;+2+ ;o+-;3-  +:+#/6:/6 +1/7 /732/7323; Przeważnie klasa obsługi znacznika jest rozszerzeniem klasy Tag- Support (która dostarcza domyślnej implementacji wszystkich metod interfejsu Tag) i przesłania tylko jedną z metod. Zauważmy, że chociaż element akcji obsługiwany przez klasę implementującą interfejs Tag może mieć ciało, to jednak kon- trola nad jego zawartością będzie bardziej ograniczona niż w przypadku zaimplementowania interfejsu BodyTag. 28/60/7$+1 +;+28/60/79 37/6+ 4//283;+246/ javax.servlet.jsp. tagext.Tag — klasy obsługi znaczników akcji specjalizowanych oraz javax.servlet.jsp. tagext.TagSupport 47 Interfejs Tag powinien być implementowany przez klasy ob- sługi znaczników, które nie wymagają dostępu do ciała odpo- wiedniego elementu akcji specjalizowanej i nie muszą po nim iterować. /83. public int doEndTag() throws JspException Wykonuje odpowiednie działania, gdy napotykane jest do- mknięcie znacznika. Jeżeli metoda ta zwraca SKIP_PAGE, pozostała część strony nie jest wykonywana i następuje po- wrót z metody _jspService() klasy implementującej -/74/-+3;+2/  stronę JSP. Jeżeli zwracana jest wartość EVAL_PAGE, wy- konywany jest kod następujący po specjalizowanej akcji w metodzie _jspService(). public int doStartTag throws JspException Rozpoczyna działanie, kiedy napotykane jest otwarcie znacznika. Metodę tę wywołuje kontener sieciowy, gdy zo- stały już wywołane wszystkie metody ustawiające wartości właściwości. Zwracana wartość decyduje o tym, w jaki spo- sób traktowane jest ciało akcji, o ile takie istnieje. Jeżeli wynikiem jest EVAL_BODY_INCLUDE, kontener sieciowy przetwarza ciało i ewentualne elementy JSP, dodając efekty tego działania do odpowiedzi. Jeżeli zwracana jest wartość SKIP_BODY, ciało jest ignorowane. Klasa obsługi znacznika, która implementuje interfejs Body- Tag (rozszerzający interfejs Tag), może zwrócić EVAL_BO- DY_TAG zamiast EVAL_BODY_INCLUDE. Kontener siecio- wy tworzy wtedy instancję BodyContent i udostępnia ją klasie obsługi znacznika w celu przeprowadzenia działań na ciele elementu akcji. public Tag getParent() Zwraca rodzica klasy obsługi znacznika (egzemplarz obiektu Tag dla zewnętrznego elementu akcji, jeśli taki istnieje lub null w przeciwnym wypadku). public void release() Zwalnia wszystkie referencje przechowywane przez obiekt. public void setPageContext(PageContext pc) Ustawia referencję do bieżącego obiektu PageContext.  +:+#/6:/6 +1/7 /732/7323; public void setParent(Tag t) Ustawia referencję do rodzica klasy obsługi znacznika (obiektu Tag dla zewnętrznego elementu akcji). +7+$+1#944368 +;++7 37/6+ 4//289/ javax.servlet.jsp. tagext.TagSupport — Tag, java.io. Serializable 4//283;+2+46/ wewnętrzne klasy, zależne od kontenera sieciowego. Większość kontenerów wykorzystuje wzorcową implementację klasy (stworzoną dla projektu Apache Jakarta) 47 TagSupport jest klasą pomocniczą, która dostarcza domyślnej implementacji dla wszystkich metod interfejsu Tag. W zamie- rzeniu ma być wykorzystywana jako nadklasa dla klas obsługi znaczników, które nie wymagają dostępu do ciał odpowiadają- cych im elementów akcji specjalizowanych. 327869836 public TagSupport() Tworzy nową instancję o wskazanej nazwie i wartości. -/74/-+3;+2/  /83. public int doEndTag() throws JspException Zwraca stałą EVAL_PAGE. public int doStartTag() throws JspException Zwraca stałą SKIP_BODY. public static final Tag findAncestorWithClass (Tag from, Class class) Zwraca instancję danej klasy, odnalezioną przez sprawdzanie kolejnych rodziców w strukturze zagnieżdżeń klasy obsługi znacznika (analogicznej do struktury zagnieżdżeń ele- mentów akcji), począwszy od obiektu Tag. Jeśli poszuki- wanie się nie powiedzie, zwraca wartość null. public String getId() Zwraca wartość atrybutu id (lub null, jeśli nie został on ustawiony). public Tag getParent() Zwraca rodzica instancji Tag (reprezentującego element ak- cji, który zawiera element odpowiadający tej instancji). Jeżeli instancja nie ma rodzica (tzn. jest na najwyższym poziomie w stronie JSP), metoda zwraca null. public Object getValue(String k) Zwraca wartość wskazanego atrybutu, ustawioną uprzednio metodą setValue(), lub null, jeśli jej nie odnajdzie. public java.util.Enumeration getValues() Zwraca obiekt Enumeration zawierający nazwy wszyst- kich atrybutów, których wartości zostały ustawione za po- mocą metody setValue().  +:+#/6:/6 +1/7 /732/7323; public void release() Zwalnia wszystkie referencje przechowywane przez obiekt. public void removeValue(String k) Zwalnia wartość ustawioną metodą setValue(). public void setPageContext(PageContext pageContext) Ustawia referencję do bieżącego obiektu PageContext. public void setId(String id) Ustawia wartość atrybutu id. public void setParent(Tag t) Ustawia referencję do rodzica klasy obsługi znacznika. public void setValue(String k, Object o) Ustawia dany atrybut przypisując mu wskazaną wartość. Podklasy mogą wykorzystywać tę metodę jako alternatywę dla stosowania zmiennych składowych. 6o+. Przykładem akcji specjalizowanej, możliwej do zaimplemento- wania jako prosta klasa obsługi znacznika (tzn. implementująca jedynie interfejs Tag), jest akcja, która dodaje cookie do odpo- wiedzi HTTP. Nazwijmy tę akcję ora:addCookie . Klasa obsługi nazywa się com.ora.jsp.tags.generic.Add- CookieTag i rozszerza klasę TagSupport, dziedzicząc więk- szość implementacji metod interfejsu Tag: package com.ora.jsp.tags.generic; import javax.servlet.http.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import com.ora.jsp.util.*; public class AddCookieTag extends TagSupport { -/74/-+3;+2/  Akcja ora:addCookie ma dwa obowiązkowe atrybuty, name i value , oraz jeden opcjonalny, maxAge. Każdy atry- but jest reprezentowany przez zmienną składową i standardową metodę ustawiającą właściwość: private String name; private String value; private String maxAgeString; public void setName(String name) { this.name = name; } public void setValue(String value) { this.value = value; } public void setMaxAge(String maxAgeString) { this.maxAgeString = maxAgeString; } Wszystkie metody ustawiające zmieniają wartości odpowiada- jących im zmiennych składowych. Celem naszej akcji specjalizowanej jest utworzenie nowego obiektu javax.servlet.Cookie z wartościami name, value i maxAge, określonymi przez atrybuty i dodanie cookie do odpowiedzi. Klasa obsługi znacznika nadpisuje metodę do- EndTag(), aby wykonać to zadanie: public int doEndTag() throws JspException { int maxAge = -1; if (maxAgeString != null) { try { maxAge = Integer.valueOf (maxAgeString). intValue(); }  +:+#/6:/6 +1/7 /732/7323; catch (NumberFormatException e) { throw new JspException( Invalid maxAge: + e.getMessage()); } } sendCookie(name, value, maxAge, (HttpServletResponse) pageContext.getResponse()); return EVAL_PAGE; } private void sendCookie(String name, String value, int maxAge, HttpServletResponse res) { Cookie cookie = new Cookie(name, value); cookie.setMaxAge(maxAge); res.addCookie(cookie); } Atrybut maxAge jest opcjonalny, zanim więc odpowiednia wartość String zostanie skonwertowana na typ int, spraw- dzamy, czy została ona zdefiniowana. Podobne testy nie są konieczne dla zmiennych name i value , ponieważ wszystkie obowiązkowe atrybuty akcji specjalizowanej są weryfikowane automatycznie przez kontener sieciowy. Jeżeli nie podano war- tości obowiązkowego atrybutu, kontener odmówi przetworzenia strony — można więc zawsze mieć pewność, że zmiennej od- powiadającej atrybutowi obowiązkowemu została przypisana wartość. Informacja, czy atrybut jest obowiązkowy, jest wyspe- cyfikowana w pliku TLD. Klasa obsługi znacznika powinna także implementować metodę release(), aby zwolnić wszystkie przechowywane referencje: public void release() { name = null; value = null; -/74/-+3;+2/  maxAgeString = null; super.release(); } Metoda release() zostaje wywołana w momencie, gdy obiekt klasy obsługi znacznika nie jest już potrzebny. Klasa AddCoo- kieTag ustawia wszystkie swoje właściwości na null, po czym wywołuje super.release(), aby klasa TagSupport mogła zadziałać tak samo. W rezultacie zostają udostępnione obiekty, które były przyporządkowane właściwościom, mecha- nizmowi odśmiecania pamięci. Metodą klasy TagSupport niepotrzebną w tym przykładzie, lecz pożyteczną w innych sytuacjach, jest metoda findAnce- storWithClass(). Może ona zostać wykorzystana przez klasę obsługi w celu odnalezienia rodzica zagnieżdżonego ele- mentu akcji, a następnie wywołania metod implementowanych przez jego klasę obsługi dla dostarczenia lub pobrania niektó- rych informacji. W ten sposób można by na przykład operować na elementach jsp:param zagnieżdżonych wewnątrz elementów standardowych akcji JSP: jsp:forward oraz jsp:include . Równoważna akcja specjalizowana dla za- gnieżdżonych parametrów byłaby zaimplementowana jako klasa obsługi znacznika, wykorzystująca metodę findAncestor- WithClass() w poniższy sposób: import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class ParamTag extends TagSupport { private String name; private String value; public void setName(String name) { this.name = name; }  +:+#/6:/6 +1/7 /732/7323; public void setValue(String value) { this.value = value; } public int doEndTag() throws JspException { Tag parent = findAncestorWithClass(this, ParamParent.class); if (parent == null) { throw new JspException( Akcja param nie jest umieszczona + wewnatrz akcji obslugiwanego typu ); } ParamParent paramParent = (ParamParent) parent; paramParent.setParam(name, URLEncoder. encode(value)); return EVAL_PAGE; } } -/74/-+3;+2/(cid:20) 46/8;+6+-/-+o32+-2+ Jak widać, nietrudno jest stworzyć klasę obsługi znacznika, która nie zajmuje się ciałem elementu akcji. Jeżeli ma ona przetwarzać ciało, potrzebnych jest jeszcze kilka dodatkowych metod. Zo- stały one zdefiniowane w interfejsie BodyTag, rozszerzającym interfejs Tag. Treść elementu akcji możne zostać wykorzystana w wielu przy- padkach — na przykład wtedy, gdy mamy do czynienia z da- nymi wejściowymi zajmującymi kilka linijek tekstu. Załóżmy, że tworzymy akcję specjalizowaną mającą wykonać instrukcję SQL, wyspecyfikowaną przez autora strony. Polecenia SQL są przeważnie długie, lepiej więc pozwolić, by autor napisał je w treści znacznika, zamiast zmuszać go do upchnięcia ich w jednej -/74/-+3;+2/  linii, co jest wymagane w przypadku atrybutów akcji. Można również wykorzystać ciało elementu akcji, przetwarzając je w jakiś szczególny sposób przed dodaniem do odpowiedzi (na przykład zmienić treść XML według arkusza stylów XSL, wy- specyfikowanego jako atrybut). Podobnie jak dla interfejsu Tag, również dla interfejsu Body- Tag istnieje klasa BodyTagSupport implementująca wszyst- kie jego metody oraz kilka metod narzędziowych. Klasa obsługi znacznika implementująca interfejs BodyTag traktowana jest początkowo tak samo, jak klasa implementująca interfejs Tag: kontener wywołuje wszystkie metody ustawiania właściwości oraz metodę doStartTag(). W tym momencie jednak postępowanie odbiega od poprzedniego schematu, co widać na rysunku 6. 792/ /83.28/60/793.$+1 Dodatkowe metody setBodyContent(), doInitBody() i doAfterBody() umożliwiają klasie dostęp do ciała elementu i dają sposobność jego przetworzenia, co opisano poniżej.  +:+#/6:/6 +1/7 /732/7323; 28/60/73.$+1 +;++7 37/6+ 4//283;+246/ javax.servlet.jsp. tagext.BodyTag javax.servlet.sjp. tagext.Tag klasy obsługi znaczników specjalizowanych akcji oraz javax.servlet.jsp. tagext.BodyTagSupport 47 Interfejs BodyTag musi być implementowany przez każdą klasę obsługi znacznika, która wymaga dostępu do ciała elementu i odpowiadającej znacznikowi akcji specjalizowanej — na przy- kład, aby przekształcić zawartość w pewien sposób przed dołą- czeniem jej do odpowiedzi. Również klasy, które mają iterować po ciele, muszą implementować ten interfejs. /83. public int doAfterBody() throws JspException Wywoływana jest za każdym razem, kiedy kończy się warto- ściowanie ciała. Jeżeli metoda ta zwraca EVAL_BODY_TAG, ciało jest wartościowane ponownie, przeważnie po zmianie wartości wykorzystywanych zmiennych. Jeżeli zwraca SKIP_BODY, następuje wywołanie metody doEndTag(). Metoda doAfterBody() nie jest wywoływana, jeśli ciało elementu jest puste lub jeśli metoda doStartTag() zwró- ciła stałą SKIP_BODY. -/74/-+3;+2/  public void doInitBody() throws JspException Przeprowadza przygotowania do wartościowania ciała ele- mentu. Jest wywoływana przez implementację strony jedno- krotnie przy każdym wystąpieniu akcji, po otrzymaniu nowego obiektu BodyContent i ustawieniu referencji do niego metodą setBodyContent(), natomiast przed przeprowa- dzeniem wartościowania ciała elementu. Metoda doInitBody() nie jest wywoływana, jeśli ciało elementu jest puste lub metoda doStartTag() zwróciła stałą SKIP_BODY. public void setBodyContent (BodyContent b) Ustawia referencję do obiektu BodyContent utworzonego dla bieżącego znacznika. Ta metoda nie zostanie wywołana, jeżeli ciało jest puste lub jeśli metoda doStartTag() zwróciła stałą SKIP_BODY. +7+3.$+1#944368 +;++7 37/6+ javax.servlet.jsp. tagext.BodyTagSupport javax.servlet.jsp. tagext.TagSupport 4//289/ 4//283;+2+46/ wewnętrzne klasy, zależne od BodyTag kontenera sieciowego. Większość kontenerów wykorzystuje wzorcową implementację klasy (stworzoną dla projektu Apache Jakarta)  +:+#/6:/6 +1/7 /732/7323; 47 BodyTagSupport jest klasą pomocniczą, która dostarcza domyślnych implementacji dla wszystkich metod interfejsu BodyTag. W zamierzeniu powinna być wykorzystywana jako nadklasa dla klas obsługi wymagających dostępu do ciała elementu, odpowiadającej znacznikowi akcji specjali- zowanej. 327869836 public BodyTagSupport() Tworzy nową instancję BodyTagSupport. /83. public int doAfterBody() throws JspException Zwraca SKIP_BODY. public int doEndTag() throws JspException Zwraca EVAL_PAGE. public void doInitBody() W tej klasie nie wykonuje żadnego działania. public BodyContent getBodyContent() Zwraca przypisany do tego egzemplarza obiekt BodyCon- tent. public JspWriter getPreviousOut() Zwraca obiekt JspWriter, zewnętrzny dla obiektu Bo- dyContent przypisanego temu egzemplarzowi. -/74/-+3;+2/  public void release() Usuwa referencje do wszystkich obiektów przechowywa- nych przez tę składową. public void setBodyContent(BodyContent bodyContent) Ustawia referencję do obiektu BodyContent — przypisa- nego egzemplarzowi — jako zmienną składową. +7+3.328/28 +;++7 37/6+ javax.servlet.jsp. tagext.BodyContent javax.servlet.jsp. JspWriter 4//289/ 4//283;+2+46/ wewnętrzne klasy zależne od — kontenera 47 Kontener tworzy instancję klasy BodyContent w celu przecho- wania wyniku przetworzenia ciała elementu akcji, jeśli odpowia- dająca tej akcji klasa obsługi implementuje interfejs BodyTag. Kontener udostępnia obiekt BodyContent klasie obsługi znacz- nika przez wywołanie metody setBodyContent(). 327869836 protected BodyContent(JspWriter e) Tworzy nowy egzemplarz obiektu, przypisując mu jako zewnętrzny obiekt JspWriter wartość argumentu.  +:+#/6:/6 +1/7 /732/7323; /83. public void clearBody() Usuwa całą treść znajdującą się w buforze obiektu. public void flush() throws java.io.IOException Nadpisuje zachowanie odziedziczone po JspWriter tak, aby zawsze zgłaszany był wyjątek IOException, ponieważ wywo- łanie flush() dla obiektu BodyContent nie ma sensu. public JspWriter getEnclosingWriter() Zwraca zewnętrzny obiekt JspWriter; innymi słowy, jest to obiekt JspWriter najwyższego poziomu na stronie lub przypisany rodzicowi klasy obsługi znacznika. public abstract java.io.Reader getReader() Zwraca bieżący obiekt jako obiekt Reader z zawartością otrzymaną przez wartościowanie ciała elementu. public abstract String getString() Zwraca bieżący obiekt jako String z zawartością otrzy- maną przez wartościowanie ciała elementu. public abstract void writeOut (java.io.Writer out) throws java.io.IOException Wypisuje zawartość obiektu BodyContent do obiektu Writer. 6o+. Rozpatrzmy przykład klasy obsługi znacznika rozszerzającej klasę BodyTagSupport. Klasa EncodeHTMLTag odpowiada akcji specjalizowanej o nazwie ora:encodeHTML . Akcja ta -/74/-+3;+2/  odczytuje ciało elementu; zastępuje ona wszystkie znaki o specjal- nym znaczeniu w HTML, takie jak cudzysłowy, znaki mniejszości i większości oraz ampersandy, odpowiadającymi im symbolami HTML ( #39;, #34;, lt;, gt;, amp;), po czym wsta- wia otrzymany ciąg do odpowiedzi. Następujący przykład poka- zuje, w jaki sposób można wykorzystać tę akcję na stronie JSP: @ page language= java @ taglib uri= /orataglib prefix= ora html head title Próbka zakodowanego HTML /title /head body h1 Próbka zakodowanego HTML /h1 Następujący tekst został zakodowany przez specjalizowaną akcję lt;ora:encodeHTML gt;: pre ora:encodeHTML Dokumenty HTML 3.2 rozpoczynają się deklaracją !DOCTYPE po której następuje element HTML zawierający elementy HEAD i BODY: !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 3.2 Final//EN HTML HEAD TITLE Analiza rozwoju populacji /TITLE ... inne elementy nagłówka /HEAD BODY ... ciało dokumentu /BODY /HTML /ora:encodeHTML /pre /body /html  +:+#/6:/6 +1/7 /732/7323; Należy zwrócić uwagę, że ciało akcji ora:encodeHTML na przykładowej stronie JSP zawiera elementy HTML. Jeżeli znaki specjalne nie zostaną skonwertowane na symbole, prze- glądarka zinterpretuje je jako HTML i na ekranie ukaże się wynik tej interpretacji zamiast właściwych znaczników. Dzięki konwersji wykonanej przez akcję specjalizowaną strona zostaje jednak przetworzona poprawnie (rysunek 7.). 792/ 3.$46/8;363246/+-( 36+/2-3./$ Poza statycznym tekstem ciało akcji może zawierać dowolny element JSP. Bardziej realistyczny przykład wykorzystania tej akcji to umieszczenie na stronie JSP tekstu pobranego z bazy danych, bez przejmowania się tym, w jaki sposób znaki spe- cjalne będą zinterpretowane przez przeglądarkę. Klasa obsługi znacznika jest całkiem banalna, co ukazano poniżej: -/74/-+3;+2/  package com.ora.jsp.tags.generic; import java.io.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import com.ora.jsp.util.*; public class EncodeHTMLTag extends BodyTagSupport { public int doAfterBody() throws JspException { BodyContent bc = getBodyContent(); JspWriter out = getPreviousOut(); try { out.write (toHTMLString(bc.getString())); } catch (IOException e) {} // Ignore return SKIP_BODY; } private String toHTMLString(String in) { StringBuffer out = new StringBuffer(); for (int i = 0; in != null i in.length(); i++) { char c = in.charAt(i); if (c == ) { out.append( #39; ); } else if (c == ) { out.append( #34; ); } else if (c == ) { out.append( lt; ); } else if (c == ) { out.append( gt; ); } else if (c == ) { out.append( amp; ); }  +:+#/6:/6 +1/7 /732/7323; else { out.append(c); } } return out.toString(); } } Akcja nie ma żadnych atrybutów, w klasie nie są więc potrzeb- ne żadne zmienne składowe ani metody je ustawiające. Można wykorzystać wszystkie metody interfejsu BodyTag imple- mentowane przez klasę BodyTagSupport, z wyjątkiem me- tody doAfterBody(). W metodzie doAfterBody() korzystamy z dwu metod narzę- dziowych dostarczanych przez klasę BodyTagSupport. Metoda getBodyContent() zwraca referencję do obiektu Body- Content zawierającego wyniki przetworzenia ciała akcji. Me- toda getPreviousOut() zwraca obiekt BodyContent dla akcji zewnętrznej (jeśli taka istnieje) lub główny obiekt Jsp- Writer, jeżeli akcja znajduje się na najwyższym poziomie w stronie. Można by się zastanawiać, dlaczego metoda ta nosi nazwę get- PreviousOut(), a nie getOut(). Nazwa ta ma na celu pod- kreślenie tego, że chcemy wykorzystać obiekt przypisany jako wyjście dla elementu zewnętrznego w hierarchii zagnieżdżo- nych elementów akcji. Załóżmy, że na stronie występują nastę- pujące elementy: xmp:foo xmp:bar Jakiś tekst szablonowy /xmp:bar /xmp:foo -/74/-+3;+2/  Kontener sieciowy najpierw tworzy obiekt JspWriter i przypi- suje go zmiennej out strony. Kiedy napotyka akcję xmp:foo , tworzy obiekt BodyContent i tymczasowo przyporządkowuje go zmiennej out. Potem tworzy kolejny obiekt BodyCon- tent dla akcji xmp:bar i ponownie przypisuje go zmien- nej out. Kontener zapamiętuje tę hierarchię przypisań. Tekst szablonowy i to, co przekazują na wyjście elementy standardo- wych akcji, trafia do bieżącego obiektu wyjścia. Każdy element może uzyskać dostęp do przypisanego mu obiektu BodyCon- tent, wywołując metodę getBodyContent() i odczytując zawartość. Dla elementu xmp:bar zawartością jest tekst szablonowy. Po przetworzeniu jego treści może zapisać wynik w ciele znacznika xmp:foo , docierając do przypisanego mu obiektu BodyContent przez wywołanie metody getPrevi- ousOut(). Ostatecznie element xmp:foo przetwarza treść dostarczoną mu przez xmp:bar i wypisuje ją do obiektu wyjścia najwyższego poziomu: obiektu JspWriter, do które- go dostęp otrzymuje poprzez wywołanie metody getPrevi- ousOut(). Klasa obsługi znacznika w tym przykładzie konwertuje wszyst- kie znaki specjalne, jakie napotka w przypisanym sobie obiekcie BodyContent, za pomocą metody toHTMLString(). Wyko- rzystując metodę getString() uzyskuje dostęp do zawartości BodyContent i używa jej jako argumentu dla toHTML- String(). Wynik jest zapisywany do obiektu JspWriter otrzymanego przez wywołanie getPreviousOut(). Przedstawiona powyżej przykładowa metoda doAfterBody() zwraca stałą SKIP_BODY, co sygnalizuje kontenerowi, że w na- stępnej kolejności powinien wywołać doEndTag(). W klasie obsługi akcji, przeprowadzającej iterację po treści znacznika,  +:+#/6:/6 +1/7 /732/7323; metoda doAfterBody() może zwrócić EVAL_BODY_TAG. Wtedy kontener przeprowadza ponowne wartościowanie ciała, zapisując wynik do obiektu BodyContent odpowiadającego elementowi, i wywołuje metodę doAfterBody(). Proces ten jest powtarzany, dopóki metoda doAfterBody() nie zwróci stałej SKIP_BODY. -/8;36-/3,/8 Akcje mogą współpracować ze sobą za pośrednictwem obiek- tów dostępnych w standardowych zasięgach JSP (strony, żąda- nia, sesji i aplikacji). Przykład tego typu współpracy stanowi działanie trzech standardowych akcji JSP: jsp:useBean , jsp:setProperty i jsp:getProperty . Akcja jsp:useBean tworzy nowy obiekt i udostępnia go w jed- nym z zasięgów JSP. Dwie pozostałe mogą następnie uzyskać dostęp do właściwości obiektu, szukając go w zasięgach. Poza udostępnieniem obiektu w jednym z zasięgów, akcja jsp: useBean czyni go także osiągalnym jako zmienną skrypto- wą, tak, aby mogły mieć do niego dostęp elementy skryptowe w obrębie strony. Według specyfikacji JSP 1.1 zmienna utworzona przez akcję musi mieć nazwę taką, jak wartość atrybutu id. Wartość ta musi być unikalna w obrębie strony. Skoro będzie wykorzysty- wana jako zmienna skryptowa, musi również stosować się do reguł nazewnictwa zmiennych języka skryptowego. W Javie oznacza to, że zaczyna się literą, po której następuje kombinacja liter i cyfr, i nie może zawierać znaków specjalnych, takich jak kropka lub znak dodawania. Atrybut używany w innej akcji do odwoływania się do tej zmiennej może mieć dowolną nazwę, jednak według konwencji przyjętej dla akcji standardowych nosi on nazwę name. -/74/-+3;+2/  W celu utworzenia zmiennej skryptowej akcja specjalizowana musi współpracować z kontenerem sieciowym. Aby zrozumieć, jak działa ten mechanizm, warto przypomnieć, że strona JSP jest przekształcana przez kontener w serwlet. W pierwszej ko- lejności kontener generuje kod, w którym deklarowana jest zmienna skryptowa dla tworzonego serwletu, i przypisuje tej zmiennej wartość. Aby to zrobić, musi znać nazwę zmiennej i jej typ w Javie. Informację tę należy dostarczyć kontenerowi za pośrednictwem podklasy TagExtraInfo dla akcji specja- lizowanej. Kontener wywołuje metodę getVariableInfo() podklasy TagExtraInfo zdefiniowanej dla specjalizowanej akcji, kiedy konwertuje stronę JSP na serwlet. Metoda ta zwraca tablicę instancji VariableInfo, dostarczając informacji wy- maganych dla zmiennych tworzonych przez akcję specjalizo- waną. Następnie klasa obsługi znacznika musi umieścić obiekt w jednym z zasięgów JSP, wykorzystując metodę setAt- tribute() obiektu PageContext. Wygenerowany kod uży- wa potem metody findAttribute(), aby odzyskać obiekt i przypisać go zmiennej skryptowej. +7+$+186+203 +;++7 javax.servlet.jsp. tagext.TagExtraInfo 37/6+ 4//289/ 4//283;+2+46/ wewnętrzne klasy zależne od — — kontenera. Większość kontenerów wykorzystuje wzorcową implementację klasy, stworzoną dla projektu Apache Jakarta  +:+#/6:/6 +1/7 /732/7323; 47 Podklasa klasy TagExtraInfo musi być stworzona i zade- klarowana w TLD dla akcji specjalizowanych, które tworzą zmienne skryptowe lub wymagają dodatkowego czasu przy translacji na sprawdzenie poprawności atrybutów znacznika. Kontener sieciowy tworzy egzemplarz obiektu TagExtra- Info w fazie tłumaczenia. 327869836 public TagExtraInfo() Tworzy nową instancję klasy TagExtraInfo. /83. public TagInfo getTagInfo() Zwraca instancję TagInfo dla akcji specjalizowanej związa- nej z bieżącym egzemplarzem TagExtraInfo. Referencja do obiektu TagInfo jest ustawiana przy wykorzystaniu meto- dy setTagInfo(), wywoływanej przez kontener sieciowy. public VariableInfo[] getVariableInfo(TagData data) Zwraca tablicę VariableInfo[] zawierającą informacje o zmiennych skryptowych, utworzonych przez klasę obsługi znacznika związaną z bieżącym egzemplarzem TagEx- traInfo. Domyślna implementacja zwraca pustą tablicę. Podklasa musi nadpisać tę metodę, jeśli odpowiadająca jej klasa obsługi tworzy zmienne skryptowe. public boolean isValid(TagData data) Zwraca true, jeśli zbiór wartości atrybutów wyspecyfiko- wanych dla akcji specjalizowanej związanej z bieżącym -/74/-+3;+2/  egzemplarzem TagExtraInfo jest poprawny, w przeciw- nym wypadku — false. Domyślna implementacja zwraca true. Podklasa może nadpisać tę metodę, jeżeli sprawdze- nie poprawności dokonane przez kontener sieciowy na pod- stawie informacji zawartych w TLD jest niewystarczające. public void setTagInfo(TagInfo tagInfo) Ustawia referencję do obiektu TagInfo dla tego egzempla- rza. Tę metodę wywołuje kontener sieciowy przed wykorzy- staniem jakiejkolwiek innej metody. +7+ +6+,/203 +;++7 javax.servlet.jsp. tagext.VariableInfo 37/6+ 4//289/ 4//283;+2+46/ wewnętrzne klasy zależne od — — kontenera. Większość kontenerów wykorzystuje wzorcową implementację klasy, stworzoną dla projektu Apache Jakarta 47 Instancje VariableInfo są tworzone przez podklasy Tag- ExtraInfo w celu opisania każdej zmiennej skryptowej stwo- rzonej przez odpowiednią klasę obsługi znacznika. +:+#/6:/6 +1/7 /732/7323; 327869836 public VariableInfo(String varName, String className, boolean declare, int scope) Tworzy nową instancję według wyspecyfikowanych wartości. /83. public String getClassName() Zwraca typ Javy dla zmiennej skryptowej. public boolean getDeclare() Zwraca wartość true, jeśli kontener sieciowy tworzy in- strukcję deklaracji dla zmiennej skryptowej; w przeciwnym wypadku zwraca false (wykorzystywana, jeśli zmienna została już zadeklarowana przez inną klasę obsługi znaczni- ka i jest jedynie aktualizowana przez klasę obsługi odpo- wiadającą podklasie TagExtraInfo, która stworzyła ten egzemplarz VariableInfo). public int getScope() Zwraca jedną ze stałych: AT_BEGIN (udostępniającą zmien- ną skryptową od otwarcia znacznika do końca strony JSP), AT_END (udostępniającą zmienną od zamknięcia znacznika do końca strony JSP) lub NESTED (udostępniającą zmienną jedynie między otwarciem i zamknięciem znacznika). public String getVarName() Zwraca nazwę zmiennej. 6o+. Poniżej podano przykład podklasy TagExtraInfo dla akcji specjalizowanej, która tworzy zmienną o nazwie wskazanej przez atrybut id oraz typie Javy wyspecyfikowanym przez atrybut className: -/74/-+3;+2/ package com.ora.jsp.tags.generic; import javax.servlet.jsp.tagext.*; public class UsePropertyTagExtraInfo extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { return new VariableInfo[] { new VariableInfo( data.getAttributeString( id ), data.getAttributeString( className ), true, VariableInfo.AT_END) }; } } Kontener sieciowy wywołuje metodę getVariableInfo() podczas fazy translacji. Zwraca ona tablicę obiektów Vari- ableInfo, po jednym dla każdej zmiennej wprowadzonej przez klasę obsługi znacznika. Klasa VariableInfo to prosty komponent bean z czterema właściwościami, inicjalizowanymi przez wartości przekazywa- ne jako argumenty do konstruktora: varName, className, declare i scope ; varName jest nazwą zmiennej skrypto- wej, a className to jej klasa. Właściwość declare jest typu boolean, przy czym wartość true oznacza, że akcja tworzy nową zmienną skryptową (czyli do generowanego serwletu trzeba dodać instrukcję deklaracji zmiennej). Wartość false oznacza, że zmienna została stwo- rzona wcześniej przez inną akcję lub inne wystąpienie tej samej akcji, a zatem wygenerowany kod zawiera już stosowną dekla- rację. W tym przypadku kontener jedynie przyporządkowuje zmiennej nową wartość. Właściwość scope nie ma nic wspólnego z zasięgami JSP, z którymi mieliśmy do czynienia do tej pory (zasięgi strony,  +:+#/6:/6 +1/7 /732/7323; żądania, sesji i aplikacji). Definiuje ona natomiast, gdzie nowa zmienna będzie dostępna dla elementów skryptowych JSP. Wartość AT_BEGIN oznacza, że zmienna jest dostępna po- cząwszy od otwarcia znacznika akcji, AT_END zaś — dopiero po zamknięciu znacznika. Z kolei stała NESTED udostępnia zmienną jedynie w ciele akcji, pomiędzy otwarciem i zamknięciem znacznika. Wartość scope kontroluje zatem, w jakim miejscu jest generowany kod deklaracji zmiennej i przypisania jej wartości, a klasa obsługi znacznika musi zadbać o to, by zmienna była dostępna w jednym ze standardowych zasięgów JSP w stosownym czasie; np. wykorzystując metodę doStartTag() dla zasięgów AT_BEGIN i NESTED i w metodzie doEndTag() dla zasięgu AT_END. Dla obiektu BodyTag przeprowadzającego iteracje po ciele wartość może także być aktualizowana w metodzie doAf- terBody(), aby dostarczać nowej wartości dla każdej iteracji. #46+;.+2/4346+;23-+86,98(cid:22); W poprzednim przykładzie klasa UsePropertyTagEx- traInfo przypisywała właściwościom varName i class- Name komponentu bean VariableInfo wartości atrybutów id oraz className, wyspecyfikowane przez autora na stro- nie JSP. Działo się to przy wykorzystaniu kolejnej prostej klasy o nazwie TagData, przekazywanej jako argument do metody getVariableInfo(). Obiekt TagData jest tworzony przez kontener w celu dostarczenia podklasy TagExtraInfo, za- wierającej informacje o wszystkich atrybutach akcji dostarczo- nych przez autora strony JSP. Obiekt TagData jest także przekazywany jako argument do me- tody isValid() klasy TagExtraInfo. Metoda ta jest wywo- ływana przez kontener WWW podczas fazy translacji, aby -/74/-+3;+2/  umożliwić użytkownikowi zaimplementowanie własnych reguł sprawdzania poprawności atrybutów specjalizowanej akcji. Kontener przeprowadza proste sprawdzenie poprawności opie- rając się na informacjach zawartych w pliku TLD. Akcja spe- cjalizowana może mieć jednak opcjonalne atrybuty, które wykluczają się wzajemnie lub są od siebie zależne. Zachodzi wtedy potrzeba implementacji metody isValid() w podkla- sie TagExtraInfo i dostarczenia własnego kodu sprawdza- jącego poprawność. Klasa TagData ma dwie interesujące metody. Metoda get- AttributeString() zwraca po prostu wyszczególniony atrybut jako String. Jednak wartości niektórych atrybutów mogą być określone poprzez wyrażenie JSP (atrybut „w czasie żądania”), nie zaś poprzez obiekt String. Ponieważ taka wartość nie jest znana w fazie translacji, klasa TagData udo- stępnia metodę getAttribute(), aby zaznaczyć, czy atry- but ma wartość dosłowną, nadawaną w czasie żądania, czy też w ogóle nie został ustawiony. Metoda getAttribute() zwraca wartość typu Object. Jeżeli wartość atrybutu jest okre- ślana w czasie żądania, zwracany jest specjalny obiekt RE- QUEST_TIME_VALUE. W przeciwnym wypadku metoda zwraca obiekt String lub null, jeśli atrybut nie został ustawiony. +7+$+1+8+ +;++7 37/6+ 4//289/ javax.servlet.jsp. tagext.TagData — Cloneable  +:+#/6:/6 +1/7 /732/7323; 4//283;+2+46/ wewnętrzne klasy zależne od kontenera. Większość kontenerów wykorzystuje wzorcową implementację klasy, stworzoną dla projektu Apache Jakarta 47 Instancje TagData są tworzone przez kontener WWW w fazie translacji. Dostarczają one informacji na temat wartości atry- butów (wyspecyfikowanych dla specjalizowanej akcji) podkla- sie TagExtraInfo (jeśli taka istnieje) odpowiedniej klasy obsługi znacznika. 327869836 public TagData(Object[][] atts) Tworzy nową instancję z parami nazw atrybutów i wartości, określonymi przez macierz Object[][]. Element 0 każ- dej tablicy Object[] zawiera nazwę, a element 1 — war- tość lub stałą REQUEST_TIME_VALUE (jeżeli wartość atrybutu została zdefiniowana jako określana w czasie żąda- nia, lub wyrażenie JSP). public TagData(java.util.HashTable attrs) Tworzy nową instancję z parami nazw atrybutów i wartości, określonymi przez tablicę haszującą HashTable. /83. public Object getAttribute(String attName) Zwraca wartość wskazanego atrybutu jako String lub obiekt REQUEST_TIME_VALUE (jeżeli wartość atrybutu jest określana w czasie żądania lub jako wyrażenie JSP). -/74/-+3;+2/  public String getAttributeString(String attName) Zwraca wartość wskazanego atrybutu jako String. Zgła- szany jest wyjątek ClassCastException, jeżeli war- tość atrybutu jest definiowana w czasie żądania lub stanowi wyrażenie JSP. public String getId() Zwraca wartość atrybutu o nazwie id jako String (lub null, jeśli go nie odnajdzie). public void setAttribute(String attName, Object value) Przypisuje wskazanemu atrybutowi podaną wartość. 6o+. Kiedy kontener WWW sprawdził wszystko, co mógł skontrolo- wać samodzielnie na podstawie informacji o atrybutach zawartych w pliku TLD, szuka podklasy TagExtraInfo zdefiniowanej dla akcji specjalizowanej przez element teiclass . Jeżeli zo- stała ona zdefiniowana, kontener umieszcza wszystkie informa- cje o atrybutach w egzemplarzu TagData i wywołuje metodę isValid() podklasy TagExtraInfo: public boolean isValid(TagData data) { // Mutually exclusive attributes if (data.getAttribute( attr1 ) != null data.getAttribute( attr2 != null) { return false; } // Dependent optional attributes if (data.getAttribute( attr3 ) != null data.getAttribute( attr4 == null) { return false; } return true; }  +:+#/6:/6 +1/7 /732/7323; Podklasa TagExtraInfo może wykorzystać obiekt TagData, aby sprawdzić, czy wszystkie zależności między atrybutami zo- stały zachowane, tak jak w podanym powyżej przykładzie. Nie- stety, w JSP 1.1 nie istnieje sposób, aby wygenerować stosowny komunikat o błędzie; metoda może jedynie zwrócić wartość false, aby zaznaczyć, że coś jest nie w porządku. Miejmy nadzieję, że w kolejnych wersjach JSP ta niedogodność zostanie usunięta. $;36/2/493479 ,,38/2+-2(cid:21);(cid:22)$(cid:25) Kiedy kontener WWW przekształca elementy akcji specjalizo- wanej na kod tworzący i wywołujący odpowiednią klasę obsłu- gi znacznika, potrzebuje informacji o tym, która klasa obsługi implementuje dany element akcji. Informację tę czerpie z pliku opisu biblioteki znaczników (Tag Library Descriptor, TLD). TLD to plik w formacie XML, zawierający informacje na temat wszystkich akcji specjalizowanych znajdujących się w bibliotece. Strona JSP wykorzystująca akcje specjalizowane musi zidenty- fikować odpowiedni plik TLD i przypisać mu prefiks, za pomo- cą którego będą one wywoływane za pomocą dyrektywy taglib, opisanej szczegółowo dalej: @ taglib uri= /WEB-INF/tlds/orataglib_1_0.tld prefix= ora ... ora:redirect page= main.jsp / Strona JSP używa następnie TLD do uzyskania informacji, nie- zbędnych, gdy napotyka element akcji specjalizowanej z odpo- wiednim prefiksem. $;36/2/493479,,38/2+-2’;($* 
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

JavaServer Pages. Leksykon kieszonkowy
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: