Это серверный инструмент для разметки страниц (поддерживает JSP и FreeMarker), который характеризуется простотой, отсутствием XML и наличием всего 500 строк кода для реализации функционала, аналогичного Apache Tiles.
pom.xml
вашего проекта:<dependency>
<groupId>com.github.drinkjava2</groupId>
<artifactId>jwebbox</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version> <!-- или другую версию -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version> <!-- или другую версию -->
<scope>provided</scope>
</dependency>
jWebBox работает на Java 6 или выше и зависит от двух библиотек времени выполнения: javax.servlet-api
и javax.servlet.jsp-api
, которые обычно предоставляются Servlet-контейнером.
Далее приведено подробное объяснение использования jWebBox через пример, исходный код которого находится в директории jwebbox-demo
проекта. В корневой директории проекта также есть артефакт jwebbox-demo.war
, который можно запустить в Tomcat или WebLogic.
Серверный код представлен ниже:
public static class demo1 extends WebBox {
{
this.setPage("/WEB-INF/pages/homepage.jsp");
this.setAttribute("menu",
new WebBox("/WEB-INF/pages/menu.jsp").setAttribute("msg", "Пример 1 — базовый макет"));
this.setAttribute("body", new LeftRightLayout());
this.setAttribute("footer", "/WEB-INF/pages/footer.jsp");
}
}
public static class LeftRightLayout extends WebBox {
{
this.setPage("/WEB-INF/pages/left_right_layout.jsp");
ArrayList<Object> boxlist = new ArrayList<Object>();
boxlist.add("/WEB-INF/pages/page1.jsp");
boxlist.add("/WEB-INF/pages/page2.jsp");
this.setAttribute("boxlist", boxlist);
}
}
```Файл `homepage.jsp` является основным шаблоном страницы, его содержание приведено ниже:
<%@ taglib prefix="box" uri="http://github.com/drinkjava2/jwebbox"%>
Шаблон left_right_layout.jsp
представляет собой макет размещения, его содержание приведено ниже (подобные JSP-файлы имеют аналогичную структуру):
<%@ taglib prefix="box" uri="http://github.com/drinkjava2/jwebbox"%>
<div id="temp_left" style="margin: 10px; width: 430px; float: left; background-color:#CCFFCC;">
<box:show target="${jwebbox.attributeMap.boxlist[0]}"/>
</div>
<div id="temp_right" style="margin: 10px; float: right; width: 430px; background-color:#FFFFCC;">
<box:show target="${jwebbox.attributeMap.boxlist[1]}"/>
</div>
```Объяснение:
* Метод `setPage` используется для установки целевой страницы текущего экземпляра `WebBox` (необязательно). Конструктор `WebBox` позволяет принимать один параметр — страницу.
* Метод `setAttribute` временно хранит пару ключ-значение в внутреннем HashMap объекта `WebBox`. Значение может быть любым Java-объектом, а получение значения осуществляется методом `getAttribute`. В JSP-страницах значение можно получить через EL-выражение `${jwebbox.attributeMap.keyname}`.
* В JSP-страницах вызывается тег `<box:show attribute="body"/>` для отображения страницы, связанной с указанным ключом. Значение должно быть строкой, экземпляром `WebBox` или списком таких значений.
* Другое использование тега `show` выглядит как `<box:show target="xxx"/>`, где `target` может быть строкой, экземпляром `WebBox` или списком. Ниже приведены пять эквивалентных способов использования этого тега в JSP-страницах:
<box:show attribute="menu" /> <box:show target="${jwebbox.attributeMap.menu}" /> <% WebBox.showAttribute(pageContext,"menu");%> <% WebBox.showTarget(pageContext, WebBox.getAttribute(pageContext,"menu"));%> <% ((WebBox)WebBox.getAttribute(pageContext,"menu")).show(pageContext);%> // Этот подход рекомендован только в том случае, если атрибут menu является объектом типа WebBox.
Последние три способа не рекомендуются, но они помогают понять механизм работы WebBox. На каждой странице, вызванной WebBox, существует экземпляр WebBox, который можно получить с помощью `request.getAttribute("jwebbox")` или EL выражения `${jwebbox}`.
* Для использования тега `show` необходимо добавить ссылку на библиотеку TagLib в JSP-страницу:
```html
<%@ taglib prefix="box" uri="http://github.com/drinkjava2/jwebbox"%>
```
* Каждый экземпляр WebBox может иметь опциональное имя; каждая страница может получать только свой экземпляр WebBox, но методом `getFatherWebBox` можно получить экземпляр WebBox текущего вызова (это звучит сложновато).
* В JSP и Servlet jWebBox поддерживает создание и отображение экземпляров WebBox в реальном времени, например:
```jsp
<% new WebBox("/somepage.jsp").setPrepareStaticMethod("xxx").show(pageContext); %>
```
* В данном примере проект использует небольшую хитрость, которая преобразует все запросы с расширением `.htm` в создание и отображение WebBox. Конфигурация в `web.xml` выглядит следующим образом:
```xml
<servlet>
<servlet-name>htm2box</servlet-name>
<jsp-file>/htm2box.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>htm2box</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
```
Файл `htm2box.jsp` используется как Servlet, аналогичный `DispatcherServlet` в Spring MVC:
```jsp
<%@page import="org.apache.commons.lang.StringUtils"%><%@page import="com.github.drinkjava2.jwebbox.WebBox"%><%
String uri = StringUtils.substringBefore(request.getRequestURI(), ".");
uri = StringUtils.substringAfterLast(uri, "/");
if (uri == null || uri.length() == 0)
uri = "demo1";
WebBox box = (WebBox) Class.forName("com.github.drinkjava2.jwebboxdemo.DemoBoxConfig$" + uri).newInstance();
box.show(pageContext);
%>
```
Пример 1 выводит:

