Spring-Boot + Spring-MVC + Thymeleaf + Apache Tiles

I have a pre-existing client module with apache tiles and thymeleaf, which works well. I wanted to convert it to spring-boot and wanted to do it step by step, but I am really getting stuck on it. I don't want to change many times, I would love it when someone could tell me which step I should take first and run it. I've already tried writing servlets in javaConfig, but I'm looping too. Maybe someone can help me. If you need more information, please do not hesitate to ask.

Another question, do I need to change from xml to javaconfig? I would prefer the easiest way. But as soon as I add the spring-starter dependency to the pom, the application no longer works.

enter image description here

=======

POM:

<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>at.compax.bbsng</groupId>
    <artifactId>bbsng-client</artifactId>
    <version>0.1.0-SNAPSHOT</version>
</parent>

<artifactId>bbsng-client-mvc</artifactId>
<name>bbsng-client-mvc</name>
<packaging>war</packaging>

<properties>
    <org.apache.tiles-version>2.2.2</org.apache.tiles-version>
    <org.thymeleaf-version>2.0.16</org.thymeleaf-version>
    <slf4j-version>1.7.5</slf4j-version>
    <jackson.version>1.9.10</jackson.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- Apache Tiles -->
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-template</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-servlet</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>

    <!-- ThyMeLeaf ... -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>${org.thymeleaf-version}</version>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring3</artifactId>
        <version>${org.thymeleaf-version}</version>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-tiles2</artifactId>
        <version>2.0.0</version>
    </dependency>

    <!-- Jackson JSON Mapper -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <!-- Servlet ... -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- COMMONS ... -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>

</dependencies>


<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>false</downloadJavadocs>
                <additionalBuildcommands>
                    <buildCommand>
                        <name>org.springframework.ide.eclipse.core.springbuilder</name>
                    </buildCommand>
                </additionalBuildcommands>
                <additionalProjectnatures>
                    <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                </additionalProjectnatures>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
                <warName>${project.name}-${project.version}</warName>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>${java-version}</source>
                <target>${java-version}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.5</version>
            <configuration>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
        </plugin>
    </plugins>
</build>

      

======

rest-servlet-context.xml

<mvc:annotation-driven>
    <mvc:async-support default-timeout="120000">
        <mvc:callable-interceptors>
            <bean class="at.compax.bbsng.client.mvc.TimeoutCallableProcessingInterceptor" />
        </mvc:callable-interceptors>
    </mvc:async-support>
</mvc:annotation-driven>
<context:component-scan base-package="at.compax.bbsng.client.mvc.rest" />

      

=====

applications servlet-context.xml

<!-- **************************************************************** -->
<!-- RESOURCE FOLDERS CONFIGURATION -->
<!-- Dispatcher configuration for serving static resources -->
<!-- **************************************************************** -->
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/css/" mapping="/css/**" />


<!-- **************************************************************** -->
<!-- SPRING ANNOTATION PROCESSING -->
<!-- **************************************************************** -->
<mvc:annotation-driven>
    <mvc:async-support default-timeout="120000">
        <mvc:callable-interceptors>
            <bean class="at.compax.bbsng.client.mvc.TimeoutCallableProcessingInterceptor" />
        </mvc:callable-interceptors>
    </mvc:async-support>
</mvc:annotation-driven>
<context:component-scan base-package="at.compax.bbsng.client.mvc.web" />


<!-- **************************************************************** -->
<!-- MESSAGE EXTERNALIZATION/INTERNATIONALIZATION -->
<!-- Standard Spring MessageSource implementation -->
<!-- **************************************************************** -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="Messages" />
</bean>


<!-- **************************************************************** -->
<!-- THYMELEAF-SPECIFIC ARTIFACTS -->
<!-- TemplateResolver <- TemplateEngine <- ViewResolver -->
<!-- **************************************************************** -->
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
    <property name="additionalDialects">
        <set>
            <bean class="org.thymeleaf.extras.tiles2.dialect.TilesDialect"/>
        </set>
    </property>
</bean>

<!-- Configures the Tiles layout system using a specific thymeleaf-enabled Tiles Configurer -->
<bean id="tilesConfigurer" class="org.thymeleaf.extras.tiles2.spring.web.configurer.ThymeleafTilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/**/views.xml</value>
        </list>
    </property>
</bean>

<!-- Resolves view names returned by Controllers as names of Tiles definitions -->
<bean id="tilesViewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
    <property name="viewClass" value="org.thymeleaf.extras.tiles2.spring.web.view.ThymeleafTilesView"/>
    <property name="templateEngine" ref="templateEngine"/>
</bean>

<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
</bean>

      

=========

SECOND STEP OF STEP:

I took a few steps so that I can now start my application by launching applicationClass from ECLIPSE.

What I have been doing so far:

====

POM: Please keep the view that I removed the thymeleaf starter from the classpath because I did not start it with the thymeleaf starter

...

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- <dependency> -->
    <!-- <groupId>org.springframework.boot</groupId> -->
    <!-- <artifactId>spring-boot-starter-thymeleaf</artifactId> -->
    <!-- </dependency> -->

    <!-- Apache Tiles -->
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-template</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-servlet</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>

    <!-- ThyMeLeaf ... -->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-tiles2-spring4</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>

    ...

