JSP EL používám často a sem tam se mi stane, že bych potřeboval použít vlastní funkci. J2EE specifikace nabízí velmi elegantní řešení, jak si rychle takovou funkci vytvořit.
Pozn. Přijde mi, že je to v tutoriálu J2EE trochu zapadlé, tak proto jsem se rozhodl o tom napsat dnešní článek.
Originální popis se nachází zde v tutoriálu J2EE.
Pro demonstraci postupu jsem si vybral funkci, která mi řekne, zda je/není daný prvek v kolekci.
Vytvoření funkce
package cz.anect.mis.web.tags;
import java.util.Collection;
/**
* This class encapsulates handy funcions for using in JSP EL.
*
* Functions must be defined in /WEB-INF/functions.tld.
*
* @author pjuza@anect.com
*/
public class Functions {
/**
* Method returns true if specified object is contained in
* input collection.
* @param col Input collection for searching
* @param obj Searched object
* @return returns true if specified object is contained in input collection.
*/
public static boolean inCollection(Collection col, Object obj) {
if (col == null || obj == null)
return false;
return col.contains(obj);
}
}
Snad jediné omezení je, že funkce musí být statická a veřejná (public).
Definice funkce pomocí TLD
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>A tag library that defines my custom functions.</description>
<tlib-version>1.0</tlib-version>
<short-name>FunctionTagLibrary</short-name>
<uri>/FunctionLibrary</uri>
<function>
<name>inCollection</name>
<function-class>cz.anect.mis.web.tags.Functions</function-class>
<function-signature>boolean inCollection(java.util.Collection, java.lang.Object)</function-signature>
</function>
</taglib>
Použití funkce
Nejdříve musíme TLD standardně nadeklarovat před vlastním použitím na stránce:<%@ taglib uri="/WEB-INF/tld/functions.tld" prefix="myfn" %>
A nyní můžeme bez problémů danou funkci použít:
<c:forEach var="kw" items="${keywords}">
<c:if test='${not myfn:inCollection(search.basicKeyWordIds, kw.id)}'>
<option value="<c:out value="${kw.id}"/>"><c:out value="${kw.value}"/></option>
</c:if>
</c:forEach>
6 komentářů:
Pěkné. Ačkoliv mi připadá EL v JSP trošku zbytečný - proč používat další jazyk, když už tam je Java, kde si tu statickou metodu můžeš zavolat taky. Zajímavější je ale použití EL v facelets, kde je to dělano podobně.
Já jsem dost proti tomu, aby se Java kód používat v prezentační vrstvě. Tam dle mého názoru nemá co dělat. Prezentační vrstva má sloužit pouze k zobrazení dat a k získání dat od uživatele.
pouzivani javy v jsp nakonec vede k neprehlednosti, mnohem lepsi je pouzivat EL
Já bych řekl, že nepřehlednost je to nejmenší z pohledu dané aplikace. Jako hlavní problémy pak vidím v tom, že se špatně aplikace škáluje (viděl jsem dokonce použití EJB přímo v JSP stránkách), že nemohu efektivně refaktorovat a reagovat na změny zákazníka, že nemohu vytvářet více druhů klientů (nejenom webový klient) atd.
nedalo by se toto resit take pomoci beanu (jsp:useBean) ?
Ano, Java by se v prezentační vrstvě používat neměla=> neměli by se používat JSP - myšlenka EL je v tom, aby člověk který neumí Javu, dokázal psát prezentační vrstvu. Ale myslím si, že realita je taková, že momentálně píšou prezentašní vrstvu Java programátoři. Samozřejmě jsem nemyslel aby se v prezentační vrstvě objevovala logika, ale to co se dá napsat v EL se dá i napsat v Java. Takle se velice často mixuje EL a Java na jedné stránce, což je podle mě špatně. Proto si myslím, že když chce někdo používat EL, tak rovnou ať použije Facelets, nebo jiný podobný framework.
Okomentovat