Domanda

Voglio aggiungere una lista di parametri variabile a un tag URL Struts2. Ho una mappa dei parametri (coppie di valori nome) in un oggetto nella sessione. Sto lottando per trovare un buon approccio a questo. Ecco il codice JSP rilevanti:

    <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 variabile parametri è una mappa che contiene i params. Questo, ovviamente non funziona, ma non riesco a vedere un modo per avvicinarsi a questo al momento. Sto pensando in questo momento che potrei avere bisogno di un modello freemarker personalizzato per questo. Qualcuno può suggerire un modo migliore?

È stato utile?

Soluzione

Il tag Parameter popola i parametri solo al suo antecessor diretta. CONFEZIONI un tag iteratore attorno al tag parametro non ha alcun effetto. :) Per risolvere questo si può facilmente scrivere alternativa tag parametro Quale può utilizzare una mappa direttamene Il tag può apparire come questo.

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

E avete bisogno di un corrispondente 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>

Altri suggerimenti

Forse è possibile utilizzare i tag JSTL come questo

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

So che c'è una certa esitazione a mescolare EL con OGNL ecc, ma questo funziona ...

È possibile iterare su una mappa utilizzando

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

ma l'iteratore si consumano i parametri in quanto è il componente principale del param.

Aggiunta di parametri arbitrari ad un URL in Struts2 per sapere come fare questo con un costume tag che si traduce nella simili

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

iterabile-param è un componente personalizzato che restituisce il nonno del param nel caso in cui il genitore è un iteratore.

Con riferimento alle osservazioni 3, si prega di mostrare come si usa questo tag personalizzato nella vostra jsp per achive il comportamento richiesto.

Inoltre, per utilizzare la soluzione di cui al commento 1, qual è la voce che abbiamo bisogno di fare in un file TLD?

Per favore fatemi sapere questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top