SPR-8524 Add flag to AbstractCachingViewResolver to suppress subsequent resolution of unresolved view names.
This commit is contained in:
parent
9f4a46e24c
commit
98ad8633bd
|
|
@ -42,6 +42,9 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||||
/** Whether we should cache views, once resolved */
|
/** Whether we should cache views, once resolved */
|
||||||
private boolean cache = true;
|
private boolean cache = true;
|
||||||
|
|
||||||
|
/** Whether we should attempt to resolve views again if unresolved once */
|
||||||
|
private boolean cacheUnresolved = false;
|
||||||
|
|
||||||
/** Map from view key to View instance */
|
/** Map from view key to View instance */
|
||||||
private final Map<Object, View> viewCache = new HashMap<Object, View>();
|
private final Map<Object, View> viewCache = new HashMap<Object, View>();
|
||||||
|
|
||||||
|
|
@ -63,6 +66,26 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||||
return this.cache;
|
return this.cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether a view name once resolved to {@code null} should be cached and
|
||||||
|
* automatically resolved to {@code null} subsequently.
|
||||||
|
* <p>Default is "false": unresolved view names are not cached.
|
||||||
|
* <p>Of specific interest is the ability for some AbstractUrlBasedView
|
||||||
|
* implementations (Freemarker, Velocity, Tiles) to check if an underlying
|
||||||
|
* resource exists via {@link AbstractUrlBasedView#checkResource(Locale)}.
|
||||||
|
* With this flag set to "false", an underlying resource that re-appears
|
||||||
|
* is noticed and used. With the flag set to "true", one check is made only.
|
||||||
|
*/
|
||||||
|
public void setCacheUnresolved(boolean cacheUnresolved) {
|
||||||
|
this.cacheUnresolved = cacheUnresolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if caching of unresolved views is enabled.
|
||||||
|
*/
|
||||||
|
public boolean isCacheUnresolved() {
|
||||||
|
return cacheUnresolved;
|
||||||
|
}
|
||||||
|
|
||||||
public View resolveViewName(String viewName, Locale locale) throws Exception {
|
public View resolveViewName(String viewName, Locale locale) throws Exception {
|
||||||
if (!isCache()) {
|
if (!isCache()) {
|
||||||
|
|
@ -72,7 +95,8 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||||
Object cacheKey = getCacheKey(viewName, locale);
|
Object cacheKey = getCacheKey(viewName, locale);
|
||||||
synchronized (this.viewCache) {
|
synchronized (this.viewCache) {
|
||||||
View view = this.viewCache.get(cacheKey);
|
View view = this.viewCache.get(cacheKey);
|
||||||
if (view == null) {
|
boolean isCached = this.cacheUnresolved && this.viewCache.containsKey(cacheKey);
|
||||||
|
if (view == null && !isCached) {
|
||||||
// Ask the subclass to create the View object.
|
// Ask the subclass to create the View object.
|
||||||
view = createView(viewName, locale);
|
view = createView(viewName, locale);
|
||||||
this.viewCache.put(cacheKey, view);
|
this.viewCache.put(cacheKey, view);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,18 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.view;
|
package org.springframework.web.servlet.view;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
@ -30,9 +38,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.jsp.jstl.core.Config;
|
import javax.servlet.jsp.jstl.core.Config;
|
||||||
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
|
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.PropertyValue;
|
import org.springframework.beans.PropertyValue;
|
||||||
import org.springframework.beans.TestBean;
|
import org.springframework.beans.TestBean;
|
||||||
|
|
@ -497,6 +503,31 @@ public class ViewResolverTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCacheUnresolved() throws Exception {
|
||||||
|
final AtomicInteger count = new AtomicInteger();
|
||||||
|
AbstractCachingViewResolver viewResolver = new AbstractCachingViewResolver() {
|
||||||
|
@Override
|
||||||
|
protected View loadView(String viewName, Locale locale) throws Exception {
|
||||||
|
count.incrementAndGet();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
viewResolver.setCacheUnresolved(false);
|
||||||
|
|
||||||
|
viewResolver.resolveViewName("view", Locale.getDefault());
|
||||||
|
viewResolver.resolveViewName("view", Locale.getDefault());
|
||||||
|
|
||||||
|
assertEquals(2, count.intValue());
|
||||||
|
|
||||||
|
viewResolver.setCacheUnresolved(true);
|
||||||
|
|
||||||
|
viewResolver.resolveViewName("view", Locale.getDefault());
|
||||||
|
viewResolver.resolveViewName("view", Locale.getDefault());
|
||||||
|
|
||||||
|
assertEquals(2, count.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestView extends InternalResourceView {
|
public static class TestView extends InternalResourceView {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue