【问题标题】:Why Velocity templates are not recognized in Spring Boot application?为什么在 Spring Boot 应用程序中无法识别 Velocity 模板?
【发布时间】:2017-11-30 14:54:34
【问题描述】:

我想使用 Spring Boot 设置我现有的 Spring 应用程序。我应用 spring-boot:run 命令。

我对配置做了一些更改,所以我可以启动应用程序,打开登录页面,但是速度模板 login.vm 应该在的地方只显示 login文本而不是 login.vm 的内容:

我的应用配置:

@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 -> {

        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<String,String> params = new HashMap<>();
    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;
}
}

MySiteMeshFilter:

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");
}
}

login-decorator.jsp 有以下几行:

<h2><sitemesh:write property='title'/></h2>
<sitemesh:write property='body'/>

LoginController.java 有:

@RequestMapping("/login.html")
public String login(params here) {
    //some checks
    return "login";
}

我的 pom.xml 包含以下依赖项:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.9</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-velocity</artifactId>
  <version>1.4.7.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.apache.velocity</groupId>
  <artifactId>velocity-tools</artifactId>
  <version>2.0</version>
</dependency>
<dependency>
  <groupId>org.apache.velocity</groupId>
  <artifactId>velocity</artifactId>
</dependency>

Velocity 模板位于 src/main/resources/templates/velocity

装饰器位于 src/main/webapp/WEB-INF/decorators

我在日志中没有错误。

所以我的问题是:为什么我的应用程序显示 login 文本而不是 login.vm 速度模板?如何解决这个问题?

我是如何解决这个问题的:

  1. 我将@RestController 更改为@Controller
  2. 添加了 VelocityAutoConfiguration,如 here 所述
  3. 从 ApplicationConfig 中删除了不必要的配置 - 仅保留 siteMeshFilter() 方法。

【问题讨论】:

  • 让我猜猜@RequestMapping@RestController 注释类中。
  • @M.Deinum,是的,但是如果我将 RestController 更改为 Controller,则会出现错误“Whitelabel 错误页面。此应用程序没有 /error 的显式映射,因此您将其视为后备。 "
  • 您必须使用@Controller 否则它不会解析为视图。您收到的错误表明另一个问题。你也在非常努力地不使用 Spring Boot……你自己配置了一切,为什么,Spring Boot 已经自动为你配置了所有这些。
  • @M.Deinum 是对的。 @RestController@Controller + @ResponseBody@ResponseBody 在返回字符串的方法上使 Spring 将该字符串作为纯文本返回作为响应。
  • @M.Deinum,我自己配置​​了所有东西,因为我试图“迁移”我的旧项目,所有东西都配置了。但是,是的,我删除了我的配置和应用程序工作。谢谢。

标签: java spring spring-boot velocity


【解决方案1】:

我是如何解决这个问题的:

  1. 我将@RestController 更改为@Controller
  2. 添加了 VelocityAutoConfiguration,如此处所述
  3. 从 ApplicationConfig 中删除了不必要的配置 - 仅保留 siteMeshFilter() 方法。

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 2022-01-04
    • 2020-11-16
    • 1970-01-01
    • 2021-05-30
    • 2020-05-25
    • 2021-12-08
    • 2018-03-05
    • 2020-09-04
    相关资源
    最近更新 更多