Add support for using Velocity templates
This commit is contained in:
@@ -66,6 +66,11 @@
|
||||
<artifactId>tomcat-jdbc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-templates</artifactId>
|
||||
|
||||
@@ -28,11 +28,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.template.TemplateViewResolverConfigurer;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@@ -45,7 +45,7 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for FreeMarker.
|
||||
*
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dave Syer
|
||||
* @since 1.1.0
|
||||
@@ -65,8 +65,8 @@ public class FreeMarkerAutoConfiguration {
|
||||
@PostConstruct
|
||||
public void checkTemplateLocationExists() {
|
||||
if (this.properties.isCheckTemplateLocation()) {
|
||||
Resource resource = this.resourceLoader
|
||||
.getResource(this.properties.getTemplateLoaderPath());
|
||||
Resource resource = this.resourceLoader.getResource(this.properties
|
||||
.getTemplateLoaderPath());
|
||||
Assert.state(resource.exists(), "Cannot find template location: " + resource
|
||||
+ " (please add some templates "
|
||||
+ "or check your FreeMarker configuration)");
|
||||
@@ -125,26 +125,10 @@ public class FreeMarkerAutoConfiguration {
|
||||
@ConditionalOnMissingBean(name = "freeMarkerViewResolver")
|
||||
public FreeMarkerViewResolver freeMarkerViewResolver() {
|
||||
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
|
||||
resolver.setPrefix(this.properties.getPrefix());
|
||||
resolver.setSuffix(this.properties.getSuffix());
|
||||
resolver.setCache(this.properties.isCache());
|
||||
resolver.setContentType(this.properties.getContentType());
|
||||
resolver.setViewNames(this.properties.getViewNames());
|
||||
resolver.setExposeRequestAttributes(this.properties
|
||||
.isExposeRequestAttributes());
|
||||
resolver.setExposeRequestAttributes(this.properties.isAllowRequestOverride());
|
||||
resolver.setExposeRequestAttributes(this.properties
|
||||
.isExposeSessionAttributes());
|
||||
resolver.setExposeRequestAttributes(this.properties
|
||||
.isExposeSpringMacroHelpers());
|
||||
resolver.setRequestContextAttribute(this.properties
|
||||
.getRequestContextAttribute());
|
||||
|
||||
// This resolver acts as a fallback resolver (e.g. like a
|
||||
// InternalResourceViewResolver) so it needs to have low precedence
|
||||
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
|
||||
|
||||
new TemplateViewResolverConfigurer().configureTemplateViewResolver(resolver,
|
||||
this.properties);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,19 @@ package org.springframework.boot.autoconfigure.freemarker;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties} for configuring FreeMarker
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.freemarker")
|
||||
public class FreeMarkerProperties {
|
||||
public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {
|
||||
|
||||
public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/";
|
||||
|
||||
@@ -35,138 +39,12 @@ public class FreeMarkerProperties {
|
||||
|
||||
public static final String DEFAULT_SUFFIX = ".ftl";
|
||||
|
||||
private String prefix = DEFAULT_PREFIX;
|
||||
|
||||
private String suffix = DEFAULT_SUFFIX;
|
||||
private Map<String, String> settings = new HashMap<String, String>();
|
||||
|
||||
private String templateLoaderPath = DEFAULT_TEMPLATE_LOADER_PATH;
|
||||
|
||||
private boolean cache;
|
||||
|
||||
private String contentType = "text/html";
|
||||
|
||||
private String charSet = "UTF-8";
|
||||
|
||||
private String[] viewNames;
|
||||
|
||||
private boolean checkTemplateLocation = true;
|
||||
|
||||
private String requestContextAttribute;
|
||||
|
||||
private boolean exposeRequestAttributes = false;
|
||||
|
||||
private boolean exposeSessionAttributes = false;
|
||||
|
||||
private boolean allowRequestOverride = false;
|
||||
|
||||
private boolean exposeSpringMacroHelpers = true;
|
||||
|
||||
private Map<String, String> settings = new HashMap<String, String>();
|
||||
|
||||
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
|
||||
this.checkTemplateLocation = checkTemplateLocation;
|
||||
}
|
||||
|
||||
public boolean isCheckTemplateLocation() {
|
||||
return this.checkTemplateLocation;
|
||||
}
|
||||
|
||||
public String[] getViewNames() {
|
||||
return this.viewNames;
|
||||
}
|
||||
|
||||
public void setViewNames(String[] viewNames) {
|
||||
this.viewNames = viewNames;
|
||||
}
|
||||
|
||||
public boolean isCache() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
public void setCache(boolean cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType
|
||||
+ (this.contentType.contains(";charset=") ? "" : ";charset="
|
||||
+ this.charSet);
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getCharSet() {
|
||||
return this.charSet;
|
||||
}
|
||||
|
||||
public void setCharSet(String charSet) {
|
||||
this.charSet = charSet;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getTemplateLoaderPath() {
|
||||
return this.templateLoaderPath;
|
||||
}
|
||||
|
||||
public void setTemplateLoaderPath(String templateLoaderPath) {
|
||||
this.templateLoaderPath = templateLoaderPath;
|
||||
}
|
||||
|
||||
public String getRequestContextAttribute() {
|
||||
return this.requestContextAttribute;
|
||||
}
|
||||
|
||||
public void setRequestContextAttribute(String requestContextAttribute) {
|
||||
this.requestContextAttribute = requestContextAttribute;
|
||||
}
|
||||
|
||||
public boolean isExposeRequestAttributes() {
|
||||
return this.exposeRequestAttributes;
|
||||
}
|
||||
|
||||
public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
|
||||
this.exposeRequestAttributes = exposeRequestAttributes;
|
||||
}
|
||||
|
||||
public boolean isExposeSessionAttributes() {
|
||||
return this.exposeSessionAttributes;
|
||||
}
|
||||
|
||||
public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
|
||||
this.exposeSessionAttributes = exposeSessionAttributes;
|
||||
}
|
||||
|
||||
public boolean isAllowRequestOverride() {
|
||||
return this.allowRequestOverride;
|
||||
}
|
||||
|
||||
public void setAllowRequestOverride(boolean allowRequestOverride) {
|
||||
this.allowRequestOverride = allowRequestOverride;
|
||||
}
|
||||
|
||||
public boolean isExposeSpringMacroHelpers() {
|
||||
return this.exposeSpringMacroHelpers;
|
||||
}
|
||||
|
||||
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
|
||||
this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
|
||||
public FreeMarkerProperties() {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX);
|
||||
}
|
||||
|
||||
public Map<String, String> getSettings() {
|
||||
@@ -177,4 +55,11 @@ public class FreeMarkerProperties {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public String getTemplateLoaderPath() {
|
||||
return this.templateLoaderPath;
|
||||
}
|
||||
|
||||
public void setTemplateLoaderPath(String templateLoaderPath) {
|
||||
this.templateLoaderPath = templateLoaderPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.template;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link ConfigurationProperties} for
|
||||
* {@link AbstractTemplateViewResolver view resolvers}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public abstract class AbstractTemplateViewResolverProperties {
|
||||
|
||||
private String prefix;
|
||||
|
||||
private String suffix;
|
||||
|
||||
private boolean cache;
|
||||
|
||||
private String contentType = "text/html";
|
||||
|
||||
private String charSet = "UTF-8";
|
||||
|
||||
private String[] viewNames;
|
||||
|
||||
private boolean checkTemplateLocation = true;
|
||||
|
||||
private String requestContextAttribute;
|
||||
|
||||
private boolean exposeRequestAttributes = false;
|
||||
|
||||
private boolean exposeSessionAttributes = false;
|
||||
|
||||
private boolean allowRequestOverride = false;
|
||||
|
||||
private boolean exposeSpringMacroHelpers = true;
|
||||
|
||||
protected AbstractTemplateViewResolverProperties(String defaultPrefix,
|
||||
String defaultSuffix) {
|
||||
this.prefix = defaultPrefix;
|
||||
this.suffix = defaultSuffix;
|
||||
}
|
||||
|
||||
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
|
||||
this.checkTemplateLocation = checkTemplateLocation;
|
||||
}
|
||||
|
||||
public boolean isCheckTemplateLocation() {
|
||||
return this.checkTemplateLocation;
|
||||
}
|
||||
|
||||
public String[] getViewNames() {
|
||||
return this.viewNames;
|
||||
}
|
||||
|
||||
public void setViewNames(String[] viewNames) {
|
||||
this.viewNames = viewNames;
|
||||
}
|
||||
|
||||
public boolean isCache() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
public void setCache(boolean cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType
|
||||
+ (this.contentType.contains(";charset=") ? "" : ";charset="
|
||||
+ this.charSet);
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getCharSet() {
|
||||
return this.charSet;
|
||||
}
|
||||
|
||||
public void setCharSet(String charSet) {
|
||||
this.charSet = charSet;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getRequestContextAttribute() {
|
||||
return this.requestContextAttribute;
|
||||
}
|
||||
|
||||
public void setRequestContextAttribute(String requestContextAttribute) {
|
||||
this.requestContextAttribute = requestContextAttribute;
|
||||
}
|
||||
|
||||
public boolean isExposeRequestAttributes() {
|
||||
return this.exposeRequestAttributes;
|
||||
}
|
||||
|
||||
public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
|
||||
this.exposeRequestAttributes = exposeRequestAttributes;
|
||||
}
|
||||
|
||||
public boolean isExposeSessionAttributes() {
|
||||
return this.exposeSessionAttributes;
|
||||
}
|
||||
|
||||
public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
|
||||
this.exposeSessionAttributes = exposeSessionAttributes;
|
||||
}
|
||||
|
||||
public boolean isAllowRequestOverride() {
|
||||
return this.allowRequestOverride;
|
||||
}
|
||||
|
||||
public void setAllowRequestOverride(boolean allowRequestOverride) {
|
||||
this.allowRequestOverride = allowRequestOverride;
|
||||
}
|
||||
|
||||
public boolean isExposeSpringMacroHelpers() {
|
||||
return this.exposeSpringMacroHelpers;
|
||||
}
|
||||
|
||||
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
|
||||
this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.template;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
|
||||
|
||||
/**
|
||||
* Helper class for use by configuration classes that provide an
|
||||
* {@link AbstractTemplateViewResolver} bean.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class TemplateViewResolverConfigurer {
|
||||
|
||||
/**
|
||||
* Configures the {@code resolver} using the given {@code properties} and defaults.
|
||||
*
|
||||
* @param resolver The resolver to configure
|
||||
* @param properties The properties to use to configure the resolver
|
||||
*/
|
||||
public void configureTemplateViewResolver(AbstractTemplateViewResolver resolver,
|
||||
AbstractTemplateViewResolverProperties properties) {
|
||||
|
||||
resolver.setPrefix(properties.getPrefix());
|
||||
resolver.setSuffix(properties.getSuffix());
|
||||
resolver.setCache(properties.isCache());
|
||||
resolver.setContentType(properties.getContentType());
|
||||
resolver.setViewNames(properties.getViewNames());
|
||||
resolver.setExposeRequestAttributes(properties.isExposeRequestAttributes());
|
||||
resolver.setAllowRequestOverride(properties.isAllowRequestOverride());
|
||||
resolver.setExposeSessionAttributes(properties.isExposeSessionAttributes());
|
||||
resolver.setExposeSpringMacroHelpers(properties.isExposeSpringMacroHelpers());
|
||||
resolver.setRequestContextAttribute(properties.getRequestContextAttribute());
|
||||
|
||||
// This resolver acts as a fallback resolver (e.g. like a
|
||||
// InternalResourceViewResolver) so it needs to have low precedence
|
||||
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.velocity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.exception.VelocityException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.template.TemplateViewResolverConfigurer;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.ui.velocity.VelocityEngineFactory;
|
||||
import org.springframework.ui.velocity.VelocityEngineFactoryBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityConfig;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Velocity.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(VelocityEngine.class)
|
||||
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(VelocityProperties.class)
|
||||
public class VelocityAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
@Autowired
|
||||
private VelocityProperties properties;
|
||||
|
||||
@PostConstruct
|
||||
public void checkTemplateLocationExists() {
|
||||
if (this.properties.isCheckTemplateLocation()) {
|
||||
Resource resource = this.resourceLoader.getResource(this.properties
|
||||
.getResourceLoaderPath());
|
||||
Assert.state(resource.exists(), "Cannot find template location: " + resource
|
||||
+ " (please add some templates "
|
||||
+ "or check your Velocity configuration)");
|
||||
}
|
||||
}
|
||||
|
||||
protected static class VelocityConfiguration {
|
||||
|
||||
@Autowired
|
||||
protected VelocityProperties properties;
|
||||
|
||||
protected void applyProperties(VelocityEngineFactory factory) {
|
||||
factory.setResourceLoaderPath(this.properties.getResourceLoaderPath());
|
||||
Properties velocityProperties = new Properties();
|
||||
velocityProperties.putAll(this.properties.getProperties());
|
||||
factory.setVelocityProperties(velocityProperties);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnNotWebApplication
|
||||
public static class VelocityNonWebConfiguration extends VelocityConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public VelocityEngineFactoryBean velocityConfiguration() {
|
||||
VelocityEngineFactoryBean velocityEngineFactoryBean = new VelocityEngineFactoryBean();
|
||||
applyProperties(velocityEngineFactoryBean);
|
||||
return velocityEngineFactoryBean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Servlet.class)
|
||||
@ConditionalOnWebApplication
|
||||
public static class VelocityWebConfiguration extends VelocityConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(VelocityConfig.class)
|
||||
public VelocityConfigurer velocityConfigurer() {
|
||||
VelocityConfigurer configurer = new VelocityConfigurer();
|
||||
applyProperties(configurer);
|
||||
return configurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public VelocityEngine velocityEngine(VelocityConfigurer configurer)
|
||||
throws VelocityException, IOException {
|
||||
return configurer.createVelocityEngine();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "velocityViewResolver")
|
||||
public VelocityViewResolver velocityViewResolver() {
|
||||
VelocityViewResolver resolver = new VelocityViewResolver();
|
||||
new TemplateViewResolverConfigurer().configureTemplateViewResolver(resolver,
|
||||
this.properties);
|
||||
resolver.setToolboxConfigLocation(this.properties.getToolboxConfigLocation());
|
||||
resolver.setDateToolAttribute(this.properties.getDateToolAttribute());
|
||||
resolver.setNumberToolAttribute(this.properties.getNumberToolAttribute());
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.velocity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties} for configuring Velocity
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.velocity")
|
||||
public class VelocityProperties extends AbstractTemplateViewResolverProperties {
|
||||
|
||||
public static final String DEFAULT_RESOURCE_LOADER_PATH = "classpath:/templates/";
|
||||
|
||||
public static final String DEFAULT_PREFIX = "";
|
||||
|
||||
public static final String DEFAULT_SUFFIX = ".vm";
|
||||
|
||||
private String dateToolAttribute;
|
||||
|
||||
private String numberToolAttribute;
|
||||
|
||||
private Map<String, String> properties = new HashMap<String, String>();
|
||||
|
||||
private String resourceLoaderPath = DEFAULT_RESOURCE_LOADER_PATH;
|
||||
|
||||
private String toolboxConfigLocation;
|
||||
|
||||
public VelocityProperties() {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX);
|
||||
}
|
||||
|
||||
public String getDateToolAttribute() {
|
||||
return this.dateToolAttribute;
|
||||
}
|
||||
|
||||
public void setDateToolAttribute(String dateToolAttribute) {
|
||||
this.dateToolAttribute = dateToolAttribute;
|
||||
}
|
||||
|
||||
public String getNumberToolAttribute() {
|
||||
return this.numberToolAttribute;
|
||||
}
|
||||
|
||||
public void setNumberToolAttribute(String numberToolAttribute) {
|
||||
this.numberToolAttribute = numberToolAttribute;
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String getResourceLoaderPath() {
|
||||
return this.resourceLoaderPath;
|
||||
}
|
||||
|
||||
public void setResourceLoaderPath(String resourceLoaderPath) {
|
||||
this.resourceLoaderPath = resourceLoaderPath;
|
||||
}
|
||||
|
||||
public String getToolboxConfigLocation() {
|
||||
return this.toolboxConfigLocation;
|
||||
}
|
||||
|
||||
public void setToolboxConfigLocation(String toolboxConfigLocation) {
|
||||
this.toolboxConfigLocation = toolboxConfigLocation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.velocity;
|
||||
|
||||
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link TemplateAvailabilityProvider} that provides availability information for
|
||||
* Velocity view templates
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class VelocityTemplateAvailabilityProvider implements TemplateAvailabilityProvider {
|
||||
|
||||
@Override
|
||||
public boolean isTemplateAvailable(String view, Environment environment,
|
||||
ClassLoader classLoader, ResourceLoader resourceLoader) {
|
||||
if (ClassUtils.isPresent("org.apache.velocity.app.VelocityEngine", classLoader)) {
|
||||
String loaderPath = environment.getProperty(
|
||||
"spring.velocity.resourceLoaderPath",
|
||||
VelocityProperties.DEFAULT_RESOURCE_LOADER_PATH);
|
||||
String prefix = environment.getProperty("spring.velocity.prefix",
|
||||
VelocityProperties.DEFAULT_PREFIX);
|
||||
String suffix = environment.getProperty("spring.velocity.suffix",
|
||||
VelocityProperties.DEFAULT_SUFFIX);
|
||||
return resourceLoader.getResource(loaderPath + prefix + view + suffix)
|
||||
.exists();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
|
||||
@@ -46,4 +47,5 @@ org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
|
||||
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
|
||||
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
|
||||
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
|
||||
org.springframework.boot.autoconfigure.velocity.VelocityTemplateAvailabilityProvider,\
|
||||
org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.velocity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.support.RequestContext;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
|
||||
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link VelocityAutoConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class VelocityAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
|
||||
@Before
|
||||
public void setupContext() {
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
registerAndRefreshContext();
|
||||
assertThat(this.context.getBean(VelocityViewResolver.class), notNullValue());
|
||||
assertThat(this.context.getBean(VelocityConfigurer.class), notNullValue());
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void nonExistentTemplateLocation() {
|
||||
registerAndRefreshContext("spring.velocity.resourceLoaderPath:"
|
||||
+ "classpath:/does-not-exist/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyTemplateLocation() {
|
||||
new File("target/test-classes/templates/empty-directory").mkdir();
|
||||
registerAndRefreshContext("spring.velocity.resourceLoaderPath:"
|
||||
+ "classpath:/templates/empty-directory/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultViewResolution() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
MockHttpServletResponse response = render("home");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("home"));
|
||||
assertThat(response.getContentType(), equalTo("text/html;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customContentType() throws Exception {
|
||||
registerAndRefreshContext("spring.velocity.contentType:application/json");
|
||||
MockHttpServletResponse response = render("home");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("home"));
|
||||
assertThat(response.getContentType(), equalTo("application/json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customPrefix() throws Exception {
|
||||
registerAndRefreshContext("spring.velocity.prefix:prefix/");
|
||||
MockHttpServletResponse response = render("prefixed");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("prefixed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customSuffix() throws Exception {
|
||||
registerAndRefreshContext("spring.velocity.suffix:.freemarker");
|
||||
MockHttpServletResponse response = render("suffixed");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("suffixed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customTemplateLoaderPath() throws Exception {
|
||||
registerAndRefreshContext("spring.velocity.resourceLoaderPath:classpath:/custom-templates/");
|
||||
MockHttpServletResponse response = render("custom");
|
||||
String result = response.getContentAsString();
|
||||
assertThat(result, containsString("custom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disableCache() {
|
||||
registerAndRefreshContext("spring.velocity.cache:false");
|
||||
assertThat(this.context.getBean(VelocityViewResolver.class).getCacheLimit(),
|
||||
equalTo(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customFreeMarkerSettings() {
|
||||
registerAndRefreshContext("spring.velocity.properties.directive.parse.max.depth:10");
|
||||
assertThat(this.context.getBean(VelocityConfigurer.class).getVelocityEngine()
|
||||
.getProperty("directive.parse.max.depth"), equalTo((Object) "10"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderTemplate() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
VelocityConfigurer velocity = this.context.getBean(VelocityConfigurer.class);
|
||||
StringWriter writer = new StringWriter();
|
||||
Template template = velocity.getVelocityEngine().getTemplate("message.vm");
|
||||
template.process();
|
||||
VelocityContext velocityContext = new VelocityContext();
|
||||
velocityContext.put("greeting", "Hello World");
|
||||
template.merge(velocityContext, writer);
|
||||
assertThat(writer.toString(), containsString("Hello World"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderNonWebAppTemplate() throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
VelocityAutoConfiguration.class);
|
||||
try {
|
||||
VelocityEngine velocity = context.getBean(VelocityEngine.class);
|
||||
StringWriter writer = new StringWriter();
|
||||
Template template = velocity.getTemplate("message.vm");
|
||||
template.process();
|
||||
VelocityContext velocityContext = new VelocityContext();
|
||||
velocityContext.put("greeting", "Hello World");
|
||||
template.merge(velocityContext, writer);
|
||||
assertThat(writer.toString(), containsString("Hello World"));
|
||||
}
|
||||
finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerAndRefreshContext(String... env) {
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
this.context.register(VelocityAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
public String getGreeting() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
private MockHttpServletResponse render(String viewName) throws Exception {
|
||||
VelocityViewResolver resolver = this.context.getBean(VelocityViewResolver.class);
|
||||
View view = resolver.resolveViewName(viewName, Locale.UK);
|
||||
assertThat(view, notNullValue());
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
|
||||
this.context);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
view.render(null, request, response);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.velocity;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link VelocityTemplateAvailabilityProvider}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class VelocityTemplateAvailabilityProviderTests {
|
||||
|
||||
private final TemplateAvailabilityProvider provider = new VelocityTemplateAvailabilityProvider();
|
||||
|
||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
@Test
|
||||
public void availabilityOfTemplateInDefaultLocation() {
|
||||
assertTrue(this.provider.isTemplateAvailable("home", this.environment, getClass()
|
||||
.getClassLoader(), this.resourceLoader));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void availabilityOfTemplateThatDoesNotExist() {
|
||||
assertFalse(this.provider.isTemplateAvailable("whatever", this.environment,
|
||||
getClass().getClassLoader(), this.resourceLoader));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void availabilityOfTemplateWithCustomLoaderPath() {
|
||||
this.environment.setProperty("spring.velocity.resourceLoaderPath",
|
||||
"classpath:/custom-templates/");
|
||||
|
||||
assertTrue(this.provider.isTemplateAvailable("custom", this.environment,
|
||||
getClass().getClassLoader(), this.resourceLoader));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void availabilityOfTemplateWithCustomPrefix() {
|
||||
this.environment.setProperty("spring.velocity.prefix", "prefix/");
|
||||
|
||||
assertTrue(this.provider.isTemplateAvailable("prefixed", this.environment,
|
||||
getClass().getClassLoader(), this.resourceLoader));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void availabilityOfTemplateWithCustomSuffix() {
|
||||
this.environment.setProperty("spring.velocity.suffix", ".freemarker");
|
||||
|
||||
assertTrue(this.provider.isTemplateAvailable("suffixed", this.environment,
|
||||
getClass().getClassLoader(), this.resourceLoader));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
custom
|
||||
@@ -0,0 +1 @@
|
||||
home
|
||||
@@ -0,0 +1 @@
|
||||
Message: ${greeting}
|
||||
@@ -0,0 +1 @@
|
||||
prefixed
|
||||
@@ -114,6 +114,8 @@
|
||||
<thymeleaf-extras-springsecurity3.version>2.1.1.RELEASE</thymeleaf-extras-springsecurity3.version>
|
||||
<thymeleaf-layout-dialect.version>1.2.4</thymeleaf-layout-dialect.version>
|
||||
<tomcat.version>7.0.53</tomcat.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<velocity-tools.version>2.0</velocity-tools.version>
|
||||
</properties>
|
||||
<prerequisites>
|
||||
<maven>3.0.0</maven>
|
||||
@@ -267,6 +269,11 @@
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-velocity</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@@ -450,6 +457,16 @@
|
||||
<artifactId>tomcat-jsp-api</artifactId>
|
||||
<version>${tomcat.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
<version>${velocity-tools.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
|
||||
@@ -94,6 +94,7 @@ content into your application; rather pick only the properties that you need.
|
||||
spring.freemarker.exposeSpringMacroHelpers=false
|
||||
spring.freemarker.prefix=
|
||||
spring.freemarker.requestContextAttribute=
|
||||
spring.freemarker.settings.*=
|
||||
spring.freemarker.suffix=.ftl
|
||||
spring.freemarker.templateEncoding=UTF-8
|
||||
spring.freemarker.templateLoaderPath=classpath:/templates/
|
||||
@@ -103,17 +104,36 @@ content into your application; rather pick only the properties that you need.
|
||||
spring.groovy.template.allowRequestOverride=false
|
||||
spring.groovy.template.allowSessionOverride=false
|
||||
spring.groovy.template.cache=true
|
||||
spring.groovy.template.configuration.*= # See Groovy's TemplateConfiguration
|
||||
spring.groovy.template.contentType=text/html
|
||||
spring.groovy.template.prefix=classpath:/templates/
|
||||
spring.groovy.template.suffix=.tpl
|
||||
spring.groovy.template.templateEncoding=UTF-8
|
||||
spring.groovy.template.viewNames= # whitelist of view names that can be resolved
|
||||
spring.groovy.template.configuration.*= # See Groovy's TemplateConfiguration
|
||||
|
||||
# VELOCITY TEMPLATES ({sc-spring-boot-autoconfigure}}/velocity/VelocityAutoConfiguration.{sc-ext}[VelocityAutoConfiguration])
|
||||
spring.velocity.allowRequestOverride=false
|
||||
spring.velocity.allowSessionOverride=false
|
||||
spring.velocity.cache=true
|
||||
spring.velocity.checkTemplateLocation=true
|
||||
spring.velocity.contentType=text/html
|
||||
spring.velocity.dateToolAttribute=
|
||||
spring.velocity.exposeRequestAttributes=false
|
||||
spring.velocity.exposeSessionAttributes=false
|
||||
spring.velocity.exposeSpringMacroHelpers=false
|
||||
spring.velocity.numberToolAttribute=
|
||||
spring.velocity.prefix=
|
||||
spring.velocity.properties.*=
|
||||
spring.velocity.requestContextAttribute=
|
||||
spring.velocity.resourceLoaderPath=classpath:/templates/
|
||||
spring.velocity.suffix=.ftl
|
||||
spring.velocity.templateEncoding=UTF-8
|
||||
spring.velocity.viewNames= # whitelist of view names that can be resolved
|
||||
|
||||
# INTERNATIONALIZATION ({sc-spring-boot-autoconfigure}/MessageSourceAutoConfiguration.{sc-ext}[MessageSourceAutoConfiguration])
|
||||
spring.messages.basename=messages
|
||||
spring.messages.cacheSeconds=-1
|
||||
spring.messages.encoding=UTF-8
|
||||
spring.messages.cacheSeconds=-1
|
||||
|
||||
[[common-application-properties-security]]
|
||||
# SECURITY ({sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[SecurityProperties])
|
||||
|
||||
@@ -41,6 +41,9 @@ The following auto-configuration classes are from the `spring-boot-autoconfigure
|
||||
|{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[FreeMarkerAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/groovy/templates/GroovyTemplateAutoConfiguration.{sc-ext}[GroovyTemplateAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/groovy/templates/GroovyTemplateAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{sc-ext}[HibernateJpaAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
@@ -95,6 +98,9 @@ The following auto-configuration classes are from the `spring-boot-autoconfigure
|
||||
|{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[ThymeleafAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[VelocityAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[WebMvcAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|
||||
@@ -813,20 +813,28 @@ added.
|
||||
``freeMarkerViewResolver''. It looks for resources in a loader path (externalized to
|
||||
`spring.freemarker.templateLoaderPath`, default ``classpath:/templates/'') by
|
||||
surrounding the view name with a prefix and suffix (externalized to `spring.freemarker.prefix`
|
||||
and `spring.freemarker.suffix`, defaults ``'' and ``.ftl'' respectively). It can be overriden
|
||||
and `spring.freemarker.suffix`, with empty and ``.ftl'' defaults respectively). It can be overriden
|
||||
by providing a bean of the same name.
|
||||
|
||||
* If you use Groovy templates (actually if groovy-templates is on your classpath) you
|
||||
also have a `Groovy TemplateViewResolver` with id
|
||||
* If you use Groovy templates (actually if groovy-templates is on your classpath) you will
|
||||
also have a `Groovy TemplateViewResolver` with id
|
||||
``groovyTemplateViewResolver''. It looks for resources in a loader path by
|
||||
surrounding the view name with a prefix and suffix (externalized to `spring.groovy.template.prefix`
|
||||
and `spring.groovy.template.suffix`, defaults ``classpath:/templates/'' and ``.tpl'' respectively). It can be overriden
|
||||
by providing a bean of the same name.
|
||||
surrounding the view name with a prefix and suffix (externalized to
|
||||
`spring.groovy.template.prefix` and `spring.groovy.template.suffix`, defaults
|
||||
``classpath:/templates/'' and ``.tpl'' respectively). It can be overriden by providing a bean of
|
||||
the same name.
|
||||
|
||||
* If you use Velocity you will also have a `VelocityViewResolver` with id ``velocityViewResolver''.
|
||||
It looks for resources in a loader path (externalized to `spring.velocity.resourceLoaderPath`,
|
||||
default ``classpath:/templates/'') by surrounding the view name with a prefix and suffix
|
||||
(externalized to `spring.velocity.prefix' and `spring.velocity.suffix`, with empty and ``.vm''
|
||||
defaults respectively). It can be overridden by providing a bean of the same name.
|
||||
|
||||
Check out {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`],
|
||||
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`],
|
||||
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}['GroovyTemplateAutoConfiguration'] and
|
||||
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}['FreeMarkerAutoConfiguration']
|
||||
{sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`],
|
||||
{sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`] and
|
||||
{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[`VelocityAutoConfiguration`]
|
||||
|
||||
|
||||
|
||||
@@ -1279,12 +1287,13 @@ The Actuator installs a ``whitelabel'' error page that you will see in browser c
|
||||
you encounter a server error (machine clients consuming JSON and other media types should
|
||||
see a sensible response with the right error code). To switch it off you can set
|
||||
`error.whitelabel.enabled=false`, but normally in addition or alternatively to that you
|
||||
will want to add your own error page replacing the whitelabel one. If you are using
|
||||
Thymeleaf or FreeMarker you can do this by adding an `error.html` or `error.ftl` template
|
||||
respectively. In general what you need is a `View` that resolves with a name of `error`,
|
||||
and/or a `@Controller` that handles the `/error` path. Unless you replaced some of the
|
||||
default configuration you should find a `BeanNameViewResolver` in your `ApplicationContext`
|
||||
so a `@Bean` with id `error` would be a simple way of doing that.
|
||||
will want to add your own error page replacing the whitelabel one. Exactly how you do this
|
||||
dependns on the templating technology that you are using. For example, if you are using
|
||||
Thymeleaf you would add an `error.html` template and if you are using FreeMarker you would
|
||||
add an `error.ftl` template. In general what you need is a `View` that resolves with a name
|
||||
of `error`, and/or a `@Controller` that handles the `/error` path. Unless you replaced some
|
||||
of the default configuration you should find a `BeanNameViewResolver` in your
|
||||
`ApplicationContext` so a `@Bean` with id `error` would be a simple way of doing that.
|
||||
Look at {sc-spring-boot-autoconfigure}/web/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] for more options.
|
||||
|
||||
|
||||
@@ -1403,6 +1412,13 @@ If you are using Groovy templates, then set `spring.groovy.template.cache` to `f
|
||||
for other Groovy customization options.
|
||||
|
||||
|
||||
[[howto-reload-velocity-content]]
|
||||
=== Reload Velocity templates without restarting the container
|
||||
If you are using Velocity, then set `spring.velocity.cache` to `false`. See
|
||||
{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[`VelocityAutoConfiguration`]
|
||||
for other Velocity customization options.
|
||||
|
||||
|
||||
[[howto-reload-java-classes-without-restarting]]
|
||||
=== Reload Java classes without restarting the container
|
||||
Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if you make a
|
||||
|
||||
@@ -906,27 +906,26 @@ and it will be silently ignored by most build tools if you generate a jar.
|
||||
[[boot-features-spring-mvc-template-engines]]
|
||||
==== Template engines
|
||||
|
||||
As well as REST web services, you can also use Spring MVC to serve
|
||||
dynamic HTML content. Spring MVC supports a variety of templating
|
||||
technologies including: Velocity, FreeMarker and JSPs. Many
|
||||
As well as REST web services, you can also use Spring MVC to serve dynamic HTML content. Spring
|
||||
MVC supports a variety of templating technologies including Velocity, FreeMarker and JSPs. Many
|
||||
other templating engines also ship their own Spring MVC integrations.
|
||||
|
||||
Spring Boot includes auto-configuration support for the Thymeleaf,
|
||||
[FreeMarker](http://freemarker.org/docs/) and
|
||||
[Groovy](http://beta.groovy-lang.org/docs/groovy-2.3.0/html/documentation/markup-template-engine.html)
|
||||
templating engines. Thymeleaf is an XML/XHTML/HTML5 template engine
|
||||
that can work both in web and non-web environments. If allows you to
|
||||
create natural templates that can be correctly displayed by browsers
|
||||
and therefore work also as static prototypes. Your FreeMarker, Groovy
|
||||
and Thymeleaf templates will be picked up automatically from
|
||||
`src/main/resources/templates`.
|
||||
Spring Boot includes auto-configuration support for the following templating engines:
|
||||
|
||||
- http://freemarker.org/docs/[FreeMarker]
|
||||
- http://beta.groovy-lang.org/docs/groovy-2.3.0/html/documentation/markup-template-engine.html[Groovy]
|
||||
- http://www.thymeleaf.org[Thymeleaf]
|
||||
- http://velocity.apache.org[Velocity]
|
||||
|
||||
When you're using one of these templating engines with the default configuration, your templates
|
||||
will be picked up automatically from `src/main/resources/templates`.
|
||||
|
||||
TIP: JSPs should be avoided if possible, there are several
|
||||
<<boot-features-jsp-limitations, known limitations>> when using them with embedded
|
||||
servlet containers.
|
||||
|
||||
|
||||
|
||||
[[boot-features-error-handling]]
|
||||
==== Error Handling
|
||||
Spring Boot provides an `/error` mapping by default that handles all errors in a
|
||||
|
||||
@@ -258,6 +258,9 @@ and Hibernate.
|
||||
|`spring-boot-starter-thymeleaf`
|
||||
|Support for the Thymeleaf templating engine, including integration with Spring.
|
||||
|
||||
|`spring-boot-starter-velocity`
|
||||
|Support for the Velocity templating engine
|
||||
|
||||
|`spring-boot-starter-web`
|
||||
|Support for full-stack web development, including Tomcat and `spring-webmvc`.
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<module>spring-boot-sample-web-static</module>
|
||||
<module>spring-boot-sample-web-jsp</module>
|
||||
<module>spring-boot-sample-web-ui</module>
|
||||
<module>spring-boot-sample-web-velocity</module>
|
||||
<module>spring-boot-sample-websocket</module>
|
||||
<module>spring-boot-sample-xml</module>
|
||||
</modules>
|
||||
|
||||
48
spring-boot-samples/spring-boot-sample-web-velocity/pom.xml
Normal file
48
spring-boot-samples/spring-boot-sample-web-velocity/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<!-- Your own application should inherit from spring-boot-starter-parent -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-samples</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-sample-web-velocity</artifactId>
|
||||
<name>Spring Boot Web Velocity Sample</name>
|
||||
<description>Spring Boot Web Velocity Sample</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
<m2eclipse.wtp.contextRoot>/</m2eclipse.wtp.contextRoot>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-velocity</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.velocity;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
public class SampleWebVelocityApplication {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleWebVelocityApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.velocity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class WelcomeController {
|
||||
|
||||
@Value("${application.message:Hello World}")
|
||||
private String message = "Hello World";
|
||||
|
||||
@RequestMapping("/")
|
||||
public String welcome(Map<String, Object> model) {
|
||||
model.put("time", new Date());
|
||||
model.put("message", this.message);
|
||||
return "welcome";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
application.message: Hello, Andy
|
||||
spring.velocity.dateToolAttribute: dateTool
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<body>
|
||||
Something went wrong: ${status} ${error}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<body>
|
||||
<span>Time:</span>
|
||||
<ul>
|
||||
<li>From controller: $time</li>
|
||||
<li>From velocity: $dateTool</li>
|
||||
</ul>
|
||||
<span>Message: $message</span>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.velocity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Basic integration tests for Velocity application.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SampleWebVelocityApplication.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest("server.port=0")
|
||||
@DirtiesContext
|
||||
public class SampleWebVelocityApplicationTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void testVelocityTemplate() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.port, String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
assertTrue("Wrong body:\n" + entity.getBody(),
|
||||
entity.getBody().contains("Hello, Andy"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVelocityErrorTemplate() throws Exception {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
|
||||
HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
|
||||
|
||||
ResponseEntity<String> responseEntity = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + this.port + "/does-not-exist", HttpMethod.GET,
|
||||
requestEntity, String.class);
|
||||
|
||||
assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode());
|
||||
assertTrue("Wrong body:\n" + responseEntity.getBody(), responseEntity.getBody()
|
||||
.contains("Something went wrong: 404 Not Found"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,6 +43,7 @@
|
||||
<module>spring-boot-starter-test</module>
|
||||
<module>spring-boot-starter-thymeleaf</module>
|
||||
<module>spring-boot-starter-tomcat</module>
|
||||
<module>spring-boot-starter-velocity</module>
|
||||
<module>spring-boot-starter-web</module>
|
||||
<module>spring-boot-starter-websocket</module>
|
||||
</modules>
|
||||
|
||||
38
spring-boot-starters/spring-boot-starter-velocity/pom.xml
Normal file
38
spring-boot-starters/spring-boot-starter-velocity/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starters</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-starter-velocity</artifactId>
|
||||
<name>Spring Boot Velocity Starter</name>
|
||||
<description>Spring Boot Velocity Starter</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Reference in New Issue
Block a user