DelegatingFilterProxy autodetects a unique DispatcherServlet context
Issue: SPR-13191
This commit is contained in:
@@ -68,7 +68,7 @@ public abstract class WebApplicationContextUtils {
|
||||
|
||||
|
||||
/**
|
||||
* Find the root {@link WebApplicationContext} for this web app, typically
|
||||
* Find the root {@code WebApplicationContext} for this web app, typically
|
||||
* loaded via {@link org.springframework.web.context.ContextLoaderListener}.
|
||||
* <p>Will rethrow an exception that happened on root context startup,
|
||||
* to differentiate between a failed context startup and no context at all.
|
||||
@@ -86,7 +86,7 @@ public abstract class WebApplicationContextUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the root {@link WebApplicationContext} for this web app, typically
|
||||
* Find the root {@code WebApplicationContext} for this web app, typically
|
||||
* loaded via {@link org.springframework.web.context.ContextLoaderListener}.
|
||||
* <p>Will rethrow an exception that happened on root context startup,
|
||||
* to differentiate between a failed context startup and no context at all.
|
||||
@@ -99,7 +99,7 @@ public abstract class WebApplicationContextUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a custom {@link WebApplicationContext} for this web app.
|
||||
* Find a custom {@code WebApplicationContext} for this web app.
|
||||
* @param sc ServletContext to find the web application context for
|
||||
* @param attrName the name of the ServletContext attribute to look for
|
||||
* @return the desired WebApplicationContext for this web app, or {@code null} if none
|
||||
@@ -125,6 +125,40 @@ public abstract class WebApplicationContextUtils {
|
||||
return (WebApplicationContext) attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a unique {@code WebApplicationContext} for this web app: either the
|
||||
* root web app context (preferred) or a unique {@code WebApplicationContext}
|
||||
* among the registered {@code ServletContext} attributes (typically coming
|
||||
* from a single {@code DispatcherServlet} in the current web application).
|
||||
* <p>Note that {@code DispatcherServlet}'s exposure of its context can be
|
||||
* controlled through its {@code publishContext} property, which is {@code true}
|
||||
* by default but can be selectively switched to only publish a single context
|
||||
* despite multiple {@code DispatcherServlet} registrations in the web app.
|
||||
* @param sc ServletContext to find the web application context for
|
||||
* @return the desired WebApplicationContext for this web app, or {@code null} if none
|
||||
* @since 4.2
|
||||
* @see #getWebApplicationContext(ServletContext)
|
||||
* @see ServletContext#getAttributeNames()
|
||||
*/
|
||||
public static WebApplicationContext findWebApplicationContext(ServletContext sc) {
|
||||
WebApplicationContext wac = getWebApplicationContext(sc);
|
||||
if (wac == null) {
|
||||
Enumeration<String> attrNames = sc.getAttributeNames();
|
||||
while (attrNames.hasMoreElements()) {
|
||||
String attrName = attrNames.nextElement();
|
||||
Object attrValue = sc.getAttribute(attrName);
|
||||
if (attrValue instanceof WebApplicationContext) {
|
||||
if (wac != null) {
|
||||
throw new IllegalStateException("No unique WebApplicationContext found: more than one " +
|
||||
"DispatcherServlet registered with publishContext=true?");
|
||||
}
|
||||
wac = (WebApplicationContext) attrValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wac;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register web-specific scopes ("request", "session", "globalSession")
|
||||
|
||||
@@ -249,7 +249,8 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
if (this.delegate == null) {
|
||||
WebApplicationContext wac = findWebApplicationContext();
|
||||
if (wac == null) {
|
||||
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
|
||||
throw new IllegalStateException("No WebApplicationContext found: " +
|
||||
"no ContextLoaderListener or DispatcherServlet registered?");
|
||||
}
|
||||
this.delegate = initDelegate(wac);
|
||||
}
|
||||
@@ -288,11 +289,12 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
*/
|
||||
protected WebApplicationContext findWebApplicationContext() {
|
||||
if (this.webApplicationContext != null) {
|
||||
// the user has injected a context at construction time -> use it
|
||||
// The user has injected a context at construction time -> use it...
|
||||
if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
|
||||
if (!((ConfigurableApplicationContext)this.webApplicationContext).isActive()) {
|
||||
// the context has not yet been refreshed -> do so before returning it
|
||||
((ConfigurableApplicationContext)this.webApplicationContext).refresh();
|
||||
ConfigurableApplicationContext cac = (ConfigurableApplicationContext) this.webApplicationContext;
|
||||
if (!cac.isActive()) {
|
||||
// The context has not yet been refreshed -> do so before returning it...
|
||||
cac.refresh();
|
||||
}
|
||||
}
|
||||
return this.webApplicationContext;
|
||||
@@ -302,7 +304,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
return WebApplicationContextUtils.getWebApplicationContext(getServletContext(), attrName);
|
||||
}
|
||||
else {
|
||||
return WebApplicationContextUtils.getWebApplicationContext(getServletContext());
|
||||
return WebApplicationContextUtils.findWebApplicationContext(getServletContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user