Frage

Ich möchte eine Variable Liste von Parametern zu einem Struts2 URL Tag hinzuzufügen. Ich habe eine Karte der Parameter (Name-Wert-Paare) in einem Objekt in der Sitzung. Ich kämpfe einen guten Ansatz, um diese zu finden. Hier ist der relevante Code 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>

Die Parameter Variable ist eine Karte, die die params enthält. Dies funktioniert natürlich nicht, aber ich kann nicht einen Weg findet dies im Moment zu nähern. Ich bin im Moment denken, dass ich eine benutzerdefinierte Vorlage Freemarker für diese benötigen. Kann mir jemand einen besseren Weg vorschlagen?

War es hilfreich?

Lösung

Der Parameter Tag auffüllt Parameter nur auf seine direkten Vorgänger. Umhüllungen einen Iterator-Tag um den Parameter-Tag keine Wirkung. :) Um dies zu lösen, können Sie ganz einfach eine alternative Parameter-Tag Wich schreiben kann eine Karte verwenden direclty Der Tag ist wie folgt aussehen kann.

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

Und Sie müssen einen entsprechenden TLD-Eintrag

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

Andere Tipps

Vielleicht können Sie JSTL-Tags wie folgt verwenden

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

Ich weiß, dass es einige Zögern ist EL zu mischen mit OGNL usw., aber das funktioniert ...

Sie können eine Karte iterieren mit

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

aber der Iterator die Parameter verbrauchen, da sie die übergeordnete Komponente des param ist.

Schauen Sie sich zu einer URL beliebige Parameter Hinzufügen in Struts2 wie zu tun dies mit einem benutzerdefinierten Tags, die in den ähnlichen Ergebnissen

<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 ist eine kundenspezifische Komponente, die die Großeltern des param im Fall gibt, wo die Eltern ist ein Iterator.

Unter Bezugnahme auf 3 kommentieren, bitte zeigen, wie würden Sie diesen maßgeschneiderten Tag in Ihrem jsp verwenden das gewünschte Verhalten achive.

Auch die Lösung in Kommentar 1, erwähnt zu verwenden, was ist der Eintrag, den wir in einer TLD-Datei tun müssen?

Bitte lassen Sie mich wissen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top