SPR-6144 - @ResponseStatus annotation is ignored in an @Controller redirect (RedirectView)

SPR-5468 - Modify RedirectView to allow 301 Permanent Redirects
This commit is contained in:
Arjen Poutsma
2009-09-25 10:23:06 +00:00
parent 6fe0e36fe0
commit 5b12503c47
5 changed files with 128 additions and 26 deletions

View File

@@ -37,11 +37,20 @@ import javax.servlet.http.HttpServletResponse;
* As this interface is stateless, view implementations should be thread-safe.
*
* @author Rod Johnson
* @author Arjen Poutsma
* @see org.springframework.web.servlet.view.AbstractView
* @see org.springframework.web.servlet.view.InternalResourceView
*/
public interface View {
/**
* Name of the {@link HttpServletRequest} attribute that contains the response status code.
* <p>Note: This attribute is not required to be supported by all
* View implementations.
*/
String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
/**
* Return the content type of the view, if predetermined.
* <p>Can be used to check the content type upfront,

View File

@@ -57,6 +57,7 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
@@ -708,10 +709,12 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
ExtendedModelMap implicitModel,
ServletWebRequest webRequest) throws Exception {
ResponseStatus responseStatus = AnnotationUtils.findAnnotation(handlerMethod, ResponseStatus.class);
if (responseStatus != null) {
HttpServletResponse response = webRequest.getResponse();
response.setStatus(responseStatus.value().value());
ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(handlerMethod, ResponseStatus.class);
if (responseStatusAnn != null) {
HttpStatus responseStatus = responseStatusAnn.value();
// to be picked up by the RedirectView
webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, responseStatus);
webRequest.getResponse().setStatus(responseStatus.value());
responseArgumentUsed = true;
}

View File

@@ -32,6 +32,8 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;
import org.springframework.web.servlet.View;
import org.springframework.http.HttpStatus;
/**
* <p>View that redirects to an absolute, context relative, or current request
@@ -63,6 +65,7 @@ import org.springframework.web.util.WebUtils;
* @author Juergen Hoeller
* @author Colin Sampaleanu
* @author Sam Brannen
* @author Arjen Poutsma
* @see #setContextRelative
* @see #setHttp10Compatible
* @see #setExposeModelAttributes
@@ -78,6 +81,8 @@ public class RedirectView extends AbstractUrlBasedView {
private String encodingScheme;
private HttpStatus statusCode;
/**
* Constructor for use as a bean.
@@ -183,6 +188,14 @@ public class RedirectView extends AbstractUrlBasedView {
this.encodingScheme = encodingScheme;
}
/**
* Set the status code for this view.
* <p>Default is to send 302/303, depending on the value of the
* {@link #setHttp10Compatible(boolean) http10Compatible} flag.
*/
public void setStatusCode(HttpStatus statusCode) {
this.statusCode = statusCode;
}
/**
* Convert model to request parameters and redirect to the given URL.
@@ -381,10 +394,29 @@ public class RedirectView extends AbstractUrlBasedView {
response.sendRedirect(response.encodeRedirectURL(targetUrl));
}
else {
// Correct HTTP status code is 303, in particular for POST requests.
response.setStatus(303);
HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
response.setStatus(statusCode.value());
response.setHeader("Location", response.encodeRedirectURL(targetUrl));
}
}
/**
* Determines the status code to use for HTTP 1.1 compatible requests.
* <p>The default implemenetation returns the {@link #setStatusCode(HttpStatus) statusCode}
* property if set, or the value of the {@link #RESPONSE_STATUS_ATTRIBUTE} attribute. If neither are
* set, it defaults to {@link HttpStatus#SEE_OTHER} (303).
* @param request the request to inspect
* @return the response
*/
protected HttpStatus getHttp11StatusCode(HttpServletRequest request, HttpServletResponse response, String targetUrl) {
if (statusCode != null) {
return statusCode;
}
HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE);
if (attributeStatusCode != null) {
return attributeStatusCode;
}
return HttpStatus.SEE_OTHER;
}
}