Add servletRelativeAction form tag attribute

A recent change in FormTag to prepend the context and servlet paths if
not present, causes issues when used in portlet applications.
This change introduces a servletRelativeAction form tag attribute that
must be used for the context and servlet paths to be prepended.

Issue: SPR-10382
master
Rossen Stoyanchev 12 years ago
parent aaded7e30b
commit c0cacfcd68
  1. 42
      spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java
  2. 6
      spring-webmvc/src/main/resources/META-INF/spring-form.tld
  3. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/tags/form/FormTagTests.java

@ -17,6 +17,7 @@
package org.springframework.web.servlet.tags.form;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
@ -104,6 +105,8 @@ public class FormTag extends AbstractHtmlElementTag {
private String action;
private String servletRelativeAction;
private String method = DEFAULT_METHOD;
private String target;
@ -189,6 +192,21 @@ public class FormTag extends AbstractHtmlElementTag {
return this.action;
}
/**
* Set the value of the '{@code action}' attribute.
* <p>May be a runtime expression.
*/
public void setServletRelativeAction(String servletRelativeaction) {
this.servletRelativeAction = (servletRelativeaction != null ? servletRelativeaction : "");
}
/**
* Get the value of the '{@code action}' attribute.
*/
protected String getServletRelativeAction() {
return this.servletRelativeAction;
}
/**
* Set the value of the '{@code method}' attribute.
* <p>May be a runtime expression.
@ -395,22 +413,30 @@ public class FormTag extends AbstractHtmlElementTag {
/**
* Resolve the value of the '{@code action}' attribute.
* <p>If the user configured an '{@code action}' value then
* the result of evaluating this value is used. Otherwise, the
* {@link org.springframework.web.servlet.support.RequestContext#getRequestUri() originating URI}
* is used.
* <p>If the user configured an '{@code action}' value then the result of
* evaluating this value is used. If the user configured an
* '{@code servletRelativeAction}' value then the value is prepended
* with the context and servlet paths, and the result is used. Otherwise, the
* {@link org.springframework.web.servlet.support.RequestContext#getRequestUri()
* originating URI} is used.
*
* @return the value that is to be used for the '{@code action}' attribute
*/
protected String resolveAction() throws JspException {
String action = getAction();
String servletRelativeAction = getServletRelativeAction();
if (StringUtils.hasText(action)) {
String pathToServlet = getRequestContext().getPathToServlet();
if (action.startsWith("/") && !action.startsWith(getRequestContext().getContextPath())) {
action = pathToServlet + action;
}
action = getDisplayString(evaluate(ACTION_ATTRIBUTE, action));
return processAction(action);
}
else if (StringUtils.hasText(servletRelativeAction)) {
String pathToServlet = getRequestContext().getPathToServlet();
if (servletRelativeAction.startsWith("/") && !servletRelativeAction.startsWith(getRequestContext().getContextPath())) {
servletRelativeAction = pathToServlet + servletRelativeAction;
}
servletRelativeAction = getDisplayString(evaluate(ACTION_ATTRIBUTE, servletRelativeAction));
return processAction(servletRelativeAction);
}
else {
String requestUri = getRequestContext().getRequestUri();
ServletResponse response = this.pageContext.getResponse();

@ -142,6 +142,12 @@
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>HTML Required Attribute</description>
<name>servletRelativeAction</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>HTML Optional Attribute</description>
<name>method</name>

@ -179,7 +179,7 @@ public class FormTagTests extends AbstractHtmlElementTagTests {
String onreset = "onreset";
this.tag.setCommandName(commandName);
this.tag.setAction(action);
this.tag.setServletRelativeAction(action);
this.tag.setMethod(method);
this.tag.setEnctype(enctype);
this.tag.setOnsubmit(onsubmit);

Loading…
Cancel
Save