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