title: Why Velocity templates are not recognized in Spring Boot application?
body: <p>I want to set up my existing Spring application with Spring Boot. I apply <em>spring-boot:run</em> command.</p>
  
  <p>I did some changes in configrutions, so I can start the application, open login page, but the place where velocity template <em>login.vm</em> should be it shows only <em>login</em> text instead of the content of <em>login.vm</em>:</p>
  
  <p><a href="https://i.stack.imgur.com/vtgqY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vtgqY.png" alt="enter image description here"></a></p>
  
  <p>My ApplicationConfig:</p>
  
  <pre><code>@SpringBootApplication
  @ImportResource({"classpath:/applicationContext*.xml", "classpath:/static/WEB-INF/dispatcher-servlet.xml"})
  @ComponentScan(basePackages={"my.package"})
  public class ApplicationConfig extends WebMvcConfigurerAdapter{
  
  public static void main(String[] args) {
      SpringApplication.run(ApplicationConfig.class, args);
  }
  
  @Bean
  public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
      return args -&gt; {
  
          System.out.println("Let's inspect the beans provided by Spring Boot:");
  
          String[] beanNames = ctx.getBeanDefinitionNames();
          Arrays.sort(beanNames);
          for (String beanName : beanNames) {
              System.out.println(beanName);
          }
  
      };
  }
  
  @Bean
  public FilterRegistrationBean filterRegistrationBean() {
      FilterRegistrationBean registrationBean = new FilterRegistrationBean();
      CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
      characterEncodingFilter.setForceEncoding(true);
      characterEncodingFilter.setEncoding("UTF-8");
      registrationBean.setFilter(characterEncodingFilter);
      return registrationBean;
  }
  
  @Bean
  RequestDumperFilter requestDumper() {
      return new RequestDumperFilter();
  }
  
  @Bean
  public FilterRegistrationBean siteMeshFilter(){
      FilterRegistrationBean fitler = new FilterRegistrationBean();
      MySiteMeshFilter siteMeshFilter = new MySiteMeshFilter();
      fitler.setFilter(siteMeshFilter);
      return fitler;
  }
  
  @Bean
  public FilterRegistrationBean securityFilterChainRegistration() {
      DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy();
      delegatingFilterProxy.setTargetBeanName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
      FilterRegistrationBean registrationBean = new FilterRegistrationBean(delegatingFilterProxy);
      registrationBean.setName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
      registrationBean.addUrlPatterns("/*");
      return registrationBean;
  }
  
  @Bean
  public WebAppRootListener webAppRootListener() {
      return new WebAppRootListener();
  }
  
  @Bean
  public ServletRegistrationBean dispatcherServletRegistration() {
      ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet(), "/");
      Map&lt;String,String&gt; params = new HashMap&lt;&gt;();
      params.put("load-on-startup","1");
      registration.setInitParameters(params);
      return registration;
  }
  
  @Bean
  public DispatcherServlet dispatcherServlet() {
      return new DispatcherServlet();
  }
  
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.addResourceHandler("/resources/**")
              .addResourceLocations("/resources/");
  }
  
  
  @Bean
  public ViewResolver getViewResolver() {
      VelocityViewResolver resolver = new VelocityViewResolver();
      resolver.setPrefix("");
      resolver.setSuffix(".vm");
      return resolver;
  }
  @Override
  public void configureDefaultServletHandling(
          DefaultServletHandlerConfigurer configurer) {
      configurer.enable();
  }
  
  @Bean
  public VelocityConfigurer velocityConfig() throws IOException {
      VelocityConfigurer velocityConfigurer = new VelocityConfigurer();
      velocityConfigurer.setResourceLoaderPath("/templates/velocity/");
      Properties properties =  new Properties();
      properties.put("output.encoding","UTF-8");
      properties.put("input.encoding","UTF-8");
      properties.put("file.resource.loader.path","/templates/velocity/");
      File file = new ClassPathResource("/templates/velocity/macroses.vm").getFile();
      properties.put("velocimacro.library",file);
      velocityConfigurer.setVelocityProperties(properties);
      return velocityConfigurer;
  }
  }
  </code></pre>
  
  <p>MySiteMeshFilter:</p>
  
  <pre><code>public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
  @Override
  protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
      builder.addDecoratorPath("/*", "/WEB-INF/decorators/default-decorator.jsp")
              .addDecoratorPath("/login.html", "/WEB-INF/decorators/login-decorator.jsp")
              .addDecoratorPaths("/admin/crowd/*", "/WEB-INF/decorators/crowd-decorator.jsp"
                      ,"/WEB-INF/decorators/default-decorator.jsp")
              .addDecoratorPaths("/admin/project/*", "/WEB-INF/decorators/project-decorator.jsp",
                      "/WEB-INF/decorators/default-decorator.jsp")
              .addDecoratorPaths("/admin/report/*", "/WEB-INF/decorators/report-decorator.jsp"
                      , "/WEB-INF/decorators/default-decorator.jsp");
  }
  }
  </code></pre>
  
  <p>login-decorator.jsp has the following lines:</p>
  
  <pre><code>&lt;h2&gt;&lt;sitemesh:write property='title'/&gt;&lt;/h2&gt;
  &lt;sitemesh:write property='body'/&gt;
  </code></pre>
  
  <p>LoginController.java has:</p>
  
  <pre><code>@RequestMapping("/login.html")
  public String login(params here) {
      //some checks
      return "login";
  }
  </code></pre>
  
  <p>My pom.xml contains the follwoing dependencies:</p>
  
  <pre><code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.aspectj&lt;/groupId&gt;
    &lt;artifactId&gt;aspectjweaver&lt;/artifactId&gt;
    &lt;version&gt;1.8.9&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
    &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-velocity&lt;/artifactId&gt;
    &lt;version&gt;1.4.7.RELEASE&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.apache.velocity&lt;/groupId&gt;
    &lt;artifactId&gt;velocity-tools&lt;/artifactId&gt;
    &lt;version&gt;2.0&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.apache.velocity&lt;/groupId&gt;
    &lt;artifactId&gt;velocity&lt;/artifactId&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>Velocity templates are located in <em>src/main/resources/templates/velocity</em>.</p>
  
  <p>Decorators are located in <em>src/main/webapp/WEB-INF/decorators</em>.</p>
  
  <p>I do not have errors in logs.</p>
  
  <p>So my question: Why my application show <em>login</em> text instead of <em>login.vm</em> velocity template? How to fix this?</p>
  
  <p><strong>How I fixed the issue:</strong></p>
  
  <ol>
  <li>I changed @RestController to @Controller</li>
  <li>Added <em>VelocityAutoConfiguration</em> like described <a href="https://gist.github.com/chrisi/11249866" rel="nofollow noreferrer">here</a></li>
  <li>Deleted unnesesary configurations from ApplicationConfig - leave <code>siteMeshFilter()</code> method only.</li>
  </ol>