```#### Пример 2 - Наследование макета
Код серверной части:
```
public static class demo2 extends demo1 {
{((WebBox)this.getAttribute("menu")).setAttribute("msg","Demo2 - Изменение макета тела");
this.setAttribute("body", new TopDownLayout());}
}
```
Класс `demo2` наследуется от класса `demo1`, где атрибут `"body"` заменён на шаблон страницы с вертикальной компоновкой (`top_down_layout.jsp`). Код примера представлен выше.
Выход Примера 2:

#### Пример 3 — Подготовка данных
Серверный код:
```java
public static class demo3 extends demo1 {
{
setPrepareStaticMethod(DemoBoxConfig.class.getName() + ".changeMenu");
setAttribute("body", new WebBox().setText("<div style=\"width:900px\">This is body text</div>").setPrepareURL("/WEB-INF/pages/prepare.jsp").setPrepareBean(new Printer()));
setAttribute("footer", new WebBox("/WEB-INF/pages/footer.jsp").setPrepareBean(new Printer()).setPrepareBeanMethod("print"));
}
}
public static void changeMenu(PageContext pageContext, WebBox callerBox) throws IOException {
((WebBox)callerBox.getAttribute("menu")).setAttribute("msg", "Demo3 - Prepare methods<br>This is modified by \"changeMenu\" static method");
}
public static class Printer {
public void prepare(PageContext pageContext, WebBox callerBox) throws IOException {
pageContext.getOut().write("This is printed by Printer's default \"prepare\" method<br>");
}
public void print(PageContext pageContext, WebBox callerBox) throws IOException {
pageContext.getOut().write("This is printed by Printer's \"print\" method<br>");
pageContext.getOut().write((String)pageContext.getRequest().getAttribute("urlPrepare"));
}
}
```
Одним из преимуществ использования таких инструментов для макетов, как Apache Tiles и jWebBox, является возможность подготовки данных до загрузки всех подстраниц, что позволяет достичь цели модульного программирования. У jWebBox есть три способа подготовки данных:* метод `setPrepareStaticMethod` используется для указания статического метода для подготовки данных;
* метод `setPrepareBean` используется для указания объекта для подготовки данных, имя метода которого можно указать через `setPrepareBeanMethod`. Если имя метода не указано, будет использоваться метод `prepare` по умолчанию;
* метод `setPrepareURL` вызывает URL для подготовки данных, это ссылка на серверный URL, который может обращаться к содержимому директории `/WEB-INF`;
* метод `setText` позволяет установить небольшой фрагмент текста, который будет вставлен как HTML-код перед подстраницей.
```Подготовка методов и порядок вывода страниц следующий:
prepareStaticMethod -> prepareBeanMethod -> PrepareURL -> текстовый вывод -> страница
Пример 3 вывод:

#### Пример 4 - список
Код серверной части:
```
public static class demo4 extends demo1 {
{
((WebBox) this.getAttribute("menu")).setAttribute("msg", "Demo4 - List");
ArrayList<Object> child = new ArrayList<Object>();
for (int i = 1; i <= 3; i++)
child.add(new WebBox("/WEB-INF/pages/page" + i + ".jsp").setText(" "));
ArrayList<Object> mainList = new ArrayList<Object>();
for (int i = 1; i <= 3; i++) {
mainList.add("/WEB-INF/pages/page" + i + ".jsp");
if (i == 2)
mainList.add(child);
}
this.setAttribute("body", mainList);
}
}
```
Если атрибут представляет собой список, то при вызове метода `<box:show attribute="xxx" />` в JSP-странице, если значение является списком, будет предполагаться, что каждый элемент списка представляет либо страницу, либо объект типа `WebBox`, который последовательно отображается.Пример 4 вывод:

