Disable response caching when controller resolves ETag

See gh-22797
This commit is contained in:
Rossen Stoyanchev 2019-04-18 11:45:05 -04:00
parent 13c746ae9d
commit 1a97a26eb7
2 changed files with 19 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -48,6 +48,7 @@ import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
@ -207,6 +208,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
&& isResourceNotModified(inputMessage, outputMessage)) {
// Ensure headers are flushed, no body should be written.
outputMessage.flush();
ShallowEtagHeaderFilter.disableContentCaching(inputMessage.getServletRequest());
// Skip call to converters, as they may update the body.
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.concurrent.Callable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.MethodParameter;
@ -33,6 +34,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
@ -104,6 +106,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
@ -160,6 +163,18 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
return webRequest.isNotModified();
}
private void disableContentCachingIfNecessary(ServletWebRequest webRequest) {
if (!isRequestNotModified(webRequest)) {
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
Assert.notNull(response, "Expected HttpServletResponse");
if (StringUtils.hasText(response.getHeader("ETag"))) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
Assert.notNull(request, "Expected HttpServletRequest");
ShallowEtagHeaderFilter.disableContentCaching(request);
}
}
}
private String formatErrorForReturnValue(@Nullable Object returnValue) {
return "Error handling return value=[" + returnValue + "]" +
(returnValue != null ? ", type=" + returnValue.getClass().getName() : "") +