【问题标题】:nested el variables for jsp taglibsjsp taglibs的嵌套el变量
【发布时间】:2011-06-02 09:36:32
【问题描述】:

我正在尝试创建一个仅在标签内可用的 el 变量,以便它类似于:

<mytaglib:mytag>
  Foo is ${foo}
</mytaglib:mytag>

我已经按照我可以找到的创建嵌套 el 变量的文档进行操作,但是,${foo} 在 mytag 结束后可用。

.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 中评估实际正文。 尽管“已使用”在标签范围之外可用,但似乎应该是这种情况。

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

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

【问题讨论】:

标签: jsp el taglib


【解决方案1】:

我总是引用 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);
}

【讨论】:

  • 有趣...这与我发现的任何文档嵌套变量范围都不匹配,但它基本上是我作为解决方法所做的。鉴于这种情况存在,在不同的 JSTL 库中是否存在用于变量工作的嵌套范围的问题?
  • 这不是一个有效的补充。我发现删除该属性也会删除任何先前定义的同名属性。根据文档,应在标签范围内定义和删除 NESTED 变量,使任何同名变量保持不变,如同步示例here。我无法让该示例正常工作。
猜你喜欢
  • 2011-11-03
  • 1970-01-01
  • 2012-05-05
  • 2013-04-15
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
相关资源
最近更新 更多