25 czerwca 2008

Element jsp-property-group w JSP 2.1

Podczas rozpoznawania facelets w kontekście braku interpretowania znaczników JSP z projektu jpivot natrafiłem na pewną ciekawostkę JSP 2.1 - element jsp-property-group w deskryptorze rozmieszczenia aplikacji webowej /WEB-INF/web.xml. Jestem pewien, że jest to jeden z tych niuansów specyfikacji JSP 2.1, który potrafi położyć nawet najbardziej rozeznanych w zawiłościach specyfikacji podczas egzaminu Sun Certified Web Component Developer (SCWCD). Już kiedyś miałem okazję spotkać ten element, ale przelotnie i nigdy nie przyszło mi go zastosować.

Podczas lektury artykułu Developing applications with Facelets, JSF, and JSP z sierpnia 2006r. (!) napotkałem go ponownie.
 <jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
<is-xml>true</is-xml>
</jsp-property-group>
</jsp-config>
Za pomocą jsp-property-group można konfigurować grupy stron JSP i przypisywać im parametry konfiguracyjne. W powyższym przykładzie jsp-property-group zostało wykorzystane do wyłączenia możliwości zanurzania skryptów JSP wewnątrz stron JSP o rozszerzeniu jsp. Innymi konfiguracjami mogłoby być kodowanie stron, włączenie obsługi JSP EL (języka wyrażeń JSP - tych rozpoczynających się od $) oraz dołączanie (pod)stron przed i po wykonaniu strony. Rozszeżenie stron JSP nie musi być koniecznie jsp, ale same strony muszą być poprawnymi stronami JSP.

Zgodnie ze specyfikacją JavaServer Pages 2.1 (JSP) w JSP.3.3 JSP Property Groups (strona 78) konfiguracja stron JSP za pomocą jsp-config (rodzica jsp-property-group) dotyczy wskazanych stron spełniających wzorzec w url-pattern oraz wszystkich włączonych stron za pomocą dyrektywy include za wyjątkiem parametru konfiguracyjnego page-encoding, który dotyczy wyłącznie tych spełniających url-pattern.

Jeśli wzorzec określony w url-pattern jest identyczny ze wzorcem elementu servlet-mapping, wtedy jsp-property-group ma priorytet.

Podelementy jsp-property-group:
  • el-ignored (true/false) - wyłącza/włącza JSP EL, który przed JSP 2.0 nie był dostępny. Zmiana globalnej konfiguracji możliwa jest przez atrybut isELIgnored dyrektywy page w stronie JSP. Parametr ma wpływ na obsługę \$ oraz \#, które wyłączają specjalność znaków $ oraz #. Przy wyłączonym JSP EL są one łańcuchem 2 znaków bez specjalności \, $ czy #;
  • scripting-invalid (true/false) - wyłącza/włącza mechanizm skryptów w stronach JSP. Domyślnie skrypty są włączone;
  • page-encoding - odpowiada atrybutowi pageEncoding dyrektywy page w stronie JSP i ustawia stronę kodową na podaną. Dotyczy wyłącznie stron JSP, a nie dokumentów JSP (jspx), które są dokumentami XML, gdzie podanie strony kodowej jest obowiązkowe. Przykład w specyfikacji przedstawia konfigurację dla podzbioru stron JSP spełniających wzorzec /ja/*, czyli tych należących do strony kodowej Shift_JIS;
  • include-prelude określa ścieżkę strony (fragmentu strony JSP - jspf) w aplikacji webowej dołączanego na początku strony JSP, podobnie do dyrektywy include. W przypadku wielu elementów include-prelude ich dołączanie będzie odpowiadało kolejności występowania w jsp-property-group;
  • include-coda jest odpowiednikiem include-prelude, ale dołączenie następuje na końcu stron JSP spełniających wzorzec url-pattern w sekcji jsp-property-group.
  • is-xml (true/false) wskazuje, że strony spełniające url-pattern są dokumentami XML. Za pomocą tego elementu można określić, że domyślne rozszerzenie wskazujące strony JSP jako dokumenty XML - jspx - jest rozszerzeniem zwykłych, niexmlowych stron JSP;
  • deferred-syntax-allowed-as-literal (true/false) - wyłącza/włącza specjalne traktowanie łańcuchu #{, które od JSP 2.1 są zarezerwowane dla wyrażeń JSP EL (wartość false). Za pomocą atrybutu deferredSyntaxAllowedAsLiteral dyrektywy page można zmienić wartość tego parametru dla pojedyńczej strony JSP;
  • trim-directivewhitespaces (true/false) usuwa/pozostawia "białe" znaki w odpowiedzi strony JSP. Wpływa istotnie na rozmiar wygenerowanej klientowi strony JSP. Nie ma wpływu na dokumenty JSP (strony JSP będące dokumentami XML). Domyślna wartość false - pozostawia "białe" znaki. Możliwa zmiana konfiguracji per strona JSP za pomocą atrybutu trimDirectiveWhitespaces dyrektywy page.
Dla kompletu informacji należałoby jeszcze wspomnieć o dyrektywie page - rozdział JSP.1.10.1 The page Directive specyfikacji JavaServer Pages 2.1 (strona 44). W stronach JSP dyrektywa page reprezentowana jest za pomocą elementu <%@ page { attr="value" }* %>, podczas gdy dla dokumentów JSP <jsp:directive.page>. Możliwe jest wielokrotne użycie dyrektywy page w ramach pojedyńczej strony i mogą być umiejscowione w dowolnym miejscu strony, a mimo to wpływają na całą jednostkę kompilacji (cała strona JSP już po dołączeniu podstron). Umiejscowienie dyrektywy page z atrybutami pageEncoding oraz contentType powinno być jednakże na początku strony, aby poprawnie wyznaczyć kodowanie strony. Jeśli dyrektywa page występuje w różnych częściach strony JSP to dla identycznych parametrów musi być identyczna wartość, za wyjątkiem atrybutów import oraz pageEncoding.

Składnia dyrektywy page:
 <%@ page page_directive_attr_list %>

page_directive_attr_list ::= { language="scriptingLanguage"}
{ extends="className" }
{ import="importList" }
{ session="true|false" }
{ buffer="none|sizekb" }
{ autoFlush="true|false" }
{ isThreadSafe="true|false" }
{ info="info_text" }
{ errorPage="error_url" }
{ isErrorPage="true|false" }
{ contentType="ctinfo" }
{ pageEncoding="peinfo" }
{ isELIgnored="true|false" }
{ deferredSyntaxAllowedAsLiteral="true|false"}
{ trimDirectiveWhitespaces="true|false"}
Opis poszczególnych elementów dyrektywy page znajduje się w tabeli Table JSP.1-8 Page Directive Attributes specyfikacji JavaServer Pages 2.1 (strona 46).

Pytanie konkursowe: Za pomocą jakiego elementu deskryptora aplikacji webowej /WEB-INF/web.xml konfigurowane są parametry stron JSP? Pytanie bardziej wyrafinowane, z tych wykańczających na egzaminach, czy "ostrych" rozmowach kwalifikacyjnych: Jakie elementy jsp-property-group w web.xml mogą być nadpisane przez dyrektywę page? Miłych rozmów kwalifikacyjnych ;-)