【问题标题】:JSP: Make a reusable code (tag, macro) and use it on the same pageJSP:制作可重用代码(标签、宏)并在同一页面上使用
【发布时间】:2014-01-16 00:31:21
【问题描述】:

有什么方法可以在一个 JSP 页面上制作某种参数化宏,并在同一页面上重复使用几次。可以使用 JSP 标记,但我必须为每个标记创建一个文件。

【问题讨论】:

    标签: jsp macros tags parameter-passing code-reuse


    【解决方案1】:

    多年来我一直想要这个功能,在再次谷歌搜索之后,我编写了自己的功能。我认为标签 / jsp 文件和自定义标签类很棒,但对于像你描述的简单一次性使用来说往往是过度的。

    这就是我的新“宏”标签现在的工作方式(这里用于可排序表头的简单 html 呈现):

    <%@ taglib prefix="tt" uri="/WEB-INF/tld/tags.tld" %>
    
    <!-- define a macro to render a sortable header -->
    <tt:macro id="sortable">
        <th class="sortable">${headerName}
            <span class="asc" >&uarr;</span>
            <span class="desc">&darr;</span>
        </th>
    </tt:macro>
    
    <table><thead><tr>
        <!-- use the macro for named headers -->
        <tt:macro id="sortable" headerName="Name (this is sortable)" />
        <tt:macro id="sortable" headerName="Age (this is sortable)" />
        <th>Sex (not sortable)</th>
        <!-- etc, etc -->
    

    在 /WEB-INF/tld/tags.tld 中,我添加了:

    <tag>
        <name>macro</name>
        <tag-class>com.acme.web.taglib.MacroTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <description>ID of macro to call or define</description>
            <name>id</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <dynamic-attributes>true</dynamic-attributes>
    </tag>
    

    最后是 Java 标记类:

    public class MacroTag
        extends SimpleTagSupport implements DynamicAttributes
    {
        public static final String PREFIX = "MacroTag_";
        private boolean bodyless = true;
        private String id;
        private Map<String, Object> attributes = new HashMap<String, Object>();
    
        @Override public void setJspBody(JspFragment jspFragment) {
            super.setJspBody(jspFragment);
            getJspContext().setAttribute(PREFIX + id, jspFragment, PageContext.REQUEST_SCOPE);
            bodyless = false;
        }
    
        @Override public void doTag() throws JspException, IOException {
            if (bodyless) {
                JspFragment jspFragment = (JspFragment) getJspContext().getAttribute(PREFIX + id, PageContext.REQUEST_SCOPE);
                JspContext ctx = jspFragment.getJspContext();
                for (String key : attributes.keySet())
                    ctx.setAttribute(key, attributes.get(key));
                jspFragment.invoke(getJspContext().getOut());
                for (String key : attributes.keySet()) {
                    ctx.removeAttribute(key);
                }
            }
        }
    
        public void setId(String id) {
            this.id = id;
        }
        @Override public void setDynamicAttribute(String uri, String key, Object val) throws JspException {
            attributes.put(key, val);
        }
    }
    

    实现非常基本。如果标签有正文,我们假设我们正在定义一个宏,并存储该 JspFragment。否则,我们假设我们正在调用一个宏,因此我们查找它,并将任何动态属性复制到它的上下文中,以便对其进行正确参数化,并将其渲染到调用输出流中。

    这不是 JSP 内置的。

    【讨论】:

    • 这很有用。
    • 添加了 @Stefan 的错误修复(我是 SO n00b,我认为我还没有足够的尊重点来给予尊重点)。很高兴听到 AylwynLake 的消息!
    【解决方案2】:

    我尝试了 Johnny 的解决方案,发现如果多次使用宏,就会出现错误。

    您必须在重新处理后从页面上下文中删除属性

    jspFragment.invoke(getJspContext().getOut());
    
    for (String key : attributes.keySet()) {
        ctx.removeAttribute(key);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多