Fix missing ETag/LastModified headers in responses

Prior to this commit, the `HttpEntityMethodProcessor` would avoid
writing ETag/Last-Modified response headers before calling
`ServletWebRequest` to process conditional requests. This was done to
avoid duplicate response header values due to headers being already
written to the underlying servlet response.

This is still necessary for GET/HEAD requests, since this is properly
handled by `ServletWebRequest` for those cases. But
`HttpEntityMethodProcessor` should not make that decision for
PUT/PATCH/POST responses since developers are adding response headers on
purpose and should be in control of the situation — whereas
`ServletWebRequest` does not write those headers in those cases.

Issue: SPR-14767
This commit is contained in:
Brian Clozel
2016-10-04 10:46:11 +02:00
parent 487bc7505b
commit ee17f56626
2 changed files with 126 additions and 148 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
@@ -183,7 +184,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
if (responseEntity instanceof ResponseEntity) {
int returnStatus = ((ResponseEntity<?>) responseEntity).getStatusCodeValue();
outputMessage.getServletResponse().setStatus(returnStatus);
if(returnStatus == 200) {
if (returnStatus == 200) {
if (isResourceNotModified(inputMessage, outputMessage)) {
// Ensure headers are flushed, no body should be written.
outputMessage.flush();
@@ -227,8 +228,10 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
HttpHeaders responseHeaders = outputMessage.getHeaders();
String etag = responseHeaders.getETag();
long lastModifiedTimestamp = responseHeaders.getLastModified();
responseHeaders.remove(HttpHeaders.ETAG);
responseHeaders.remove(HttpHeaders.LAST_MODIFIED);
if (inputMessage.getMethod() == HttpMethod.GET || inputMessage.getMethod() == HttpMethod.HEAD) {
responseHeaders.remove(HttpHeaders.ETAG);
responseHeaders.remove(HttpHeaders.LAST_MODIFIED);
}
return servletWebRequest.checkNotModified(etag, lastModifiedTimestamp);
}