代码之家  ›  专栏  ›  技术社区  ›  Jon Clegg

将参数从映射添加到URL标记

  •  4
  • Jon Clegg  · 技术社区  · 6 年前

    我想将参数的变量列表添加到struts2 URL标记中。我在会话中有一个对象中参数(名称-值对)的映射。我正在努力找到一个很好的方法。以下是相关的JSP代码:

        <s:iterator value="%{#session['com.strutsschool.interceptors.breadcrumbs']}" status="status">
        <s:if test="#status.index > 0">
            &#187;
        </s:if>
        <s:url id="uri" action="%{action}" namespace="%{nameSpace}">
                <s:param name="parameters" value="%{parameters}"/>
        </s:url>
        <nobr><s:a href="%{uri}"><s:property value="displayName"/></s:a></nobr>
    </s:iterator>
    

    参数变量是包含参数的映射。当然,这不起作用,但目前我看不出一种方法来解决这个问题。我现在在想,我可能需要一个自定义的FreeMarker模板。有人能提出更好的方法吗?

    4 回复  |  直到 11 年前
        1
  •  2
  •   Stefan Gebhardt    13 年前

    参数标记只将参数填充到其直接先行器。在参数标记周围包装迭代器标记没有效果。:) 要解决这个问题,您可以很容易地编写一个可选的参数标记,wich可以使用map direclty 标签可能看起来像这样。

    package my.taglibs;
    
    import java.io.Writer;
    import java.util.Map;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.struts2.components.Component;
    import org.apache.struts2.views.jsp.ComponentTagSupport;
    import com.opensymphony.xwork2.util.ValueStack;
    
    public class ParamTag extends ComponentTagSupport {
    
        private String map;
        private static final long serialVersionUID = 2522878390854066408L;
        Log log = LogFactory.getLog(ParamTag.class);
    
        @Override
        public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
            return new Param(stack);
        }
    
        @Override
        protected void populateParams() {
            super.populateParams();
    
            Param param = (Param) component;
            param.setMap(map);
        }
    
        public void setMap(String map) {
            this.map = map;
        }
    
        public class Param extends Component {
    
            private String map; 
    
            public Param(ValueStack stack) {
                super(stack);
            }
    
            @Override
            public boolean end(Writer writer, String body) {
                Component component = findAncestor(Component.class);
                if (this.map == null) {       
                    log.warn("Attribute map is mandatory.");
                    return super.end(writer, "");
                }
                Object o = findValue(this.map); //find map in vs
                if(o == null) {
                    log.warn("map not found in ValueStack");
                    return super.end(writer, "");
                }
                if(!(o instanceof Map)) {
                    log.warn("Error in JSP. Attribute map must evaluate to java.util.Map. Found type: " + o.getClass().getName());
                    return super.end(writer, "");
                }
    
                component.addAllParameters((Map) o);
                return super.end(writer, "");
            }
    
            public void setMap(String map) {
                this.map = map;
            }
        }
    }
    

    你需要一个相应的TLD条目

    <tag>
        <description><![CDATA[Parametrize other tags]]></description>
        <name>param</name>
        <tag-class>my.taglibs.ParamTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>map</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <dynamic-attributes>false</dynamic-attributes>
    </tag>
    
        2
  •  4
  •   Vincent Ramdhanie    16 年前

    也许您可以使用这样的JSTL标记

     <c:url var="uri" value="${namespace}/${action}.action">                
                        <c:forEach items="${parameters}" var="p">
                            <c:param name="${p.key}" value="${p.value}"/>
                        </c:forEach>
    </c:url>
    <a href="${uri}">Your Link</a>
    

    我知道有一些犹豫,以混合EL和ognl等,但这工作…

        3
  •  2
  •   user207095    15 年前

    您可以使用

    <s:url var="url" action="%{link}" >
      <s:iterator value="parameters.keySet()" var="key">
        <s:param name="%{key}" value="%{parameters.get(#key)}"/>
      </s:iterator>
    </s:url>
    

    但是迭代器将使用参数,因为它是参数的父组件。

    退房 Adding arbitrary parameters to a URL in Struts2 有关如何使用自定义标记执行此操作,该标记会导致

    <s:url var="url" action="%{link}" >
      <s:iterator value="parameters.keySet()" var="key">
        <ob:iterable-param name="%{key}" value="%{parameters.get(#key)}"/>
      </s:iterator>
    </s:url>
    

    iterable param是一个自定义组件,在父级是迭代器的情况下返回参数的祖辈。

        4
  •  0
  •   azaveri7    11 年前

    关于注释3,请说明如何在JSP中使用这个定制的标记来实现所需的行为。

    另外,要使用注释1中提到的解决方案,我们需要在TLD文件中做什么条目?

    请告诉我这个。

    推荐文章