Frage

Kürzlich habe ich mich entschlossen, Kenntnisse über das Schreiben von benutzerdefinierten Tags zu erhalten. Und es gibt ein Problem.

In meiner Web -App verwende ich einige JSTL -Tags und auf jeder JSP -Seite habe ich einen identischen Code:

<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>

Wie Sie sehen können, legt diese Konstruktion das richtige Ressourcenpaket fest.

Daher würde ich gerne wissen, ob es Möglichkeit gibt, dieses Stück Code abzuwickeln und anstelle eines einzigen Tags zu verwenden (ich weiß, dass es einen anderen Weg gibt. Setzen Sie diesen Code einfach auf die einzelnen JSP -Seite und verwenden Sie < %@ include % > Richtlinie, aber ich würde gerne ein Tag ausprobieren)?

Wie ich verstehe, sollte ich den Körperinhalt (innerhalb von Tag, nicht von JSP) auf den Körperinhalten setzen und Container zum Ausführen machen, aber ich kann keine Beispiele dafür finden.

Was ich jetzt habe:

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>

und mein Tag:

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);
}
}

Es kompiliert, tut aber nichts richtig.

War es hilfreich?

Lösung

Nein, das wird nicht funktionieren, denn es gibt keine Erwartung, dass der Körperinhalt dann auch vom JSP -Compiler verarbeitet wird. Vielmehr müssten Sie die FMT: SetBundle in Ihrem Tag implementieren.

Eine JSP -Tag -Datei wäre einfacher. Operativ ist es nicht weit entfernt von dem, den Sie erwähnt haben, aber es macht Refactorings wie diese wirklich trivial.

Ich habe hier ein erweitertes Beispiel: JSP -Tricks, um das Vorlagen zu erleichtern?

Andere Tipps

Sie können andere JSP -Tags nicht in einem benutzerdefinierten Tag (dh einer in einer Java -Klasse) wie diese erstellt. Sie können jedoch eine "Tag -Datei" erstellen, mit der Sie ein benutzerdefiniertes Tag so definieren können, wie Sie eine JSP -Seite definieren würden. Hier ist ein Link, um Ihnen den Einstieg zu erleichtern: http://java.sun.com/j2ee/1.4/docs/tutorial/doc/jsptags5.html.

Was Sie jedoch versuchen, sieht aus wie etwas, was etwas anderes für Sie tun kann. Verwenden Sie Spring in Ihrer App? Wenn ja, sollten Sie sich die Spring -MessageSource und Localeresolver ansehen.

Der beste Weg, dies anzugehen, wäre eine Verwendung von a Servlet -Filter. Ein Filter kann jede Anforderung abfangen und Attribute in Anforderungsbereich festlegen. Das Java -Äquivalent der fmt:bundle Tag ist so etwas wie:

Config.set(request, Config.FMT_LOCALE, "ru_RU")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top