java 将地图中的参数添加到 URL 标记
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/872375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding parameters from a map to a URL tag
提问by Peter Kelley
I want to add a variable list of parameters to a Struts2 URL tag. I have a map of the parameters (name value pairs) in an object in the session. I'm struggling to find a good approach to this. Here is the relevant JSP code:
我想向 Struts2 URL 标记添加一个可变参数列表。我在会话中的一个对象中有一个参数(名称值对)的映射。我正在努力寻找解决这个问题的好方法。下面是相关的JSP代码:
<s:iterator value="%{#session['com.strutsschool.interceptors.breadcrumbs']}" status="status">
<s:if test="#status.index > 0">
»
</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>
The parameters variable is a Map that contains the params. This, of course does not work but I cannot see a way to approach this at the moment. I'm thinking at the moment that I might need a custom freemarker template for this. Can anyone suggest a better way?
参数变量是一个包含参数的 Map。这当然行不通,但我目前看不到解决此问题的方法。我现在在想我可能需要一个自定义的 freemarker 模板。任何人都可以提出更好的方法吗?
采纳答案by Stefan Gebhardt
The Parameter tag populates parameters only to its direct antecessor. Wrappings an iterator tag around the parameter tag has no effect. :) To solve this you can easily write an alternative parameter tag wich can use a map direclty The tag may look like this.
Parameter 标签仅将参数填充到其直接前序。环绕参数标签的迭代器标签没有效果。:) 要解决这个问题,您可以轻松编写一个替代参数标签,该标签可以使用地图 direclty 该标签可能如下所示。
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 a corresponding tld-entry
你需要一个相应的 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>
回答by Vincent Ramdhanie
Maybe you can use JSTL tags like this
也许你可以使用这样的 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>
I know there is some hesitation to mix EL with OGNL etc but this works...
我知道将 EL 与 OGNL 等混合使用时有些犹豫,但这有效......
回答by Vincent Ramdhanie
You can iterate over a 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 consume the parameters as it's the parent component of the param.
但迭代器将使用参数,因为它是 param 的父组件。
Check outAdding arbitrary parameters to a URL in Struts2for how to do this with a custom tag which results in the similar
查看向 Struts2 中的 URL 添加任意参数以了解如何使用自定义标签执行此操作,这会导致类似的结果
<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 of the param in the case where the parent is an iterator.
iterable-param 是一个自定义组件,在父项是迭代器的情况下返回 param 的祖父项。
回答by azaveri7
With reference to comment 3, please show how would you use this customized tag in your jsp to achive the required behaviour.
参考评论 3,请说明您将如何在您的 jsp 中使用此自定义标签来实现所需的行为。
Also, to use the solution mentioned in comment 1, what is the entry that we need to do in a tld file?
另外,要使用注释 1 中提到的解决方案,我们需要在 tld 文件中执行哪些条目?
Please let me know this.
请让我知道这一点。

