Introduce Freemarker/Velocity/TilesWebMvcConfigurer
This change improves the support for auto-registration of FreeMarker, Velocity, and Tiles configuration. The configuration is now conditional not only based on the classpath but also based on whether a FreeMarkerConfigurer for example is already present in the configuration. This change also introduces FreeMarker~, Velocity~, and TilesWebMvcConfigurer interfaces for customizing each view technology. The WebMvcConfigurer can still be used to configure all view resolvers centrally (including FreeMarker, Velocity, and Tiles) without some default conifguration, i.e. without the need to use the new ~WebMvcConfigurer interfaces until customizations are required. Issue: SPR-7093
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.servlet.config.annotation;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.test.MockServletConfig;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Integration tests for view resolution with {@code @EnableWebMvc}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.1
|
||||
*/
|
||||
public class ViewResolutionIntegrationTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void minimalFreemarkerConfig() throws Exception {
|
||||
MockHttpServletResponse response = runTest(MinimalFreeMarkerWebConfig.class);
|
||||
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalVelocityConfig() throws Exception {
|
||||
MockHttpServletResponse response = runTest(MinimalVelocityWebConfig.class);
|
||||
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalTilesConfig() throws Exception {
|
||||
MockHttpServletResponse response = runTest(MinimalTilesWebConfig.class);
|
||||
assertEquals("/WEB-INF/index.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void freemarker() throws Exception {
|
||||
MockHttpServletResponse response = runTest(FreeMarkerWebConfig.class);
|
||||
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void velocity() throws Exception {
|
||||
MockHttpServletResponse response = runTest(VelocityWebConfig.class);
|
||||
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tiles() throws Exception {
|
||||
MockHttpServletResponse response = runTest(TilesWebConfig.class);
|
||||
assertEquals("/WEB-INF/index.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void freemarkerInvalidConfig() throws Exception {
|
||||
this.thrown.expectMessage("It looks like you're trying to configure FreeMarker view resolution.");
|
||||
runTest(InvalidFreeMarkerWebConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void velocityInvalidConfig() throws Exception {
|
||||
this.thrown.expectMessage("It looks like you're trying to configure Velocity view resolution.");
|
||||
runTest(InvalidVelocityWebConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tilesInvalidConfig() throws Exception {
|
||||
this.thrown.expectMessage("It looks like you're trying to configure Tiles view resolution.");
|
||||
runTest(InvalidTilesWebConfig.class);
|
||||
}
|
||||
|
||||
|
||||
private MockHttpServletResponse runTest(Class<?> configClass) throws ServletException, IOException {
|
||||
String basePath = "org/springframework/web/servlet/config/annotation";
|
||||
MockServletContext servletContext = new MockServletContext(basePath);
|
||||
MockServletConfig servletConfig = new MockServletConfig(servletContext);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
context.register(configClass);
|
||||
context.setServletContext(servletContext);
|
||||
context.refresh();
|
||||
DispatcherServlet servlet = new DispatcherServlet(context);
|
||||
servlet.init(servletConfig);
|
||||
servlet.service(request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
static class SampleController {
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
public String tiles(@ModelAttribute("model") ModelMap model) {
|
||||
model.addAttribute("hello", "Hello World!");
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
|
||||
@EnableWebMvc
|
||||
static abstract class AbstractWebConfig extends WebMvcConfigurerAdapter {
|
||||
@Bean
|
||||
public SampleController sampleController() {
|
||||
return new SampleController();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MinimalFreeMarkerWebConfig extends AbstractWebConfig {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.freemarker();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MinimalVelocityWebConfig extends AbstractWebConfig {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.velocity();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MinimalTilesWebConfig extends AbstractWebConfig {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.tiles();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class FreeMarkerWebConfig extends AbstractWebConfig implements FreeMarkerWebMvcConfigurer {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.freemarker();
|
||||
}
|
||||
@Override
|
||||
public void configureFreeMarker(FreeMarkerConfigurer configurer) {
|
||||
configurer.setTemplateLoaderPath("/WEB-INF/");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class VelocityWebConfig extends AbstractWebConfig implements VelocityWebMvcConfigurer {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.velocity();
|
||||
}
|
||||
@Override
|
||||
public void configureVelocity(VelocityConfigurer configurer) {
|
||||
configurer.setResourceLoaderPath("/WEB-INF/");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TilesWebConfig extends AbstractWebConfig implements TilesWebMvcConfigurer {
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.tiles();
|
||||
}
|
||||
@Override
|
||||
public void configureTiles(TilesConfigurer configurer) {
|
||||
configurer.setDefinitions("/WEB-INF/tiles.xml");
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
static class InvalidFreeMarkerWebConfig extends WebMvcConfigurationSupport {
|
||||
|
||||
// No @EnableWebMvc and no FreeMarkerConfigurer bean
|
||||
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.freemarker();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class InvalidVelocityWebConfig extends WebMvcConfigurationSupport {
|
||||
|
||||
// No @EnableWebMvc and no VelocityConfigurer bean
|
||||
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.velocity();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class InvalidTilesWebConfig extends WebMvcConfigurationSupport {
|
||||
|
||||
// No @EnableWebMvc and no TilesConfigurer bean
|
||||
|
||||
@Override
|
||||
public void configureViewResolution(ViewResolutionRegistry registry) {
|
||||
registry.tiles();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,15 +19,13 @@ package org.springframework.web.servlet.config.annotation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.view.BeanNameViewResolver;
|
||||
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
|
||||
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
|
||||
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -44,7 +42,7 @@ public class ViewResolutionRegistryTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
registry = new ViewResolutionRegistry();
|
||||
registry = new ViewResolutionRegistry(new StaticWebApplicationContext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,25 +98,15 @@ public class ViewResolutionRegistryTests {
|
||||
|
||||
@Test
|
||||
public void tilesViewResolution() {
|
||||
registry.tiles().checkRefresh(true).definition("def1").definition("def2");
|
||||
assertNotNull(registry.getViewResolvers());
|
||||
assertEquals(1, registry.getViewResolvers().size());
|
||||
assertEquals(TilesViewResolver.class, registry.getViewResolvers().get(0).getClass());
|
||||
|
||||
assertNotNull(registry.getTilesConfigurer());
|
||||
TilesConfigurer configurer = registry.getTilesConfigurer();
|
||||
DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer);
|
||||
assertTrue((boolean) configurerDirectFieldAccessor.getPropertyValue("checkRefresh"));
|
||||
assertNotNull(configurerDirectFieldAccessor.getPropertyValue("definitions"));
|
||||
String[] definitions = (String[])configurerDirectFieldAccessor.getPropertyValue("definitions");
|
||||
assertEquals(2, definitions.length);
|
||||
assertEquals("def1", definitions[0]);
|
||||
assertEquals("def2", definitions[1]);
|
||||
this.registry.tiles();
|
||||
assertNotNull(this.registry.getViewResolvers());
|
||||
assertEquals(1, this.registry.getViewResolvers().size());
|
||||
assertEquals(TilesViewResolver.class, this.registry.getViewResolvers().get(0).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void velocityViewResolution() {
|
||||
registry.velocity().prefix("/").suffix(".vm").cache(true).resourceLoaderPath("testResourceLoaderPath");
|
||||
registry.velocity().prefix("/").suffix(".vm").cache(true);
|
||||
assertNotNull(registry.getViewResolvers());
|
||||
assertEquals(1, registry.getViewResolvers().size());
|
||||
assertEquals(VelocityViewResolver.class, registry.getViewResolvers().get(0).getClass());
|
||||
@@ -127,11 +115,6 @@ public class ViewResolutionRegistryTests {
|
||||
assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix"));
|
||||
assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix"));
|
||||
assertEquals(1024, resolverDirectFieldAccessor.getPropertyValue("cacheLimit"));
|
||||
|
||||
assertNotNull(registry.getVelocityConfigurer());
|
||||
VelocityConfigurer configurer = registry.getVelocityConfigurer();
|
||||
DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer);
|
||||
assertEquals("testResourceLoaderPath", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,16 +127,11 @@ public class ViewResolutionRegistryTests {
|
||||
DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver);
|
||||
assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix"));
|
||||
assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix"));
|
||||
|
||||
assertNotNull(registry.getVelocityConfigurer());
|
||||
VelocityConfigurer configurer = registry.getVelocityConfigurer();
|
||||
DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer);
|
||||
assertEquals("/WEB-INF/", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void freeMarkerViewResolution() {
|
||||
registry.freemarker().prefix("/").suffix(".fmt").cache(false).templateLoaderPath("path1", "path2");
|
||||
registry.freemarker().prefix("/").suffix(".fmt").cache(false);
|
||||
assertNotNull(registry.getViewResolvers());
|
||||
assertEquals(1, registry.getViewResolvers().size());
|
||||
assertEquals(FreeMarkerViewResolver.class, registry.getViewResolvers().get(0).getClass());
|
||||
@@ -162,15 +140,6 @@ public class ViewResolutionRegistryTests {
|
||||
assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix"));
|
||||
assertEquals(".fmt", resolverDirectFieldAccessor.getPropertyValue("suffix"));
|
||||
assertEquals(0, resolverDirectFieldAccessor.getPropertyValue("cacheLimit"));
|
||||
|
||||
assertNotNull(registry.getFreeMarkerConfigurer());
|
||||
FreeMarkerConfigurer configurer = registry.getFreeMarkerConfigurer();
|
||||
DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer);
|
||||
assertNotNull(configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths"));
|
||||
String[] templateLoaderPaths = (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths");
|
||||
assertEquals(2, templateLoaderPaths.length);
|
||||
assertEquals("path1", templateLoaderPaths[0]);
|
||||
assertEquals("path2", templateLoaderPaths[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,8 +152,6 @@ public class ViewResolutionRegistryTests {
|
||||
DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver);
|
||||
assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix"));
|
||||
assertEquals(".ftl", resolverDirectFieldAccessor.getPropertyValue("suffix"));
|
||||
DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(registry.getFreeMarkerConfigurer());
|
||||
assertArrayEquals(new String[]{"/WEB-INF/"}, (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user