jsp标记库的嵌套el变量

jsp标记库的嵌套el变量,jsp,el,taglib,Jsp,El,Taglib,我正在尝试创建一个el变量,该变量仅在标记中可用,因此类似于: <mytaglib:mytag> Foo is ${foo} </mytaglib:mytag> 我的理解是doInitBody中的pageContext.setAttribute()应该位于嵌套范围内,并且您可以在doAfterBody中计算实际的主体。 虽然as“used”在标记的范围之外可用,但似乎是这样 一般背景。。。标签看起来像(简化形式) Used是${Used} 或 您已达到极限,您

我正在尝试创建一个el变量,该变量仅在标记中可用,因此类似于:

<mytaglib:mytag>
  Foo is ${foo}
</mytaglib:mytag>
我的理解是doInitBody中的pageContext.setAttribute()应该位于嵌套范围内,并且您可以在doAfterBody中计算实际的主体。 虽然as“used”在标记的范围之外可用,但似乎是这样

一般背景。。。标签看起来像(简化形式)


Used是${Used}


您已达到极限,您已使用:${used}
您低于限制,您已使用:${used}

如何将${used}限定为mytag?

我总是引用JSTL作为我编写的任何标记的模型。因此,我的方法是查看做类似事情的标记的源代码,然后复制它。 标签就是一个完美的例子

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);
}
/**
*删除此LoopTag支持设置的所有属性。
*
*这些属性旨在支持使用
*嵌套的作用域,所以我们不想留下来污染属性空间
*他们到处躺着。
*/
公共空间{
/*
*确保取消暴露变量,将它们恢复到其原始状态
*先前值(如适用)。
*/
不可回避的();
}
/**
*删除我们已公开的页面属性,如果适用,
*将它们恢复为以前的值(和作用域)。
*/
不可撤销的私有无效(){
//“嵌套”变量现在只需删除即可
if(itemId!=null)
pageContext.removeAttribute(itemId,pageContext.PAGE\u范围);
if(statusId!=null)
pageContext.removeAttribute(statusId,pageContext.PAGE\u范围);
}

您的问题令人困惑<代码>${foo}不是脚本变量。那是
。那些
${}
东西被称为EL(表达式语言),参见似乎也将EL称为“脚本变量”。我正在更新这个问题,让它更清楚。你知道如何将EL变量的作用域设置为嵌套的吗?很有趣。。。这与我找到的任何文档嵌套变量范围都不匹配,但它基本上是我作为一种解决方法所做的。如果存在这种情况,那么在不同的JSTL库中,嵌套变量作用域是否存在问题?这不是一个有效的补充。我发现删除属性也会删除以前定义的同名属性。根据文档,嵌套变量应该在标记的范围内定义和删除,保留任何相同名称的变量不变,如同步示例所示。我没能让这个例子起作用。
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;
  }
}
<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>
/**
 * 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);
}