SPR-7695 - Add ETag version of WebRequest.checkNotModified()

This commit is contained in:
Arjen Poutsma
2010-10-29 10:28:47 +00:00
parent 095a36e853
commit 7cc3f49910
5 changed files with 157 additions and 15 deletions

View File

@@ -130,6 +130,10 @@ public class FacesWebRequest extends FacesRequestAttributes implements NativeWeb
return false;
}
public boolean checkNotModified(String eTag) {
return false;
}
public String getDescription(boolean includeClientInfo) {
ExternalContext externalContext = getExternalContext();
StringBuilder sb = new StringBuilder();

View File

@@ -40,10 +40,16 @@ import org.springframework.util.StringUtils;
*/
public class ServletWebRequest extends ServletRequestAttributes implements NativeWebRequest {
private static final String HEADER_ETAG = "ETag";
private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
private static final String HEADER_LAST_MODIFIED = "Last-Modified";
private static final String METHOD_GET = "GET";
private HttpServletResponse response;
@@ -186,7 +192,7 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
long ifModifiedSince = getRequest().getDateHeader(HEADER_IF_MODIFIED_SINCE);
this.notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000));
if (this.response != null) {
if (this.notModified && "GET".equals(getRequest().getMethod())) {
if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
else {
@@ -197,6 +203,30 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
return this.notModified;
}
public boolean checkNotModified(String eTag) {
if (StringUtils.hasLength(eTag) && !this.notModified &&
(this.response == null || !this.response.containsHeader(HEADER_ETAG))) {
if (!eTag.startsWith("\"")) {
eTag = "\"" + eTag;
}
if (!eTag.endsWith("\"")) {
eTag = eTag + "\"";
}
String ifNoneMatch = getRequest().getHeader(HEADER_IF_NONE_MATCH);
this.notModified = eTag.equals(ifNoneMatch);
if (this.response != null) {
if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
else {
this.response.setHeader(HEADER_ETAG, eTag);
}
}
}
return this.notModified;
}
public boolean isNotModified() {
return this.notModified;
}

View File

@@ -141,6 +141,9 @@ public interface WebRequest extends RequestAttributes {
* model.addAttribute(...);
* return "myViewName";
* }</pre>
* <p><strong>Note:</strong> that you typically want to use either
* this {@link #checkNotModified(long)} method; or
* {@link #checkNotModified(String)}, but not both.
* @param lastModifiedTimestamp the last-modified timestamp that
* the application determined for the underlying resource
* @return whether the request qualifies as not modified,
@@ -149,6 +152,35 @@ public interface WebRequest extends RequestAttributes {
*/
boolean checkNotModified(long lastModifiedTimestamp);
/**
* Check whether the request qualifies as not modified given the
* supplied {@code ETag} (entity tag), as determined by the application.
* <p>This will also transparently set the appropriate response headers,
* for both the modified case and the not-modified case.
* <p>Typical usage:
* <pre class="code">
* public String myHandleMethod(WebRequest webRequest, Model model) {
* String eTag = // application-specific calculation
* if (request.checkNotModified(eTag)) {
* // shortcut exit - no further processing necessary
* return null;
* }
* // further request processing, actually building content
* model.addAttribute(...);
* return "myViewName";
* }</pre>
* <p><strong>Note:</strong> that you typically want to use either
* this {@link #checkNotModified(String)} method; or
* {@link #checkNotModified(long)}, but not both.
* @param eTag the entity tag that the application determined
* for the underlying resource. This parameter will be padded
* with quotes (") if necessary.
* @return whether the request qualifies as not modified,
* allowing to abort request processing and relying on the response
* telling the client that the content has not been modified
*/
boolean checkNotModified(String eTag);
/**
* Get a short description of this request,
* typically containing request URI and session id.