我正在尝试创建一个仅在标记内可用的el变量,以便它类似于:
<mytaglib:mytag>
Foo is ${foo}
</mytaglib:mytag>
我已经按照我可以找到的用于创建嵌套el变量的文档,但是,在mytag结束后可以使用$ {foo}。
缩小版的.tld文件是:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<description>My Tags</description>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>mytaglib</short-name>
<uri>http://www.example.com/taglibs/mytaglib</uri>
<tag>
<name>mytag</name>
<tag-class>com.example.tags.MyTag</tag-class>
<body-content>JSP</body-content>
<variable>
<name-given>used</name-given>
<variable-class>java.lang.String</variable-class>
<scope>NESTED</scope>
</variable>
</tag>
</taglib>
然后MyTag执行以下操作(我删除了所有不应该相关的代码):
public class MyTag extends BodyTagSupport
{
// these are subtags
private JspFragment below;
private JspFragment at;
@Override
public int doStartTag() throws JspException
{
return EVAL_BODY_BUFFERED;
}
@Override
public int doEndTag() throws JspException
{
try
{
if (aBoolean)
{
below.invoke(pageContext.getOut());
}
else
{
at.invoke(pageContext.getOut());
}
}
catch (IOException e)
{
throw new JspException(e);
}
return EVAL_PAGE;
}
@Override
public void doInitBody() throws JspException
{
pageContext.setAttribute("used", "valueOfUsed");
}
@Override
public int doAfterBody() throws JspException
{
try
{
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}
catch (IOException e)
{
throw new JspException(e);
}
return SKIP_BODY;
}
}
我的理解是doInitBody中的pageContext.setAttribute()应该在嵌套范围内,并且你在doAfterBody中评估实际的主体。 这似乎应该是这种情况,因为'used'在标签范围之外可用。
一般背景...标签看起来像(简化形式)
<mytaglib:mytag>
Used is ${used}
</mytaglib:mytag>
或
<mytaglib:mytag>
<mytaglib:at>
You are at your limit, you have used: ${used}
</mytaglib:at>
<mytaglib:below>
You are below your limit, you have used: ${used}
</mytaglib:below>
</mytaglib:mytag>
如何将$ {used}限定为mytag?
答案 0 :(得分:1)
我总是将JSTL作为我写的任何标签的模型。因此,我的方法是查看执行类似操作的标记的源代码,然后复制它。 &lt; c:forEach&gt;标签是一个很好的例子。
JSTL中的LoopTagSupport类实现接口 javax.servlet.jsp.tagext.TryCatchFinally ,在doFinally方法中,它手动调用pageContext.removeAttribute()。
引用JSTL1.1源代码分发:
/**
* Removes any attributes that this LoopTagSupport set.
*
* <p> These attributes are intended to support scripting variables with
* NESTED scope, so we don't want to pollute attribute space by leaving
* them lying around.
*/
public void doFinally() {
/*
* Make sure to un-expose variables, restoring them to their
* prior values, if applicable.
*/
unExposeVariables();
}
/**
* Removes page attributes that we have exposed and, if applicable,
* restores them to their prior values (and scopes).
*/
private void unExposeVariables() {
// "nested" variables are now simply removed
if (itemId != null)
pageContext.removeAttribute(itemId, PageContext.PAGE_SCOPE);
if (statusId != null)
pageContext.removeAttribute(statusId, PageContext.PAGE_SCOPE);
}