Adding parameters from the map to the URL tag

I want to add a variable parameter list to the Struts2 URL tag. I have a parameter map (name value pairs) in an object in a session. I am struggling to find a good approach to this. Here is the relevant JSP code:

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

A parameter variable is a map containing parameters. This, of course, does not work, but I see no way to approach this at the moment. At the moment, I think that for this I may need a special freemarker template. Can anyone suggest a better way?

+4
source share
4 answers

The Parameter tag fills parameters only to its immediate predecessor. Wrapping the iterator tag around the parameter tag is not affected. :) To solve this problem, you can easily write an alternative parameter tag that can use the direclty map. The tag may look like this.

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

And you need the appropriate 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> 
+2
source

Maybe you can use JSTL tags like this

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

I know there is some hesitation to mix EL with OGNL etc., but it works ...

+4
source

You can iterate over the map using

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

but the iterator will use the parameters as the parent component of the parameter.

Check out Add custom parameters to URLs in Struts2 in order to do this with a custom tag that results in a similar

 <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 is a custom component that returns the grandparent parameter when parent is an iterator.

+2
source

With reference to comment 3, please show how to use this custom tag in your jsp to achieve the desired behavior.

Also, in order to use the solution mentioned in comment 1, what is the record we need to make in the tld file?

Please let me know about this.

0
source

All Articles