Question

Je veux ajouter une liste variable de paramètres à une balise d'URL Struts2. J'ai une carte des paramètres (paires nom-valeur) à un objet dans la session. Je me bats pour trouver une bonne approche à ce sujet. Voici le code JSP correspondant:

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

La variable paramètres est une carte qui contient les params. Ceci, bien sûr, ne fonctionne pas, mais je ne peux pas voir une façon d'aborder ce au moment. Je pense au moment où je pourrais avoir besoin d'un modèle de freemarker personnalisé pour cela. Quelqu'un peut-il suggérer une meilleure façon?

Était-ce utile?

La solution

La balise de paramètre paramètres ne remplit à son antecessor direct. EMBALLAGES une balise iterator autour de la balise de paramètre n'a pas d'effet. :) Pour résoudre cela, vous pouvez facilement écrire une balise de paramètre alternatif Wich peut utiliser une carte direclty La balise peut ressembler à ceci.

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

Et vous avez besoin d'un tld entrée correspondant

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

Autres conseils

Peut-être que vous pouvez utiliser des balises JSTL comme celui-ci

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

Je sais qu'il ya une certaine hésitation à mélanger avec EL OGNL etc, mais cela fonctionne ...

Vous pouvez itérer sur une carte en utilisant

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

mais le iterator consommera les paramètres comme il est le composant parent du param.

Consultez Ajout de paramètres arbitraires à une URL dans Struts2 pour savoir comment faire ce avec une étiquette personnalisée qui entraîne la même

<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 est un composant personnalisé qui renvoie le grand-parent du param dans le cas où le parent est un itérateur.

En ce qui concerne 3 commentaires, s'il vous plaît montrer comment voulez-vous utiliser cette balise personnalisée dans votre jsp pour achive le comportement requis.

En outre, d'utiliser la solution mentionnée dans le commentaire 1, ce qui est l'entrée que nous devons faire dans un fichier tld?

S'il vous plaît laissez-moi savoir cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top