4

我想将参数的变量列表添加到 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>

参数变量是一个包含参数的 Map。这当然行不通,但我目前看不到解决此问题的方法。我现在在想,我可能需要一个自定义的 freemarker 模板。任何人都可以提出更好的方法吗?

4

4 回答 4

4

也许你可以像这样使用 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 等混合使用会有些犹豫,但这很有效……

于 2009-05-21T14:39:20.413 回答
2

您可以使用遍历地图

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

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

查看在 Struts2 中将任意参数添加到 URL 以了解如何使用自定义标记执行此操作,这会导致类似的结果

<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 是一个自定义组件,它在父级是迭代器的情况下返回参数的祖父级。

于 2009-11-09T16:56:59.903 回答
2

Parameter 标签仅将参数填充到其直接前身。在参数标记周围包装迭代器标记无效。:) 要解决这个问题,您可以轻松编写一个替代参数标签,它可以使用映射直接标签可能看起来像这样。

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

<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>
于 2010-02-15T09:51:25.790 回答
0

参考评论 3,请说明您将如何在您的 jsp 中使用此自定义标记来实现所需的行为。

另外,要使用评论 1 中提到的解决方案,我们需要在 tld 文件中执行什么条目?

请让我知道这一点。

于 2014-07-30T13:33:52.093 回答