</dependencies>


<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

      

====

WebMvcConfig for ThyMeLeaf configuration

@Configuration
@ComponentScan
public class WebMvcConfig {

    @Bean
    public ThymeleafTilesConfigurer tilesConfigurer() {
        final ThymeleafTilesConfigurer configurer = new ThymeleafTilesConfigurer();
        configurer.setDefinitions("/WEB-INF/**/views.xml");
        return configurer;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        final ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setViewClass(ThymeleafTilesView.class);
        resolver.setTemplateEngine(templateEngine());
        resolver.setCharacterEncoding(UTF_8);
        return resolver;
    }

    private SpringTemplateEngine templateEngine() {
        final SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver());
        engine.setAdditionalDialects(dialects());
        return engine;
    }

    private ServletContextTemplateResolver templateResolver() {
        final ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("HTML5");
        resolver.setCharacterEncoding(UTF_8);
        return resolver;
    }

    private Set<IDialect> dialects() {
        final Set<IDialect> set = new HashSet<IDialect>();
        set.add(new TilesDialect());
        return set;
    }

}

      

=====

Spring ThyMeLeaf Autoconfiguration initial start class deactivated because I was not working with apache tile

@Configuration
@Import({ ServiceConfig.class, RestMvcConfig.class, WebMvcConfig.class })
@EnableAutoConfiguration(exclude = { ThymeleafAutoConfiguration.class })
public class ApplicationClientMvc implements WebApplicationInitializer {
    public static void main(final String[] args) {
        SpringApplication.run(ApplicationClientMvc.class, args);
    }

    @Bean
    public ServletRegistrationBean applicationDispatcherRegistration(final DispatcherServlet dispatcherServlet) {
        final ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.setName("applicationServlet");
        registration.addUrlMappings("/app/*");
        registration.setAsyncSupported(true);
        registration.setLoadOnStartup(1);
        registration.addInitParameter("contextConfigLocation", "at.compax.bbsng.client.mvc.web.WebMvcConfig");
        registration.setOrder(1);
        return registration;
    }

    @Bean
    public ServletRegistrationBean restDispatcherRegistration(final DispatcherServlet dispatcherServlet) {
        final ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.setName("restServlet");
        registration.addUrlMappings("/rest/*");
        registration.setAsyncSupported(true);
        registration.setLoadOnStartup(0);
        registration.addInitParameter("contextConfigLocation", "at.compax.bbsng.client.mvc.rest.RestMvcConfig");
        registration.setOrder(0);
        return registration;
    }

    @Override
    public void onStartup(final ServletContext servletContext) throws ServletException {
        final FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter());
        encodingFilter.setInitParameter("encoding", UTF_8);
        encodingFilter.setInitParameter("forceEncoding", "true");
        encodingFilter.addMappingForUrlPatterns(null, true, "/*");
    }
}

      

====

When I launch this application through Eclipse by running the spring-Boot Start class, the application is running.

+2


source to share


2 answers


Ok guys

I got it right and I hope it helps other developers with similar problems.

In the POM, I removed all Spring-Dependencies and I only use Spring-Starter-Dependencies, for example the following snippet:

...

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <!-- Apache Tiles -->
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-template</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-servlet</artifactId>
        <version>${org.apache.tiles-version}</version>
    </dependency>

    <!-- ThyMeLeaf ... -->
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-tiles2-spring4</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>

....

      

In my starter class, I have activated ThyMeLeaf Autoconfiguration again, my complete class looks like this. Be careful, I am using two different servlets, one for REST, one for Thymeleaf.

@Configuration
@Import({ ServiceConfig.class, RestMvcConfig.class, WebMvcConfig.class })
@EnableAutoConfiguration
public class ApplicationClientMvc {
    public static void main(final String[] args) {
        SpringApplication.run(ApplicationClientMvc.class, args);
    }

    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }

    @Bean
    public ServletRegistrationBean applicationDispatcherRegistration(final DispatcherServlet dispatcherServlet) {
        final ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.setName("applicationServlet");
        registration.addUrlMappings("/app/*");
        registration.setAsyncSupported(true);
        registration.setLoadOnStartup(1);
        registration.addInitParameter("contextConfigLocation", "a.c.b.c.m.w.WebMvcConfig");
        registration.setOrder(1);
        return registration;
    }

    @Bean
    public ServletRegistrationBean restDispatcherRegistration(final DispatcherServlet dispatcherServlet) {
        final ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.setName("restServlet");
        registration.addUrlMappings("/rest/*");
        registration.setAsyncSupported(true);
        registration.setLoadOnStartup(0);
        registration.addInitParameter("contextConfigLocation", "a.c.b.c.m.r.RestMvcConfig");
        registration.setOrder(0);
        return registration;
    }
}

      

====

My WebMVCConfig class looks like this, is in the package ....mvc.rest

:

