最近我决定了解一些关于编写自定义标签的知识。而且有一个问题。
在我的网络应用程序中,我使用了一些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页面中并使用&lt; %@ include%&gt;指令,但我想尝试标记)?
据我所知,我应该设置正文内容(在标记类内,而不是从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);
}
}
它编译,但没有正确执行任何操作。
答案 0 :(得分:1)
不,这不起作用,因为不期望JSP编译器也会处理正文内容。相反,您需要在标签中自己实现fmt:setBundle。
JSP标记文件会更容易。在操作上,它与你提到的包含的距离并没有那么远,但是它使得这样的重构非常简单。
我在这里有一个扩展示例:JSP tricks to make templating easier?
答案 1 :(得分:0)
您不能在自定义标记(即在Java类中创建的标记)中使用其他JSP标记。但是,您可以创建一个“标记文件”,它允许您定义自定义标记,就像定义JSP页面一样。这是一个帮助您入门的链接:http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPTags5.html。
然而,你想要做的事情看起来像其他东西应该能为你做的事情。你在你的应用程序中使用Spring吗?如果是这样,请考虑查看Spring的MessageSource和LocaleResolver。
答案 2 :(得分:0)
解决这个问题的最佳方法是使用servlet filter。过滤器可以拦截每个请求并在请求范围中设置属性。 fmt:bundle
标记的java等价物如下:
Config.set(request, Config.FMT_LOCALE, "ru_RU")