Внедрите XML в JSP страницы с помощью custom тегов!
(Артем Рудой)
Данная статья посвящена описанию способа разделения содержания и дизайна JSP страниц с
помощью технологий XML и XSL.
При создании пользовательского интерфейса возникает проблема разделения содержания и
дизайна (представления). Обычно желательно чтобы можно было вносить изменения в дизайн,
не затрагивая содержание. Такое разделение облегчает разработку и внесение изменений при
создании приложения.
Одним из решений задачи разделения дизайна и содержания является использование XML и
XSL технологий. Основная идея заключается в том, что данные для представления содержаться
в XML формате, в то время как XSL стиль содержит описание преобразования данных в формат
подходящий для отображения (например, в HTML формат).
При создании веб-интерфейса часто используют JavaServer Pages для динамической
генерации HTML страниц. Этот метод имеет ряд несдостатков:
- Дизайнерам страниц необходимо иметь представление о языке Java чтобы корректно
модифицировать JSP страницы.
- Эти страницы превращаются в смесь HTML и Java кода что делает их сложными для
понимания и для внесения изменений.
Однако, существует возможность использовать JSP страницы для генерации XML содержания,
которое впоследствии будет преобразовано с помощью XSL стиля. Сделать это можно с помощью
custom тегов – способа расширения синтаксиса JSP страниц. В качестве примера сделаем тег
transform, который будет к своему содержимому применять XSL стиль, указанный
в атрибуте xsl:
<xml:transform xsl="test.xsl">
…XML content…
</xml:transform>
Для этого необходимо сделать обработчик тега transform:
TransformerTag.java:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class TransformTag extends BodyTagSupport
{
private String xsl = null;
public TransformTag()
{
}
public void setXsl(String xsl)
{
this.xsl = xsl;
}
public String getXsl()
{
return xsl;
}
public int doStartTag() throws JspException
{
return BodyTag.EVAL_BODY_TAG;
}
public int doAfterBody() throws JspException
{
try
{
// Create document builder using JAXP
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db =
dbf.newDocumentBuilder();
// Create DOM tree of the tag body
Document body =
db.parse(new InputSource(bodyContent.getReader()));
// Create DOM tree of the xsl
Document xslDom =
db.parse(pageContext.getServletContext().getRealPath(xsl));
// Perform transformation
Transformer transformer =
TransformerFactory.newInstance().
newTransformer(new DOMSource(xslDom));
transformer.transform(
new DOMSource(body), new StreamResult(getPreviousOut()));
}
catch(Exception e)
{
throw new JspException(e.getMessage());
}
return BodyTag.SKIP_BODY;
}
}
Создаем в каталоге WEB-INF Web-приложения файл xml_transform.tld с описанием
библиотеки:
<?xml version="1.0" ?>
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>XML transform</shortname>
<tag>
<name>transform</name>
<tagclass>TransformTag</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>xsl</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Прописываем библиотеку в конфигурации web-приложения, для этого в файл web.xml
необходимо добавить следующее:
<taglib>
<taglib-uri>xml_transform</taglib-uri>
<taglib-location>/WEB-INF/xml_transform.tld</taglib-location>
</taglib>
Теперь библиотека тегов доступна для использования в JSP страницах. Для демонстрации
работы, создадим тестовую страницу test.jsp:
<%@ page contentType="text/html" %>
<%@ taglib uri="xml_transform" prefix="xml" %>
<xml:transform xsl="test.xsl">
<phonebook>
<item>
<name>Mary</name>
<phone>123-45-67</phone>
</item>
<item>
<name>John</name>
<phone>987-65-43</phone>
</item>
</phonebook>
И файл с XSL стилем для преобразования:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
<xsl:apply-templates select="phonebook"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="phone"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Теперь, при вызове страницы test.jsp мы получим результат преобразования динамически
созданного XML содержания статическим XSL стилем:
| Name |
Phone |
| Mary |
123-45-67 |
| John |
987-65-43 |
Таким образом становится возможным физическое разделение по различным файлам
содержания, которое генерируется динамически в JSP странице (в виде XML) и представления
в виде статического XSL стиля.
Способы улучшения
Данный пример представляет собой простейший способ реализации внедрения XML/XSL
технологии в JSP. При создании реальных систем надо отметить следующее:
- Так как XSL файл является статическим, то для увеличения быстродействия можно
сохранять прекомпилированные XSL (объекты класса javax.xml.transform.Templates).
- Нет необходимости создавать DOM дерево XML содержимого. Можно воспользоваться SAX
парсером для однопроходного преобразования что также повысит быстродействие.
Ресурсы
- XML - http://www.w3.org/XML/
- XSL - http://www.w3.org/Style/XSL/
- JSP -
http://java.sun.com/products/jsp/index.html
- JAXP -
http://java.sun.com/xml/xml_jaxp.html
- Jakarta Taglibs -
http://jakarta.apache.org/taglibs/
|