diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/view/UrlBasedViewResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/view/UrlBasedViewResolver.java index 5449493789..e6db4c6f37 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/view/UrlBasedViewResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/view/UrlBasedViewResolver.java @@ -21,6 +21,7 @@ import reactor.core.publisher.Mono; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.PatternMatchUtils; import org.springframework.web.reactive.View; @@ -61,6 +62,8 @@ public class UrlBasedViewResolver extends ViewResolverSupport implements Initial private String suffix = ""; + private String[] viewNames; + /** * Set the view class to instantiate through {@link #createUrlBasedView(String)}. @@ -120,6 +123,25 @@ public class UrlBasedViewResolver extends ViewResolverSupport implements Initial return this.suffix; } + /** + * Set the view names (or name patterns) that can be handled by this + * {@link org.springframework.web.reactive.ViewResolver}. View names can + * contain simple wildcards such that 'my*', '*Report' and '*Repo*' will + * all match the view name 'myReport'. + * @see #canHandle + */ + public void setViewNames(String... viewNames) { + this.viewNames = viewNames; + } + + /** + * Return the view names (or name patterns) that can be handled by this + * {@link org.springframework.web.reactive.ViewResolver}. + */ + protected String[] getViewNames() { + return this.viewNames; + } + @Override public void afterPropertiesSet() throws Exception { @@ -131,6 +153,9 @@ public class UrlBasedViewResolver extends ViewResolverSupport implements Initial @Override public Mono resolveViewName(String viewName, Locale locale) { + if (!canHandle(viewName, locale)) { + return Mono.empty(); + } AbstractUrlBasedView urlBasedView = createUrlBasedView(viewName); View view = applyLifecycleMethods(viewName, urlBasedView); try { @@ -141,6 +166,22 @@ public class UrlBasedViewResolver extends ViewResolverSupport implements Initial } } + /** + * Indicates whether or not this + * {@link org.springframework.web.reactive.ViewResolver} can handle the + * supplied view name. If not, an empty result is returned. The default + * implementation checks against the configured {@link #setViewNames + * view names}. + * @param viewName the name of the view to retrieve + * @param locale the Locale to retrieve the view for + * @return whether this resolver applies to the specified view + * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String) + */ + protected boolean canHandle(String viewName, Locale locale) { + String[] viewNames = getViewNames(); + return (viewNames == null || PatternMatchUtils.simpleMatch(viewNames, viewName)); + } + /** * Creates a new View instance of the specified view class and configures it. * Does not perform any lookup for pre-defined View instances. diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/view/UrlBasedViewResolverTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/view/UrlBasedViewResolverTests.java new file mode 100644 index 0000000000..1595dde4c2 --- /dev/null +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/view/UrlBasedViewResolverTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.web.reactive.view; + +import java.util.Locale; +import java.util.Map; + +import org.junit.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.web.reactive.View; +import org.springframework.web.server.ServerWebExchange; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * Unit tests for {@link UrlBasedViewResolver}. + * + * @author Rossen Stoyanchev + */ +public class UrlBasedViewResolverTests { + + + @Test + public void viewNames() throws Exception { + StaticApplicationContext context = new StaticApplicationContext(); + context.refresh(); + + UrlBasedViewResolver resolver = new UrlBasedViewResolver(); + resolver.setViewClass(TestView.class); + resolver.setViewNames("my*"); + resolver.setApplicationContext(context); + + Mono mono = resolver.resolveViewName("my-view", Locale.US); + assertNotNull(mono.get()); + + mono = resolver.resolveViewName("not-my-view", Locale.US); + assertNull(mono.get()); + } + + + private static class TestView extends AbstractUrlBasedView { + + @Override + public boolean checkResourceExists(Locale locale) throws Exception { + return true; + } + + @Override + protected Flux renderInternal(Map attributes, ServerWebExchange exchange) { + return Flux.empty(); + } + } + +}