Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions core/src/main/java/org/apache/struts2/components/Anchor.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@
* <!-- START SNIPPET: javadoc -->
* <p>
* A tag that creates a HTML &lt;a &gt;.This tag supports the same attributes as the "url" tag,
* including nested parameters using the "param" tag.
* including nested parameters using the "param" tag. Nested parameters are applied only when the URL is built
* from the "value" or "action" attributes; they are ignored when "href" is set.
* </p>
* <!-- END SNIPPET: javadoc -->
*
* <p><b>Examples</b></p>
*
* <pre>
* <!-- START SNIPPET: example1 -->
* &lt;s:a id="link1" href="/do-it.action"&gt;
* &lt;s:a id="link1" value="/do-it.action"&gt;
* &lt;img border="none" src="&lt;%=request.getContextPath()%&gt;/images/delete.gif"/&gt;
* &lt;s:param name="id" value="1"/&gt;
* &lt;/s:a&gt;
Expand Down Expand Up @@ -101,6 +102,10 @@ protected void evaluateExtraParams() {

if (href != null) {
addParameter("href", ensureAttributeSafelyNotEscaped(findString(href)));
if (devMode && !urlParameters.isEmpty()) {
LOG.warn("Nested params {} are ignored because <s:a> has href [{}], use value or action to build a URL with params",
urlParameters.keySet(), href);
}
} else {
//no href, build it from URL attributes
StringWriter sw = new StringWriter();
Expand Down Expand Up @@ -189,7 +194,7 @@ public UrlProvider getUrlProvider() {
return urlProvider;
}

@StrutsTagAttribute(description = "The URL.")
@StrutsTagAttribute(description = "The URL. Nested param tags are not applied, use value or action to build a URL with params")
public void setHref(String href) {
this.href = href;
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/site/resources/tags/a-attributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
<td class="tag-attribute"></td>
<td class="tag-attribute">false</td>
<td class="tag-attribute">String</td>
<td class="tag-attribute">The URL.</td>
<td class="tag-attribute">The URL. Nested param tags are not applied, use value or action to build a URL with params</td>
</tr>
<tr>
<td class="tag-attribute">id</td>
Expand Down
50 changes: 50 additions & 0 deletions core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package org.apache.struts2.views.jsp;

import org.apache.struts2.components.Anchor;
import org.apache.struts2.test.LogCapture;
import org.apache.struts2.views.jsp.ui.AnchorTag;
import org.apache.struts2.views.jsp.ui.StrutsBodyContent;

Expand Down Expand Up @@ -1646,4 +1648,52 @@ protected void setUp() throws Exception {
pageContext.setJspWriter(jspWriter);
}

public void testHrefIgnoresNestedParams() throws Exception {
tag.setHref("/do-it.action");

try (LogCapture logs = new LogCapture(Anchor.class)) {
renderWithParam("id", "%{'1'}");

assertEquals(wrapWithAnchor("/do-it.action"), writer.toString());
assertTrue(logs.messages().toString(), logs.messages().isEmpty());
}
}

public void testHrefWithNestedParamsWarnsInDevMode() throws Exception {
setDevMode(true);
tag.setHref("/do-it.action");

try (LogCapture logs = new LogCapture(Anchor.class)) {
renderWithParam("id", "%{'1'}");

assertEquals(wrapWithAnchor("/do-it.action"), writer.toString());
assertEquals(1, logs.messages().size());
assertTrue(logs.messages().get(0), logs.messages().get(0).contains("[id]"));
}
}

public void testValueWithNestedParamsDoesNotWarnInDevMode() throws Exception {
setDevMode(true);
tag.setValue("/do-it.action");

try (LogCapture logs = new LogCapture(Anchor.class)) {
renderWithParam("id", "%{'1'}");

assertEquals(wrapWithAnchor("/do-it.action?id=1"), writer.toString());
assertTrue(logs.messages().toString(), logs.messages().isEmpty());
}
}

private void renderWithParam(String name, String value) throws JspException {
ParamTag param = new ParamTag();
param.setPageContext(pageContext);
param.setName(name);
param.setValue(value);

tag.doStartTag();
param.doStartTag();
param.doEndTag();
tag.doEndTag();
}

}
Loading