2
votes

I want to set up my existing Spring application with Spring Boot. I apply spring-boot:run command.

I did some changes in configrutions, so I can start the application, open login page, but the place where velocity template login.vm should be it shows only login text instead of the content of login.vm:

enter image description here

My ApplicationConfig:

@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 has the following lines:

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

LoginController.java has:

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

My pom.xml contains the follwoing dependencies:

<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 templates are located in src/main/resources/templates/velocity.

Decorators are located in src/main/webapp/WEB-INF/decorators.

I do not have errors in logs.

So my question: Why my application show login text instead of login.vm velocity template? How to fix this?

How I fixed the issue:

  1. I changed @RestController to @Controller
  2. Added VelocityAutoConfiguration like described here
  3. Deleted unnesesary configurations from ApplicationConfig - leave siteMeshFilter() method only.
1
Let me guess that @RequestMapping is in a @RestController annotated class. - M. Deinum
@M.Deinum, yes, but if I change RestController to Controller, I have error "Whitelabel Error Page. This application has no explicit mapping for /error, so you are seeing this as a fallback." - RuF
You have to use @Controller else it won't resolve to a view. The error you get is an indication of another issue. You are also trying very hard NOT to use Spring Boot... You configure everything yourself, why, Spring Boot auto configures all that for you already. - M. Deinum
@M.Deinum is right. @RestController is @Controller + @ResponseBody. @ResponseBody on a method that returns a string makes Spring to return that string as plain text in response. - naXa
@M.Deinum, I configured everything by myself because I tried to "migrate" my old project where are everything are configured. But yes, I removed my configurations and application works. Thanks. - RuF

1 Answers

0
votes

How I fixed the issue:

  1. I changed @RestController to @Controller
  2. Added VelocityAutoConfiguration like described here
  3. Deleted unnesesary configurations from ApplicationConfig - leave siteMeshFilter() method only.