Как добавить поддержку Freemarker в Spring MVC webapp? Проблема зависимости?

Я пытаюсь создать приложение Spring MVC, используя настройки Freemarker и Java.

Я привык использовать JSP, но думал, что дам Freemarker в этом проекте.

Я добавил Freemarker в качестве зависимости, и jar загружается Maven:

        <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.20</version>
    </dependency>

Я пытаюсь использовать версию 3.2.3.RELEASE Spring.

Моя конфигурация MVC, собранная при чтении аналогичного вопроса:

@ComponentScan(basePackages="yhj.*")
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{


@Bean
public ViewResolver viewResolver() {
    FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
    resolver.setCache(true);
    resolver.setPrefix("");
    resolver.setSuffix(".ftl");
    return resolver;

}

@Bean
public FreeMarkerConfigurer freemarkerConfig() {
    FreeMarkerConfigurer result = new FreeMarkerConfigurer();
    result.setTemplateLoaderPath("/WEB-INF/views/");
    return result;

}
}

Когда я пытаюсь запустить это, я получаю ошибку компиляции, моя IDE сообщает мне, что метод setTemplateLoaderPath (String) не может быть разрешен.

Итак... выглядит как правильный способ настройки Spring MVC с помощью Freemarker? Какую зависимость мне нужно добавить в мой POM, если это проблема?

Ответ 1

Ну, я отсортировал проблему компиляции, добавил зависимость от моего pom...

    <dependency><!-- needed for freemarker FreeMarkerConfigurer stuff -->
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>

Ответ 2

Мое решение для Spring Boot 1.0.2, Spring 4.0.3 и FreeMarker 2.3.20 было следующим классом:

@Configuration
public class MvcConfigurer extends WebMvcConfigurerAdapter {
  @Bean
  public ViewResolver viewResolver() {
    FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
    resolver.setCache(true);
    resolver.setPrefix("");
    resolver.setSuffix(".ftl");
    resolver.setContentType("text/html; charset=UTF-8");
    return resolver;
  }

  @Bean
  public FreeMarkerConfigurer freemarkerConfig() throws IOException, TemplateException {
    FreeMarkerConfigurationFactory factory = new FreeMarkerConfigurationFactory();
    factory.setTemplateLoaderPath("classpath:templates");
    factory.setDefaultEncoding("UTF-8");
    FreeMarkerConfigurer result = new FreeMarkerConfigurer();
    result.setConfiguration(factory.createConfiguration());
    return result;
  }
}

Кроме того, вам нужны те же изменения pom.xml, что и в вопросе и собственный ответ DaFoot.

Ответ 3

@Bean(name = "freeMarkerViewResolver")
    public FreeMarkerViewResolver getFreeMarkerViewResolver() { 
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
        resolver.setPrefix("/WEB-INF/views/json/");
        resolver.setSuffix(".json");
        resolver.setOrder(2);
        resolver.setContentType("application/json");
        resolver.setCache(true);
        return resolver;
    }

    @Bean(name = "freemarkerConfig")
    public FreeMarkerConfigurer getFreemarkerConfig() throws IOException, TemplateException { 
        FreeMarkerConfigurer result = new FreeMarkerConfigurer();
        result.setTemplateLoaderPaths("/"); // prevents FreeMarkerConfigurer from using its default path allowing setPrefix to work as expected
        return result;
    }

Ответ 4

Это моя настраиваемая конфигурация для проекта MVC с использованием Boot

/**
 * Otras configuraciones de la aplicaciones web, incluyendo algunas definidas en
 * xml. Usar @ImportResource("classpath:/extra-config.xml") en caso de quererse
 * importar configuracion en xml
 */
@Configuration 
@PropertySource("classpath:application.properties")
public class WebAppConfig
{
    @Autowired
    private ServletContext context;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer placeHolderConfigurer = new PropertySourcesPlaceholderConfigurer(); 
        return placeHolderConfigurer;
    }

   @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() throws IOException, TemplateException 
    {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer()
        {

            @Override
            protected void postProcessConfiguration(freemarker.template.Configuration config) throws IOException, TemplateException
            {
                WebappTemplateLoader WebAppTplLoader = new WebappTemplateLoader(context, "/WEB-INF/ftl");
                ClassTemplateLoader classTplLoader = new ClassTemplateLoader(context.getClassLoader(), "/templates");
                ClassTemplateLoader baseMvcTplLoader = new ClassTemplateLoader(FreeMarkerConfigurer.class, "");
                MultiTemplateLoader mtl = new MultiTemplateLoader(new TemplateLoader[]
                {
                    WebAppTplLoader,
                    classTplLoader,
                    baseMvcTplLoader
                });  
                config.setTemplateLoader(mtl);
            }
        };
        configurer.setDefaultEncoding("UTF-8"); 
        configurer.setPreferFileSystemAccess(false); 
        return configurer; 
    }

    @Bean
    public FreeMarkerViewResolver viewResolver()
    {
         FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver(); 
         viewResolver.setExposeSpringMacroHelpers(true);  
         viewResolver.setExposeRequestAttributes(true);
         viewResolver.setPrefix("");
         viewResolver.setSuffix(".ftl");
         viewResolver.setContentType("text/html;charset=UTF-8");
         return viewResolver;
    }
}

Первые 2 загрузчика позволяют загружать .ftl шаблоны в war файлы из "/WEB-INF/ftl" и из обычных jar файлов из src/resources/templates. Если вы хотите использовать теги безопасности в freemarker, то escense это две строки:

         viewResolver.setExposeSpringMacroHelpers(true);  
         viewResolver.setExposeRequestAttributes(true);

И загрузчик baseMvcTplLoader, чтобы получить spring.ftl от org.springframework.web.servlet.view.freemarker. Я предлагаю изучить шаблоны ftl в некотором примерном проекте или документации чтобы понять, как работает spring.ftl.

Конфигурация заполнитель не связана с freemarker конфигурация, но очень полезная для инъекций значений в переменных от src/resources/application.properties с помощью @Valueаннотаций.

С этим вы можете использовать все spring в шаблонах freemarker.