From 451cce4fe8c0eff189de1e6c08bca4138313337b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 13 Jun 2019 17:42:14 +0300 Subject: [PATCH] Do not override requestContextAttribute with null in UrlBasedViewResolvers Prior to this commit, if a subclass of org.springframework.web.servlet.view.AbstractView or org.springframework.web.reactive.result.view.AbstractUrlBasedView configured a custom value for the requestContextAttribute, that value was overwritten with null whenever the View was dynamically instantiated by a UrlBasedViewResolver, and this could lead to confusing behavior for users of the View. This commit addresses this issue by ensuring that the UrlBasedViewResolvers in spring-webmvc and spring-webflux do not override the requestContextAttribute in a View if the UrlBasedViewResolver has not been explicitly configured with a custom requestContextAttribute value. Closes gh-23129 --- .../result/view/UrlBasedViewResolver.java | 15 +- .../view/UrlBasedViewResolverTests.java | 48 ++- .../servlet/view/UrlBasedViewResolver.java | 16 +- .../web/servlet/view/ViewResolverTests.java | 323 +++++++++--------- 4 files changed, 235 insertions(+), 167 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java index 8ac251a338..4390875bed 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/UrlBasedViewResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 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. @@ -30,8 +30,8 @@ import org.springframework.util.Assert; import org.springframework.util.PatternMatchUtils; /** - * A {@link ViewResolver} that allow direct resolution of symbolic view names - * to URLs without explicit mapping definition. This is useful if symbolic names + * A {@link ViewResolver} that allows direct resolution of symbolic view names + * to URLs without explicit mapping definitions. This is useful if symbolic names * match the names of view resources in a straightforward manner (i.e. the * symbolic name is the unique part of the resource's filename), without the need * for a dedicated mapping to be defined for each view. @@ -59,6 +59,7 @@ import org.springframework.util.PatternMatchUtils; * @author Rossen Stoyanchev * @author Sebastien Deleuze * @author Juergen Hoeller + * @author Sam Brannen * @since 5.0 */ public class UrlBasedViewResolver extends ViewResolverSupport @@ -266,7 +267,7 @@ public class UrlBasedViewResolver extends ViewResolverSupport /** * Creates a new View instance of the specified view class and configures it. - * Does not perform any lookup for pre-defined View instances. + *

Does not perform any lookup for pre-defined View instances. *

Spring lifecycle methods as defined by the bean container do not have to * be called here: They will be automatically applied afterwards, provided * that an {@link #setApplicationContext ApplicationContext} is available. @@ -281,10 +282,14 @@ public class UrlBasedViewResolver extends ViewResolverSupport AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(viewClass); view.setSupportedMediaTypes(getSupportedMediaTypes()); - view.setRequestContextAttribute(getRequestContextAttribute()); view.setDefaultCharset(getDefaultCharset()); view.setUrl(getPrefix() + viewName + getSuffix()); + String requestContextAttribute = getRequestContextAttribute(); + if (requestContextAttribute != null) { + view.setRequestContextAttribute(requestContextAttribute); + } + return view; } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/UrlBasedViewResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/UrlBasedViewResolverTests.java index 44e08d78ad..63e4f6c154 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/UrlBasedViewResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/UrlBasedViewResolverTests.java @@ -37,20 +37,60 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Rossen Stoyanchev * @author Sebastien Deleuze + * @author Sam Brannen */ public class UrlBasedViewResolverTests { - private UrlBasedViewResolver resolver; + private final UrlBasedViewResolver resolver = new UrlBasedViewResolver(); @Before public void setup() { StaticApplicationContext context = new StaticApplicationContext(); context.refresh(); - this.resolver = new UrlBasedViewResolver(); this.resolver.setApplicationContext(context); } + @Test + public void urlBasedViewResolverOverridesCustomRequestContextAttributeWithNonNullValue() throws Exception { + assertThat(new TestView().getRequestContextAttribute()) + .as("requestContextAttribute when instantiated directly") + .isEqualTo("testRequestContext"); + + this.resolver.setViewClass(TestView.class); + this.resolver.setRequestContextAttribute("viewResolverRequestContext"); + + Mono mono = this.resolver.resolveViewName("example", Locale.getDefault()); + StepVerifier.create(mono) + .consumeNextWith(view -> { + assertThat(view).isInstanceOf(TestView.class); + assertThat(((TestView) view).getRequestContextAttribute()) + .as("requestContextAttribute when instantiated dynamically by UrlBasedViewResolver") + .isEqualTo("viewResolverRequestContext"); + }) + .expectComplete() + .verify(Duration.ZERO); + } + + @Test + public void urlBasedViewResolverDoesNotOverrideCustomRequestContextAttributeWithNull() throws Exception { + assertThat(new TestView().getRequestContextAttribute()) + .as("requestContextAttribute when instantiated directly") + .isEqualTo("testRequestContext"); + + this.resolver.setViewClass(TestView.class); + + Mono mono = this.resolver.resolveViewName("example", Locale.getDefault()); + StepVerifier.create(mono) + .consumeNextWith(view -> { + assertThat(view).isInstanceOf(TestView.class); + assertThat(((TestView) view).getRequestContextAttribute()) + .as("requestContextAttribute when instantiated dynamically by UrlBasedViewResolver") + .isEqualTo("testRequestContext"); + }) + .expectComplete() + .verify(Duration.ZERO); + } @Test public void viewNames() throws Exception { @@ -98,6 +138,10 @@ public class UrlBasedViewResolverTests { private static class TestView extends AbstractUrlBasedView { + public TestView() { + setRequestContextAttribute("testRequestContext"); + } + @Override public boolean checkResourceExists(Locale locale) throws Exception { return true; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java index 73735dec0e..bbdf7c9557 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/UrlBasedViewResolver.java @@ -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. @@ -34,7 +34,7 @@ import org.springframework.web.servlet.View; /** * Simple implementation of the {@link org.springframework.web.servlet.ViewResolver} * interface, allowing for direct resolution of symbolic view names to URLs, - * without explicit mapping definition. This is useful if your symbolic names + * without explicit mapping definitions. This is useful if your symbolic names * match the names of your view resources in a straightforward manner * (i.e. the symbolic name is the unique part of the resource's filename), * without the need for a dedicated mapping to be defined for each view. @@ -65,14 +65,15 @@ import org.springframework.web.servlet.View; * a symbolic view name to different resources depending on the current locale. * *

Note: When chaining ViewResolvers, a UrlBasedViewResolver will check whether - * the {@link AbstractUrlBasedView#checkResource specified resource actually exists}. + * the {@linkplain AbstractUrlBasedView#checkResource specified resource actually exists}. * However, with {@link InternalResourceView}, it is not generally possible to * determine the existence of the target resource upfront. In such a scenario, - * a UrlBasedViewResolver will always return View for any given view name; + * a UrlBasedViewResolver will always return a View for any given view name; * as a consequence, it should be configured as the last ViewResolver in the chain. * * @author Juergen Hoeller * @author Rob Harrop + * @author Sam Brannen * @since 13.12.2003 * @see #setViewClass * @see #setPrefix @@ -550,14 +551,17 @@ public class UrlBasedViewResolver extends AbstractCachingViewResolver implements AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(viewClass); view.setUrl(getPrefix() + viewName + getSuffix()); + view.setAttributesMap(getAttributesMap()); String contentType = getContentType(); if (contentType != null) { view.setContentType(contentType); } - view.setRequestContextAttribute(getRequestContextAttribute()); - view.setAttributesMap(getAttributesMap()); + String requestContextAttribute = getRequestContextAttribute(); + if (requestContextAttribute != null) { + view.setRequestContextAttribute(requestContextAttribute); + } Boolean exposePathVariables = getExposePathVariables(); if (exposePathVariables != null) { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java index 4ff71ee88b..018fd92612 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ViewResolverTests.java @@ -22,8 +22,6 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -31,6 +29,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.jstl.core.Config; import javax.servlet.jsp.jstl.fmt.LocalizationContext; +import org.junit.Before; import org.junit.Test; import org.springframework.beans.MutablePropertyValues; @@ -56,94 +55,140 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** + * Unit tests for {@link BeanNameViewResolver}, {@link UrlBasedViewResolver}, + * {@link InternalResourceViewResolver}, {@link XmlViewResolver}, and + * {@link AbstractCachingViewResolver}. + * * @author Juergen Hoeller * @author Chris Beams + * @author Sam Brannen * @since 18.06.2003 */ public class ViewResolverTests { + private final StaticWebApplicationContext wac = new StaticWebApplicationContext(); + private final MockServletContext sc = new MockServletContext(); + private final MockHttpServletRequest request = new MockHttpServletRequest(this.sc); + private final HttpServletResponse response = new MockHttpServletResponse(); + + @Before + public void setUp() { + this.wac.setServletContext(this.sc); + } + @Test - public void testBeanNameViewResolver() throws ServletException { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); + public void beanNameViewResolver() { MutablePropertyValues pvs1 = new MutablePropertyValues(); pvs1.addPropertyValue(new PropertyValue("url", "/example1.jsp")); - wac.registerSingleton("example1", InternalResourceView.class, pvs1); + this.wac.registerSingleton("example1", InternalResourceView.class, pvs1); MutablePropertyValues pvs2 = new MutablePropertyValues(); pvs2.addPropertyValue(new PropertyValue("url", "/example2.jsp")); - wac.registerSingleton("example2", JstlView.class, pvs2); + this.wac.registerSingleton("example2", JstlView.class, pvs2); BeanNameViewResolver vr = new BeanNameViewResolver(); - vr.setApplicationContext(wac); - wac.refresh(); + vr.setApplicationContext(this.wac); + this.wac.refresh(); View view = vr.resolveViewName("example1", Locale.getDefault()); assertThat(view.getClass()).as("Correct view class").isEqualTo(InternalResourceView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("/example1.jsp"); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((JstlView) view).getUrl()).as("Correct URL").isEqualTo("/example2.jsp"); } @Test - public void testUrlBasedViewResolverWithoutPrefixes() throws Exception { + public void urlBasedViewResolverOverridesCustomRequestContextAttributeWithNonNullValue() throws Exception { + assertThat(new TestView().getRequestContextAttribute()) + .as("requestContextAttribute when instantiated directly") + .isEqualTo("testRequestContext"); + + UrlBasedViewResolver vr = new UrlBasedViewResolver(); + vr.setViewClass(TestView.class); + vr.setApplicationContext(this.wac); + vr.setRequestContextAttribute("viewResolverRequestContext"); + this.wac.refresh(); + + View view = vr.resolveViewName("example", Locale.getDefault()); + assertThat(view).isInstanceOf(TestView.class); + assertThat(((TestView) view).getRequestContextAttribute()) + .as("requestContextAttribute when instantiated dynamically by UrlBasedViewResolver") + .isEqualTo("viewResolverRequestContext"); + } + + @Test + public void urlBasedViewResolverDoesNotOverrideCustomRequestContextAttributeWithNull() throws Exception { + assertThat(new TestView().getRequestContextAttribute()) + .as("requestContextAttribute when instantiated directly") + .isEqualTo("testRequestContext"); + + UrlBasedViewResolver vr = new UrlBasedViewResolver(); + vr.setViewClass(TestView.class); + vr.setApplicationContext(this.wac); + this.wac.refresh(); + + View view = vr.resolveViewName("example", Locale.getDefault()); + assertThat(view).isInstanceOf(TestView.class); + assertThat(((TestView) view).getRequestContextAttribute()) + .as("requestContextAttribute when instantiated dynamically by UrlBasedViewResolver") + .isEqualTo("testRequestContext"); + } + + @Test + public void urlBasedViewResolverWithoutPrefixes() throws Exception { UrlBasedViewResolver vr = new UrlBasedViewResolver(); vr.setViewClass(JstlView.class); doTestUrlBasedViewResolverWithoutPrefixes(vr); } @Test - public void testUrlBasedViewResolverWithPrefixes() throws Exception { + public void urlBasedViewResolverWithPrefixes() throws Exception { UrlBasedViewResolver vr = new UrlBasedViewResolver(); vr.setViewClass(JstlView.class); doTestUrlBasedViewResolverWithPrefixes(vr); } @Test - public void testInternalResourceViewResolverWithoutPrefixes() throws Exception { + public void internalResourceViewResolverWithoutPrefixes() throws Exception { doTestUrlBasedViewResolverWithoutPrefixes(new InternalResourceViewResolver()); } @Test - public void testInternalResourceViewResolverWithPrefixes() throws Exception { + public void internalResourceViewResolverWithPrefixes() throws Exception { doTestUrlBasedViewResolverWithPrefixes(new InternalResourceViewResolver()); } private void doTestUrlBasedViewResolverWithoutPrefixes(UrlBasedViewResolver vr) throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.refresh(); - vr.setApplicationContext(wac); + this.wac.refresh(); + vr.setApplicationContext(this.wac); vr.setContentType("myContentType"); vr.setRequestContextAttribute("rc"); View view = vr.resolveViewName("example1", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("example1"); assertThat(((InternalResourceView) view).getContentType()).as("Correct textContentType").isEqualTo("myContentType"); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("example2"); assertThat(((InternalResourceView) view).getContentType()).as("Correct textContentType").isEqualTo("myContentType"); - HttpServletRequest request = new MockHttpServletRequest(wac.getServletContext()); - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); - request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); + this.request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); Map model = new HashMap<>(); TestBean tb = new TestBean(); model.put("tb", tb); - view.render(model, request, response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - boolean condition = request.getAttribute("rc") instanceof RequestContext; + view.render(model, this.request, this.response); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + boolean condition = this.request.getAttribute("rc") instanceof RequestContext; assertThat(condition).as("Correct rc attribute").isTrue(); view = vr.resolveViewName("redirect:myUrl", Locale.getDefault()); assertThat(view.getClass()).as("Correct view class").isEqualTo(RedirectView.class); assertThat(((RedirectView) view).getUrl()).as("Correct URL").isEqualTo("myUrl"); - assertThat(((RedirectView) view).getApplicationContext()).as("View not initialized as bean").isSameAs(wac); + assertThat(((RedirectView) view).getApplicationContext()).as("View not initialized as bean").isSameAs(this.wac); view = vr.resolveViewName("forward:myUrl", Locale.getDefault()); assertThat(view.getClass()).as("Correct view class").isEqualTo(InternalResourceView.class); @@ -151,19 +196,17 @@ public class ViewResolverTests { } private void doTestUrlBasedViewResolverWithPrefixes(UrlBasedViewResolver vr) throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.refresh(); + this.wac.refresh(); vr.setPrefix("/WEB-INF/"); vr.setSuffix(".jsp"); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view = vr.resolveViewName("example1", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("/WEB-INF/example1.jsp"); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("/WEB-INF/example2.jsp"); view = vr.resolveViewName("redirect:myUrl", Locale.getDefault()); @@ -176,11 +219,8 @@ public class ViewResolverTests { } @Test - public void testInternalResourceViewResolverWithAttributes() throws Exception { - MockServletContext sc = new MockServletContext(); - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.refresh(); + public void internalResourceViewResolverWithAttributes() throws Exception { + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); Properties props = new Properties(); props.setProperty("key1", "value1"); @@ -188,45 +228,40 @@ public class ViewResolverTests { Map map = new HashMap<>(); map.put("key2", new Integer(2)); vr.setAttributesMap(map); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view = vr.resolveViewName("example1", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("example1"); Map attributes = ((InternalResourceView) view).getStaticAttributes(); assertThat(attributes.get("key1")).isEqualTo("value1"); assertThat(attributes.get("key2")).isEqualTo(new Integer(2)); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((InternalResourceView) view).getUrl()).as("Correct URL").isEqualTo("example2"); attributes = ((InternalResourceView) view).getStaticAttributes(); assertThat(attributes.get("key1")).isEqualTo("value1"); assertThat(attributes.get("key2")).isEqualTo(new Integer(2)); - MockHttpServletRequest request = new MockHttpServletRequest(sc); - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); Map model = new HashMap<>(); TestBean tb = new TestBean(); model.put("tb", tb); - view.render(model, request, response); + view.render(model, this.request, this.response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - assertThat(request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); - assertThat(request.getAttribute("key1")).isEqualTo("value1"); - assertThat(request.getAttribute("key2")).isEqualTo(new Integer(2)); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + assertThat(this.request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); + assertThat(this.request.getAttribute("key1")).isEqualTo("value1"); + assertThat(this.request.getAttribute("key2")).isEqualTo(new Integer(2)); } @Test - public void testInternalResourceViewResolverWithContextBeans() throws Exception { - MockServletContext sc = new MockServletContext(); - final StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.registerSingleton("myBean", TestBean.class); - wac.registerSingleton("myBean2", TestBean.class); - wac.setServletContext(sc); - wac.refresh(); + public void internalResourceViewResolverWithContextBeans() throws Exception { + this.wac.registerSingleton("myBean", TestBean.class); + this.wac.registerSingleton("myBean2", TestBean.class); + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); Properties props = new Properties(); props.setProperty("key1", "value1"); @@ -235,9 +270,9 @@ public class ViewResolverTests { map.put("key2", new Integer(2)); vr.setAttributesMap(map); vr.setExposeContextBeansAsAttributes(true); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); - MockHttpServletRequest request = new MockHttpServletRequest(sc) { + HttpServletRequest request = new MockHttpServletRequest(this.sc) { @Override public RequestDispatcher getRequestDispatcher(String path) { return new MockRequestDispatcher(path) { @@ -252,21 +287,17 @@ public class ViewResolverTests { }; } }; - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); + request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); View view = vr.resolveViewName("example1", Locale.getDefault()); - view.render(new HashMap(), request, response); + view.render(new HashMap(), request, this.response); } @Test - public void testInternalResourceViewResolverWithSpecificContextBeans() throws Exception { - MockServletContext sc = new MockServletContext(); - final StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.registerSingleton("myBean", TestBean.class); - wac.registerSingleton("myBean2", TestBean.class); - wac.setServletContext(sc); - wac.refresh(); + public void internalResourceViewResolverWithSpecificContextBeans() throws Exception { + this.wac.registerSingleton("myBean", TestBean.class); + this.wac.registerSingleton("myBean2", TestBean.class); + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); Properties props = new Properties(); props.setProperty("key1", "value1"); @@ -275,9 +306,9 @@ public class ViewResolverTests { map.put("key2", new Integer(2)); vr.setAttributesMap(map); vr.setExposedContextBeanNames(new String[] {"myBean2"}); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); - MockHttpServletRequest request = new MockHttpServletRequest(sc) { + HttpServletRequest request = new MockHttpServletRequest(this.sc) { @Override public RequestDispatcher getRequestDispatcher(String path) { return new MockRequestDispatcher(path) { @@ -292,101 +323,88 @@ public class ViewResolverTests { }; } }; - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); + request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); View view = vr.resolveViewName("example1", Locale.getDefault()); - view.render(new HashMap(), request, response); + view.render(new HashMap(), request, this.response); } @Test - public void testInternalResourceViewResolverWithJstl() throws Exception { + public void internalResourceViewResolverWithJstl() throws Exception { Locale locale = !Locale.GERMAN.equals(Locale.getDefault()) ? Locale.GERMAN : Locale.FRENCH; - MockServletContext sc = new MockServletContext(); - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.addMessage("code1", locale, "messageX"); - wac.refresh(); + this.wac.addMessage("code1", locale, "messageX"); + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); vr.setViewClass(JstlView.class); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view = vr.resolveViewName("example1", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((JstlView) view).getUrl()).as("Correct URL").isEqualTo("example1"); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((JstlView) view).getUrl()).as("Correct URL").isEqualTo("example2"); - MockHttpServletRequest request = new MockHttpServletRequest(sc); - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale)); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale)); Map model = new HashMap<>(); TestBean tb = new TestBean(); model.put("tb", tb); - view.render(model, request, response); + view.render(model, this.request, this.response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - assertThat(request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + assertThat(this.request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); - assertThat(Config.get(request, Config.FMT_LOCALE)).isEqualTo(locale); - LocalizationContext lc = (LocalizationContext) Config.get(request, Config.FMT_LOCALIZATION_CONTEXT); + assertThat(Config.get(this.request, Config.FMT_LOCALE)).isEqualTo(locale); + LocalizationContext lc = (LocalizationContext) Config.get(this.request, Config.FMT_LOCALIZATION_CONTEXT); assertThat(lc.getResourceBundle().getString("code1")).isEqualTo("messageX"); } @Test - public void testInternalResourceViewResolverWithJstlAndContextParam() throws Exception { + public void internalResourceViewResolverWithJstlAndContextParam() throws Exception { Locale locale = !Locale.GERMAN.equals(Locale.getDefault()) ? Locale.GERMAN : Locale.FRENCH; - MockServletContext sc = new MockServletContext(); - sc.addInitParameter(Config.FMT_LOCALIZATION_CONTEXT, "org/springframework/web/context/WEB-INF/context-messages"); - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(sc); - wac.addMessage("code1", locale, "messageX"); - wac.refresh(); + this.sc.addInitParameter(Config.FMT_LOCALIZATION_CONTEXT, "org/springframework/web/context/WEB-INF/context-messages"); + this.wac.addMessage("code1", locale, "messageX"); + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); vr.setViewClass(JstlView.class); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view = vr.resolveViewName("example1", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((JstlView) view).getUrl()).as("Correct URL").isEqualTo("example1"); view = vr.resolveViewName("example2", Locale.getDefault()); - assertThat(view.getClass()).as("Correct view class").isEqualTo(JstlView.class); + assertThat(view).isInstanceOf(JstlView.class); assertThat(((JstlView) view).getUrl()).as("Correct URL").isEqualTo("example2"); - MockHttpServletRequest request = new MockHttpServletRequest(sc); - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale)); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale)); Map model = new HashMap<>(); TestBean tb = new TestBean(); model.put("tb", tb); - view.render(model, request, response); + view.render(model, this.request, this.response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - assertThat(request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + assertThat(this.request.getAttribute("rc") == null).as("Correct rc attribute").isTrue(); - assertThat(Config.get(request, Config.FMT_LOCALE)).isEqualTo(locale); - LocalizationContext lc = (LocalizationContext) Config.get(request, Config.FMT_LOCALIZATION_CONTEXT); + assertThat(Config.get(this.request, Config.FMT_LOCALE)).isEqualTo(locale); + LocalizationContext lc = (LocalizationContext) Config.get(this.request, Config.FMT_LOCALIZATION_CONTEXT); assertThat(lc.getResourceBundle().getString("code1")).isEqualTo("message1"); assertThat(lc.getResourceBundle().getString("code2")).isEqualTo("message2"); } @Test - public void testXmlViewResolver() throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.registerSingleton("testBean", TestBean.class); - wac.setServletContext(new MockServletContext()); - wac.refresh(); - TestBean testBean = (TestBean) wac.getBean("testBean"); + public void xmlViewResolver() throws Exception { + this.wac.registerSingleton("testBean", TestBean.class); + this.wac.refresh(); + TestBean testBean = (TestBean) this.wac.getBean("testBean"); XmlViewResolver vr = new XmlViewResolver(); vr.setLocation(new ClassPathResource("org/springframework/web/servlet/view/views.xml")); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view1 = vr.resolveViewName("example1", Locale.getDefault()); assertThat(TestView.class.equals(view1.getClass())).as("Correct view class").isTrue(); @@ -396,34 +414,30 @@ public class ViewResolverTests { assertThat(JstlView.class.equals(view2.getClass())).as("Correct view class").isTrue(); assertThat("/example2new.jsp".equals(((InternalResourceView) view2).getUrl())).as("Correct URL").isTrue(); - ServletContext sc = new MockServletContext(); Map model = new HashMap<>(); TestBean tb = new TestBean(); model.put("tb", tb); - HttpServletRequest request = new MockHttpServletRequest(sc); - HttpServletResponse response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); - request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); - view1.render(model, request, response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - assertThat("testvalue1".equals(request.getAttribute("test1"))).as("Correct test1 attribute").isTrue(); - assertThat(testBean.equals(request.getAttribute("test2"))).as("Correct test2 attribute").isTrue(); - - request = new MockHttpServletRequest(sc); - response = new MockHttpServletResponse(); - request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); - request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); - view2.render(model, request, response); - assertThat(tb.equals(request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); - assertThat("testvalue1".equals(request.getAttribute("test1"))).as("Correct test1 attribute").isTrue(); - assertThat("testvalue2".equals(request.getAttribute("test2"))).as("Correct test2 attribute").isTrue(); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); + this.request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); + view1.render(model, this.request, this.response); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + assertThat("testvalue1".equals(this.request.getAttribute("test1"))).as("Correct test1 attribute").isTrue(); + assertThat(testBean.equals(this.request.getAttribute("test2"))).as("Correct test2 attribute").isTrue(); + + this.request.clearAttributes(); + this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); + this.request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver()); + this.request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver()); + view2.render(model, this.request, this.response); + assertThat(tb.equals(this.request.getAttribute("tb"))).as("Correct tb attribute").isTrue(); + assertThat("testvalue1".equals(this.request.getAttribute("test1"))).as("Correct test1 attribute").isTrue(); + assertThat("testvalue2".equals(this.request.getAttribute("test2"))).as("Correct test2 attribute").isTrue(); } @Test - public void testXmlViewResolverDefaultLocation() { + public void xmlViewResolverDefaultLocation() { StaticWebApplicationContext wac = new StaticWebApplicationContext() { @Override protected Resource getResourceByPath(String path) { @@ -431,16 +445,15 @@ public class ViewResolverTests { return super.getResourceByPath(path); } }; - wac.setServletContext(new MockServletContext()); + wac.setServletContext(this.sc); wac.refresh(); XmlViewResolver vr = new XmlViewResolver(); vr.setApplicationContext(wac); - assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy( - vr::afterPropertiesSet); + assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(vr::afterPropertiesSet); } @Test - public void testXmlViewResolverWithoutCache() throws Exception { + public void xmlViewResolverWithoutCache() throws Exception { StaticWebApplicationContext wac = new StaticWebApplicationContext() { @Override protected Resource getResourceByPath(String path) { @@ -448,7 +461,7 @@ public class ViewResolverTests { return super.getResourceByPath(path); } }; - wac.setServletContext(new MockServletContext()); + wac.setServletContext(this.sc); wac.refresh(); XmlViewResolver vr = new XmlViewResolver(); vr.setCache(false); @@ -458,13 +471,11 @@ public class ViewResolverTests { } @Test - public void testCacheRemoval() throws Exception { - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - wac.setServletContext(new MockServletContext()); - wac.refresh(); + public void cacheRemoval() throws Exception { + this.wac.refresh(); InternalResourceViewResolver vr = new InternalResourceViewResolver(); vr.setViewClass(JstlView.class); - vr.setApplicationContext(wac); + vr.setApplicationContext(this.wac); View view = vr.resolveViewName("example1", Locale.getDefault()); View cached = vr.resolveViewName("example1", Locale.getDefault()); @@ -477,11 +488,11 @@ public class ViewResolverTests { } @Test - public void testCacheUnresolved() throws Exception { + public void cacheUnresolved() throws Exception { final AtomicInteger count = new AtomicInteger(); AbstractCachingViewResolver viewResolver = new AbstractCachingViewResolver() { @Override - protected View loadView(String viewName, Locale locale) throws Exception { + protected View loadView(String viewName, Locale locale) { count.incrementAndGet(); return null; } @@ -508,9 +519,13 @@ public class ViewResolverTests { public static class TestView extends InternalResourceView { + public TestView() { + setRequestContextAttribute("testRequestContext"); + } + public void setLocation(Resource location) { if (!(location instanceof ServletContextResource)) { - throw new IllegalArgumentException("Expecting ClassPathResource, not " + location.getClass().getName()); + throw new IllegalArgumentException("Expecting ServletContextResource, not " + location.getClass().getName()); } } } -- GitLab