Определение собственного тела тега JSP - PullRequest
0 голосов
/ 07 сентября 2011

Недавно я решил получить некоторые знания о написании пользовательских тегов.И есть проблема.

В моем веб-приложении я использую несколько тегов JSTL, и на каждой странице JSP у меня есть идентичный фрагмент кода:

<c:if test="${sessionScope.locale == 'locale_ru_RU' or empty sessionScope.locale}" >
    <fmt:setBundle basename="locale_ru_RU" />
</c:if>
<c:if test="${sessionScope.locale == 'locale_en_US'}">
    <fmt:setBundle basename="locale_en_US" />
</c:if>

Как вы можете видеть эту конструкциюустанавливает правильный пакет ресурсов.

Поэтому я хотел бы знать, есть ли возможность обернуть этот кусок кода и использовать вместо него один тег (я знаю, что есть другой способ - просто поместите этот код вотдельную страницу JSP и используйте директиву <% @ include%>, но я хотел бы попробовать тег)?

Как я понимаю, мне нужно каким-то образом установить содержимое тела (внутри класса тега, а не из JSP) исделать контейнер для его выполнения, но я не могу найти никаких примеров об этом.

Что я получил сейчас:

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
 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
 version="2.0">
<tlib-version>1.0</tlib-version>
<tag>
    <name>setLocale</name>
    <tag-class>com.test.tags.LocaleBundleTag</tag-class>
    <body-content>empty</body-content>
</tag>
</taglib>

и мой тег:

public class LocaleBundleTag extends BodyTagSupport {

@Override
public void setBodyContent(BodyContent b) {

    try {
        b.clear();
        b.append("<c:if test=\"${sessionScope.locale == 'locale_ru_RU' or empty sessionScope.locale}\" >");
        b.append("<fmt:setBundle basename=\"locale_ru_RU\" />");
        b.append("</c:if>");
        b.append("<c:if test=\"${sessionScope.locale == 'locale_en_US'}\">");
        b.append("<fmt:setBundle basename=\"locale_en_US\" />");
        b.append("</c:if>");
    } catch (IOException e) {
    }

    super.setBodyContent(b);
}
}

Он компилируется, но ничего не делает правильно.

Ответы [ 3 ]

1 голос
/ 07 сентября 2011

Нет, это не сработает, потому что не ожидается, что содержимое тела будет также обрабатываться компилятором JSP.Скорее вам нужно будет реализовать fmt: setBundle внутри вашего тега.

Файл тега JSP будет проще.С практической точки зрения он не так уж далек от упомянутого вами включения, но делает рефакторинг, подобный этому, действительно тривиальным.

У меня есть расширенный пример: Трюки JSP, чтобы упростить создание шаблонов?

0 голосов
/ 07 сентября 2011

Лучший способ справиться с этим - использовать фильтр сервлетов .Фильтр может перехватывать каждый запрос и устанавливать атрибуты в области запроса.Java-эквивалент тега fmt:bundle выглядит примерно так:

Config.set(request, Config.FMT_LOCALE, "ru_RU")
0 голосов
/ 07 сентября 2011

Вы не можете использовать другие теги JSP внутри пользовательского тега (то есть, созданного в классе Java), подобного этому.Тем не менее, вы можете создать «файл тегов», который позволит вам определить собственный тег почти так же, как вы бы определили страницу JSP.Вот ссылка, с которой можно начать: http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPTags5.html.

Однако то, что вы пытаетесь сделать, похоже на то, что что-то еще должно быть в состоянии сделать для вас.Вы используете Spring в своем приложении?Если это так, подумайте о том, чтобы посмотреть на SpringSource и LocaleResolver.

...