@Configuration
@ComponentScan
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {

    @Autowired public SpringTemplateEngine templateEngine;

    @Bean
    public ThymeleafTilesConfigurer tilesConfigurer() {
        final ThymeleafTilesConfigurer configurer = new ThymeleafTilesConfigurer();
        configurer.setDefinitions(ThymeleafAutoConfiguration.DEFAULT_PREFIX + "**/views.xml");
        return configurer;
    }

    @Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
        final ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setViewClass(ThymeleafTilesView.class);
        resolver.setTemplateEngine(templateEngine);
        resolver.setCharacterEncoding(UTF_8);
        return resolver;
    }

    @Bean
    public TilesDialect tilesDialect() {
        return new TilesDialect();
    }

    //

    @Value("${server.session-timeout}") private Long sessionTimeOut;

    @Override
    public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(sessionTimeOut * 1000L);
        configurer.registerCallableInterceptors(timeoutInterceptor());
    }

    @Bean
    public TimeoutCallableProcessingInterceptor timeoutInterceptor() {
        return new TimeoutCallableProcessingInterceptor();
    }

}

      

===



My RestConfig class is pretty simple

@Configuration
@ComponentScan
public class RestMvcConfig {}

      

===



I moved all my html files or thymelear templates to the templates folder in src / main / resources. Also in one folder you can put all client resources like images, js and css under a static folder. The static folder and templates are keywords and will be found by Spring-Boot automatically. There are no special configurations in application.properties that are needed for thymeleaf and apache tiles.

project structure

====

To enable your application to find resources, you can configure the path as follows:

<link rel="stylesheet" type="text/css" media="screen, projection" 
          href="/static/css/bootstrap.css" 
          th:href="@{/css/bootstrap.css}" />

<link rel="stylesheet" type="text/css" media="screen, projection" 
          href="/static/css/bootstrap-responsive.css" 
          th:href="@{/css/bootstrap-responsive.css}" />

      

===



The folder is java/src/webapp

no longer needed !!!

enter image description here

====

If it helps you, feel free to vote ;-). If you need more information, just comment, I will try to answer within a few days.

======

SECOND PHASE

Ok, so far it only works under Eclipse. When I execute the jar executable, I still get the error. Maybe someone wants to help; -)

Stacktrace:

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/layout/login", template might not exist or might not be accessible by any of the configured Template Resolvers
    at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:245)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
    at org.thymeleaf.extras.tiles2.renderer.ThymeleafAttributeRenderer.write(ThymeleafAttributeRenderer.java:155)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.thymeleaf.extras.tiles2.renderer.MetadataCleaningAttributeRendererWrapper.render(MetadataCleaningAttributeRendererWrapper.java:111)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
    at org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView.render(ThymeleafTilesView.java:125)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:280)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

      

The structure of my JAR is similar:

enter image description here

======

DECISION:

I don't know exactly why, but additionally I need to fix url paths for my templates, which works like in Eclipse, but not like a jar executable. To get it to work in both environments, I had to fix all the template urls as shown below, taking a special look at the attribute value :

BEFORE:

<definition name="home" extends="standard1ColLayout">
    <put-attribute name="title" value="/home/title :: content" type="thymeleaf" />
    <put-attribute name="body" value="/home/body :: content" type="thymeleaf" />
</definition>

      

AFTER:

<definition name="home" extends="standard1ColLayout">
    <put-attribute name="title" value="./home/title :: content" type="thymeleaf" />
    <put-attribute name="body" value="./home/body :: content" type="thymeleaf" />
</definition>

      

Finally, it works under Eclipse and as executable banks. The conversion from a regular Spring-Project to a Spring-Boot Project was not very easy, I hope it helps other developers and I hope this post deserves a vote .; -)

+4


source


This example shows how to configure Thymeleaf using Apache tiles, but it allows spring to boot to auto-configure Thymeleaf. This way you can use all spring-boot predefined environment variables like spring.thymeleaf. * In your application.properties

@Configuration
@AutoConfigureAfter(ThymeleafAutoConfiguration.class)//tweak autoconfiguration for apache tiles after spring boot
@EnableConfigurationProperties(ThymeleafProperties.class)
public class ThymeleafTilesConfig {

    @Autowired//this bean is autoconfigured with spring-boot-thymeleaf
    private ThymeleafViewResolver thymeleafViewResolver;

    @Autowired
    private ThymeleafProperties properties;

    @PostConstruct
    public void setThymeleafTilesViewClass() {
        //just set view class for thymeleaf-tiles
        thymeleafViewResolver.setViewClass(ThymeleafTilesView.class);
    }

    @Bean  
    TilesDialect tilesDialect() {       
    // This bean will be auto picked-up by spring-boot and will be autoconfigured :)
        return new TilesDialect();
    }

    @Bean//create tiles configurer for your needs
    ThymeleafTilesConfigurer tilesConfigurer() {
        final ThymeleafTilesConfigurer configurer = new ThymeleafTilesConfigurer();
        configurer.setDefinitions("classpath:/templates/**/views.xml");
        configurer.setCheckRefresh(!properties.isCache());
        return configurer;
    }
}

      



https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java#L116

+1


source







All Articles