V tomto díle našeho seriálu se seznámíme se Sitemesh flow, tedy s principem, na jakém Sitemesh funguje. Ukážeme si, jak Sitemesh nasadit do aplikace, jeho konfiguraci a vysvětlíme si postup výběru jednotlivých dekorátorů. Nic více, nic méně.
Jak jsem psal v prvním díle tohoto miniseriálu, Sitemesh je založen na technologii javax.servlet.Filter. Třída, která implementuje toto rozhraní a která tvoří vstupní bod do Sitemeshe, se nazývá PageFilter.
Celý proces začíná tím, že webový kontejner příjme požadavek na stránku, která je v kontextu aplikace, na který je namapován PageFilter. Pokud se tak stane, požadavek je předán právě tomuto filtru, který vytvoří vlastní objekt odezvy, který pošle do aplikace spolu s daným požadavkem. Do tohoto objektu je zapouzdřena odpověď aplikace na daný požadavek a ten je vrácen zpět
PageFilteru.
Mapování PageFilteru na kontext aplikace ve WEB-INF/web.xml
<filter> </filter><filter -name>sitemesh</filter> <filter -class>com.opensymphony.module.sitemesh.filter.PageFilter</filter> <filter -mapping> </filter><filter -name>sitemesh</filter> <url -pattern>/*</url> <filter -mapping>
Jakmile se odezva vrátí PageFiltru, PageFilter zjistí typ jejího obsahu a vytvoří parser, kterým daný obsah bude zpracovávat. Sitemesh disponuje FastPageParserem, který je schopen zpracovávat obsah s content-type=“text/html“, ale nic programátorům nebrání naprogramovat si vlastní pro jakýkoli typ odezvy. Typ odezvy a její parser se specifikuje v dokumentu WEB-INF/sitemesh.xml.
Po rozparsování odezvy nastává fáze dekorační. Sitemesh obsahuje systém tzv. mapperů, tříd implementujících rozhraní DecoratorMapper, které určují, na základě jakých pravidel se bude vybírat správný dekorátor. Tyto mappery jsou definovány v souboru WEB-INF/sitemesh.xml. Každý mapper (definován v tomto souboru níže) je rodičem mapperu definovaného nad ním.
Definice mapperů ve WEB-INF/sitemesh.xml
<sitemesh> <property name="decorators-file" value="/WEB-INF/decorators.xml"></property> <excludes file="${decorators-file}"></excludes> <page -parsers> <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser"></parser> </page> <decorator -mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper"> <param name="match.en" value="en" /> <param name="match.cs" value="cs" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"> <param name="match.MSIE" value="ie" /> <param name="match.Mozilla" value="moz" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"> <param name="config" value="${decorators-file}" /> </mapper> </decorator> </sitemesh>
Dekorátory mohou být vybírány např. na základě typu prohlížeče požadujícího stránku, na základě jazyka prohlížeče, hodnoty uchovávané v cookies či v session atd.
Pokud má Sitemesh vybrat dekorátor pro danou stránku, nejdříve vytvoří instanci prvního mapperu uvedeného v souboru WEB-INF/sitemesh.xml a volá jeho metodu getDecorator(). V této metodě se Sitemesh pokusí vybrat prodanou stránku správný dekorátor. Pokud se mu to nepodaří, pak volá stejnou metodu na jeho rodiči, tedy na mapperu definovaného v WEB-INF/sitemesh.xml pod ním. Tenhle postup se opakuje do nalezení správného dekorátoru pro danou stránku.
Pokud není v souboru WEB-INF/sitemesh.xml žádný mapper definován, či soubor WEB-INF/sitemesh.xml neexistuje, je vytvořen defaultní ConfigDecoratorMapper, který čte jména dekorátorů a jejich mapování ze souboru WEB-INF/decorators.xml, pokud není v souboru WEB-INF/sitemesh.xml definováno jinak.
Definice dekorátorů pro ConfigDecoratorMapper v WEB-INF/decorators.xml
<decorators defaultdir="WEB-INF/decorators"> <decorator name="administrace" page="blog-admin.jsp"> <pattern>/blog/administrace/*.jsp</pattern> </decorator> <decorator name="blog" page="blog-dec.jsp"> <pattern>/blog.jsp </pattern></decorator> <decorator name="site" page="site-dec.jsp"> <pattern>/*</pattern> </decorator> </decorators>
V elementech můžeme krom názvů cest využívat také tzv. wildcards, tedy znaky se speciálním významem. Jedná se o znaky „?„, „*„, které zastupují po řadě jeden či více znaků. Toto mapování ConfigDecoratorMaper porovnává s hodnotou, kterou vrací metoda request.getServletPath().
Často se stává, že jedna vyhovuje více dekorátorům. Potom se jejich výběr řídí následujícími pravidly. Nejdříve se kontrolují vzory, které neobsahují wilcards a potom vzory, které je obsahují. Pokud toto porovnání selže, je vybrán ten dekorátor, jehož vzor je nejdelší, tedy vyhrává /blog/administrace/*.jsp nad /blog/*. Vyhrává tedy ten, jehož vzor obsahuje více lomítek „/„.
Obsah dekorátoru WEB-INF/site-dec.jsp
< %@ taglib uri="https://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> <html> <head> <title><decorator :title default="MoroSystems | Programování v Javě"></decorator></title> <meta http-equiv="content-type" content="text/html"; charset="utf-8"/> <decorator :head></decorator> </head> <body> <h1>MoroSystems</h1> <div id="text"> <decorator :body></decorator> </div> </body> </html>
Pokud je nalezen správný dekorátor, který je JSP stránkou, Sitemesh pro něj vyšle požadavek. Tato stránka má přístup k rozpársované stránce, o které jsme se zmiňovaly v části o FastPageParseru. V dekorátoru můžeme použít knihovnu značek Sitemeshe k získání různých částí parsované stránky, jako jsou obsahy elementů title, head, body, které se vloží do vybraného dekorátoru. Takto zpracovaný dekorátor doplňen o části parsované stránky je vrácen prohlížeči jako obsah požadované stránky.
Příklad stránky site.jsp
< %@page language="java" contentType="text/html; charset=utf-8" pageEncoding="windows-1250" %> <html> <head> <title>MoroSystems | Příklad - Sitemesh</title> <meta name="keywords" content="sitemesh" /> </head> <body> <p>Stránka, která bude dekorována.</p> </body> </html>
Výsledkem pak bude následující HTML kód
<pre><html> <head> <title>MoroSystems | Příklad - Sitemesh</title> <meta http-equiv="content-type" content="text/html"; charset="utf-8"/> <meta name="keywords" content="sitemesh" /> </head> <body> <h1>MoroSystems</h1> <div id="text"> <p>Stránka, která bude dekorována.</p> </div> </body> </html>
V přecházejícím textu jsme se seznámili s instalací a konfigurací aplikačního rámce Sitemesh a jeho použitím. Na závěr je však nutné poznamenat, že současná verze Sitemeshe, tedy verze 2.2.1, není vhodná pro použítí v aplikacích stavěných podle vzoru MVC, což by se ale mělo v příštích verzích změnit. Ale o tom snad někdy jindy v jednom z příštích dílů tohoto seriálu.
Relevantní odkazy
Poslední komentáře