|  | 
| 17 | 17 | package org.springframework.web.servlet.tags.form; | 
| 18 | 18 | 
 | 
| 19 | 19 | import java.util.Map; | 
|  | 20 | + | 
| 20 | 21 | import javax.servlet.ServletRequest; | 
| 21 | 22 | import javax.servlet.ServletResponse; | 
| 22 | 23 | import javax.servlet.http.HttpServletRequest; | 
| @@ -104,6 +105,8 @@ public class FormTag extends AbstractHtmlElementTag { | 
| 104 | 105 | 
 | 
| 105 | 106 | 	private String action; | 
| 106 | 107 | 
 | 
|  | 108 | +	private String servletRelativeAction; | 
|  | 109 | + | 
| 107 | 110 | 	private String method = DEFAULT_METHOD; | 
| 108 | 111 | 
 | 
| 109 | 112 | 	private String target; | 
| @@ -189,6 +192,21 @@ protected String getAction() { | 
| 189 | 192 | 		return this.action; | 
| 190 | 193 | 	} | 
| 191 | 194 | 
 | 
|  | 195 | +	/** | 
|  | 196 | +	 * Set the value of the '{@code action}' attribute. | 
|  | 197 | +	 * <p>May be a runtime expression. | 
|  | 198 | +	 */ | 
|  | 199 | +	public void setServletRelativeAction(String servletRelativeaction) { | 
|  | 200 | +		this.servletRelativeAction = (servletRelativeaction != null ? servletRelativeaction : ""); | 
|  | 201 | +	} | 
|  | 202 | + | 
|  | 203 | +	/** | 
|  | 204 | +	 * Get the value of the '{@code action}' attribute. | 
|  | 205 | +	 */ | 
|  | 206 | +	protected String getServletRelativeAction() { | 
|  | 207 | +		return this.servletRelativeAction; | 
|  | 208 | +	} | 
|  | 209 | + | 
| 192 | 210 | 	/** | 
| 193 | 211 | 	 * Set the value of the '{@code method}' attribute. | 
| 194 | 212 | 	 * <p>May be a runtime expression. | 
| @@ -395,22 +413,30 @@ protected String resolveModelAttribute() throws JspException { | 
| 395 | 413 | 
 | 
| 396 | 414 | 	/** | 
| 397 | 415 | 	 * Resolve the value of the '{@code action}' attribute. | 
| 398 |  | -	 * <p>If the user configured an '{@code action}' value then | 
| 399 |  | -	 * the result of evaluating this value is used. Otherwise, the | 
| 400 |  | -	 * {@link org.springframework.web.servlet.support.RequestContext#getRequestUri() originating URI} | 
| 401 |  | -	 * is used. | 
|  | 416 | +	 * <p>If the user configured an '{@code action}' value then the result of | 
|  | 417 | +	 * evaluating this value is used. If the user configured an | 
|  | 418 | +	 * '{@code servletRelativeAction}' value then the value is prepended | 
|  | 419 | +	 * with the context and servlet paths, and the result is used. Otherwise, the | 
|  | 420 | +	 * {@link org.springframework.web.servlet.support.RequestContext#getRequestUri() | 
|  | 421 | +	 * originating URI} is used. | 
|  | 422 | +	 * | 
| 402 | 423 | 	 * @return the value that is to be used for the '{@code action}' attribute | 
| 403 | 424 | 	 */ | 
| 404 | 425 | 	protected String resolveAction() throws JspException { | 
| 405 | 426 | 		String action = getAction(); | 
|  | 427 | +		String servletRelativeAction = getServletRelativeAction(); | 
| 406 | 428 | 		if (StringUtils.hasText(action)) { | 
| 407 |  | -			String pathToServlet = getRequestContext().getPathToServlet(); | 
| 408 |  | -			if (action.startsWith("/") && !action.startsWith(getRequestContext().getContextPath())) { | 
| 409 |  | -				action = pathToServlet + action; | 
| 410 |  | -			} | 
| 411 | 429 | 			action = getDisplayString(evaluate(ACTION_ATTRIBUTE, action)); | 
| 412 | 430 | 			return processAction(action); | 
| 413 | 431 | 		} | 
|  | 432 | +		else if (StringUtils.hasText(servletRelativeAction)) { | 
|  | 433 | +			String pathToServlet = getRequestContext().getPathToServlet(); | 
|  | 434 | +			if (servletRelativeAction.startsWith("/") && !servletRelativeAction.startsWith(getRequestContext().getContextPath())) { | 
|  | 435 | +				servletRelativeAction = pathToServlet + servletRelativeAction; | 
|  | 436 | +			} | 
|  | 437 | +			servletRelativeAction = getDisplayString(evaluate(ACTION_ATTRIBUTE, servletRelativeAction)); | 
|  | 438 | +			return processAction(servletRelativeAction); | 
|  | 439 | +		} | 
| 414 | 440 | 		else { | 
| 415 | 441 | 			String requestUri = getRequestContext().getRequestUri(); | 
| 416 | 442 | 			ServletResponse response = this.pageContext.getResponse(); | 
|  | 
0 commit comments