【问题标题】:Adding parameters from a map to a URL tag将地图中的参数添加到 URL 标记
【发布时间】:2010-10-26 17:18:40
【问题描述】:

我想将参数的变量列表添加到 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 模板。任何人都可以提出更好的方法吗?

【问题讨论】:

    标签: java url struts2 tags param


    【解决方案1】:

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

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

    请告诉我。

    【讨论】:

      【解决方案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>
      

      【讨论】:

        【解决方案3】:

        您可以使用迭代地图

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

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

          【讨论】:

          • +1 表示简短、简洁的 sn-p 以及关于 EL 和 OGNL 有时不适合的充分评论。无论如何,我认为这没有问题。
          猜你喜欢
          • 2018-07-30
          • 2015-03-08
          • 2018-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多