Servlet/PortletResponse supported as a resolvable dependency now (in particular for web controllers)
This feature required support for response exposure on Servlet/PortletRequestAttributes, instead of just in the Servlet/PortletWebRequest subclasses. Issue: SPR-11795
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.web.context.request;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
@@ -48,6 +49,8 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private HttpServletResponse response;
|
||||
|
||||
private volatile HttpSession session;
|
||||
|
||||
private final Map<String, Object> sessionAttributesToUpdate = new ConcurrentHashMap<String, Object>(1);
|
||||
@@ -62,6 +65,16 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ServletRequestAttributes instance for the given request.
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response (for optional exposure)
|
||||
*/
|
||||
public ServletRequestAttributes(HttpServletRequest request, HttpServletResponse response) {
|
||||
this(request);
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exposes the native {@link HttpServletRequest} that we're wrapping.
|
||||
@@ -70,6 +83,13 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
|
||||
return this.request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the native {@link HttpServletResponse} that we're wrapping (if any).
|
||||
*/
|
||||
public final HttpServletResponse getResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the {@link HttpSession} that we're wrapping.
|
||||
* @param allowCreate whether to allow creation of a new session if none exists yet
|
||||
|
||||
@@ -52,8 +52,6 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
private static final String METHOD_HEAD = "HEAD";
|
||||
|
||||
|
||||
private HttpServletResponse response;
|
||||
|
||||
private boolean notModified = false;
|
||||
|
||||
|
||||
@@ -71,18 +69,10 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
* @param response current HTTP response (for automatic last-modified handling)
|
||||
*/
|
||||
public ServletWebRequest(HttpServletRequest request, HttpServletResponse response) {
|
||||
this(request);
|
||||
this.response = response;
|
||||
super(request, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exposes the native {@link HttpServletRequest} that we're wrapping (if any).
|
||||
*/
|
||||
public final HttpServletResponse getResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNativeRequest() {
|
||||
return getRequest();
|
||||
@@ -181,8 +171,9 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean checkNotModified(long lastModifiedTimestamp) {
|
||||
HttpServletResponse response = getResponse();
|
||||
if (lastModifiedTimestamp >= 0 && !this.notModified &&
|
||||
(this.response == null || !this.response.containsHeader(HEADER_LAST_MODIFIED))) {
|
||||
(response == null || !response.containsHeader(HEADER_LAST_MODIFIED))) {
|
||||
long ifModifiedSince = -1;
|
||||
try {
|
||||
ifModifiedSince = getRequest().getDateHeader(HEADER_IF_MODIFIED_SINCE);
|
||||
@@ -202,12 +193,12 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
}
|
||||
}
|
||||
this.notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000));
|
||||
if (this.response != null) {
|
||||
if (response != null) {
|
||||
if (this.notModified && supportsNotModifiedStatus()) {
|
||||
this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
}
|
||||
else {
|
||||
this.response.setDateHeader(HEADER_LAST_MODIFIED, lastModifiedTimestamp);
|
||||
response.setDateHeader(HEADER_LAST_MODIFIED, lastModifiedTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,16 +207,17 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
|
||||
|
||||
@Override
|
||||
public boolean checkNotModified(String etag) {
|
||||
HttpServletResponse response = getResponse();
|
||||
if (StringUtils.hasLength(etag) && !this.notModified &&
|
||||
(this.response == null || !this.response.containsHeader(HEADER_ETAG))) {
|
||||
(response == null || !response.containsHeader(HEADER_ETAG))) {
|
||||
String ifNoneMatch = getRequest().getHeader(HEADER_IF_NONE_MATCH);
|
||||
this.notModified = etag.equals(ifNoneMatch);
|
||||
if (this.response != null) {
|
||||
if (response != null) {
|
||||
if (this.notModified && supportsNotModifiedStatus()) {
|
||||
this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
}
|
||||
else {
|
||||
this.response.setHeader(HEADER_ETAG, etag);
|
||||
response.setHeader(HEADER_ETAG, etag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -26,6 +26,7 @@ import javax.faces.context.FacesContext;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
@@ -154,6 +155,7 @@ public abstract class WebApplicationContextUtils {
|
||||
}
|
||||
|
||||
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
|
||||
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
|
||||
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
|
||||
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
|
||||
if (jsfPresent) {
|
||||
@@ -300,6 +302,29 @@ public abstract class WebApplicationContextUtils {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory that exposes the current response object on demand.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class ResponseObjectFactory implements ObjectFactory<ServletResponse>, Serializable {
|
||||
|
||||
@Override
|
||||
public ServletResponse getObject() {
|
||||
ServletResponse response = currentRequestAttributes().getResponse();
|
||||
if (response == null) {
|
||||
throw new IllegalStateException("Current servlet response not available - " +
|
||||
"consider using RequestContextFilter instead of RequestContextListener");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Current HttpServletResponse";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory that exposes the current session object on demand.
|
||||
*/
|
||||
@@ -326,7 +351,8 @@ public abstract class WebApplicationContextUtils {
|
||||
|
||||
@Override
|
||||
public WebRequest getObject() {
|
||||
return new ServletWebRequest(currentRequestAttributes().getRequest());
|
||||
ServletRequestAttributes requestAttr = currentRequestAttributes();
|
||||
return new ServletWebRequest(requestAttr.getRequest(), requestAttr.getResponse());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.web.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -92,7 +91,7 @@ public class RequestContextFilter extends OncePerRequestFilter {
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
|
||||
ServletRequestAttributes attributes = new ServletRequestAttributes(request, response);
|
||||
initContextHolders(request, attributes);
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user