#### Пример 5 - Поддержка шаблонов FreeMarker
С версии 2.1, jWebBox поддерживает FreeMarker и может использоваться вместе с JSP, как показано ниже:
```
public static class demo5 extends WebBox {
{
this.setPage("/WEB-INF/pages/homepage.ftl");
this.setAttribute("menu",
new WebBox("/WEB-INF/pages/menu.jsp").setAttribute("msg", "Demo5 - FreeMarker demo"));
this.setAttribute("body", new FreemakerLeftRightLayout());
this.setAttribute("footer", new WebBox("/WEB-INF/pages/footer.jsp"));
}
}
```
FreeMarker не поддерживает прямое встраивание Java-кода в страницах; его синтаксис отличается от JSP. Вместо этого используются специальные теги, такие как `<#assign box=JspTaglibs["http://github.com/drinkjava2/jwebbox"] />`, а также специальный синтаксис для тега `show`: `<@box.show attribute="menu" />`.
Для использования FreeMarker требуется добавление конфигураций в файл `web.xml`:
```
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
```
Также необходимо добавить зависимость на библиотеку FreeMarker в файл `pom.xml`:
```
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version> <!-- или более поздняя версия -->
</dependency>
```
Пример 5 вывод:

#### Пример 6 — Демонстрация таблиц и пагинацииЭтот пример демонстрирует использование функциональности наследования конфигураций WebBox для создания компонентов таблиц и пагинационной полосы. Он выводит две таблицы и пагинационную полосу, а также обрабатывает данные формы. Из-за большого объема приведены только отрывки кода:```java
public static class demo6 extends demo1 {
{
setAttribute("menu",
((WebBox) this.getAttribute("menu")).setAttribute("msg", "Пример 6 - Таблицы и пагинация"));
List<WebBox> bodyList = new ArrayList<>();
bodyList.add(new TableBox());
bodyList.add(new TablePaginBarBox());
bodyList.add(new WebBox().setText(
"<br/>-----------------------------------------------------------------------------------"));
bodyList.add(new CommentBox());
bodyList.add(new CommentPaginBarBox());
bodyList.add(new WebBox("/WEB-INF/pages/commentform.jsp"));
this.setPrepareStaticMethod(DemoBoxConfig.class.getName() + ".receiveCommentPost");
this.setAttribute("body", bodyList);
}
class TableBox extends WebBox {
{
this.setPrepareBean(new PrepareForDemo6()).setPrepareBeanMethod("prepareTable");
setPage("/WEB-INF/pages/page_table.jsp");
setAttribute("pageId", "table");
setAttribute("targetList", tableDummyData);
setAttribute("row", 3).setAttribute("col", 4);
setAttribute("render", new WebBox("/WEB-INF/pages/render_table.jsp"));
}
}
class TablePaginBarBox extends TableBox {
{
this.setPrepareBean(new PrepareForDemo6()).setPrepareBeanMethod("preparePaginBar");
setPage("/WEB-INF/pages/pagin_bar.jsp");
}
}
class CommentBox extends TableBox {
{
setAttribute("pageId", "comment");
setAttribute("targetList", commentDummyData);
setAttribute("row", 3).setAttribute("col", 1);
setAttribute("render", new WebBox("/WEB-INF/pages/render_comment.jsp"));
}
}
class CommentPaginBarBox extends CommentBox {
{
this.setPrepareBean(new PrepareForDemo6()).setPrepareBeanMethod("preparePaginBar");
setPage("/WEB-INF/pages/pagin_bar.jsp");
}
}
}
```
Скриншот Примера 6:

Это полное руководство по jWebBox. В случае возникновения вопросов обратитесь к исходному коду проекта или примерам.#### Приложение — история версий:
**jWebBox 2.1:** Добавлена поддержка шаблонов FreeMarker; добавлен один JSP-тег; созданы демонстрационные материалы для таблиц, пагинации и обработки форм; исправлен баг, препятствовавший запуску приложения на WebLogic.
**jWebBox 2.1.1:** Добавлены несколько пустых методов-обратных вызовов (`beforeShow`, `beforeExecute`, `execute`, `afterExecute`, `afterShow`, `afterPrepared`) для использования в подклассах. Примеры см. в проекте jBooox.
**jWebBox 2.1.2:** Тип метода `show()` изменён с `void` на `WebBox`, что упрощает его использование.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )