【问题标题】:Spring-Boot + Spring-MVC + Thymeleaf + Apache TilesSpring-Boot + Spring-MVC + Thymeleaf + Apache Tiles
【发布时间】:2015-02-19 09:45:26
【问题描述】:

我已经有一个带有 apache tile 和 thymeleaf 的客户端模块,效果很好。我想将它转换为 spring-boot 并想一步一步地做,但我真的坚持下去。我不想改变太多,当有人可以告诉我,我应该先做什么并让它运行时,我会喜欢它。我已经尝试在 javaConfig 中编写 servlet,但我也卡住了。也许有人可以帮助我。如果需要更多信息,请不要犹豫。

其他问题是,我需要从 xml 更改为 javaconfig 吗?我更喜欢最简单的方法。但是一旦我向 pom 添加 spring-starter 依赖项,应用程序就不再工作了。

=======

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" />

=====

应用程序-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>

=========

第二步编辑:

我做了几个步骤,现在我可以通过从 ECLIPSE 运行 applicationClass 来启动我的应用程序。

到目前为止我做了什么:

====

POM: 请注意,我从类路径中删除了 thymeleaf-starter,因为我没有使用 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 用于配置 ThyMeLeaf

@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 Boot 入门类 ThyMeLeaf 自动配置已停用,因为我没有让它与 apache 瓦片一起使用

@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, "/*");
    }
}

====

当我通过 Eclipse 通过启动 Spring-Boot Start 类启动该应用程序时,应用程序可以工作。

【问题讨论】:

    标签: spring-mvc spring-boot thymeleaf spring-java-config apache-tiles


    【解决方案1】:

    好吧,伙计们,

    我知道了,希望对其他有类似问题的开发者有所帮助。

    在 POM 中,我删除了所有 Spring-Dependencies,我只使用 Spring-Starter-Dependencies,如下面的 sn-p:

    ...
    
        <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>
    
    ....
    

    在我的初学者课程中,我再次激活了 Thymeleaf 自动配置,我的完整课程如下所示。请注意,我使用两种不同的 servlet,一种用于 REST,一种用于 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;
        }
    }
    

    ====

    我的 WebMVCConfig 类如下所示,在包 ....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();
        }
    
    }
    

    ===

    我的 RestConfig 类非常简单

    @Configuration
    @ComponentScan
    public class RestMvcConfig {}
    

    ===

    我将我所有的 html 文件或 thymeleaf 模板移动到 src/main/resources 下的模板文件夹。同样在同一个文件夹中,您可以将所有客户端资源(如图像、js 和 css)放在静态文件夹下。文件夹 static 和 templates 是关键字,Spring-Boot 会自动找到。 application.properties 中没有 thymeleaf 和 apache 瓦片所需的特殊配置。

    ====

    如果您的应用程序能够找到资源,您可以配置如下路径:

    <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}" />
    

    ===

    文件夹java/src/webapp 不再需要!!!

    ====

    如果这对您有帮助,请不要犹豫投票 ;-)。如果您需要更多信息,请发表评论,我会在几天内尝试回答。

    ======

    第二步

    好的,直到现在它只在 Eclipse 下工作。当我执行可执行 jar 时,仍然出现错误。也许有人想帮忙;-)

    堆栈跟踪是:

    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)
    

    我的 JAR 的结构是这样的:

    ======

    解决方案:

    我不知道确切原因,但另外我必须修复我的模板的 url 路径,就像在 Eclipse 中一样,但不是作为可执行 jar。为了让它在两种环境中运行,我必须修复所有模板 url,如下所示,对属性值进行特殊查看

    之前:

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

    之后:

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

    最后它可以在 Eclipse 下作为可执行的 jars 运行。从普通的 Spring-Project 转换为 Spring-Boot 项目并不是很容易运行,我希望它对其他开发人员有所帮助,我希望这篇文章值得投票。 ;-)

    【讨论】:

    • 参加,以上帖子已修改更正
    【解决方案2】:

    这个例子演示了如何使用 Apache tile 配置 Thymeleaf,但是它让 spring boot 自动配置 Thymeleaf。这样,您仍然可以在 application.properties 中使用所有 spring-boot 预定义的环境变量,例如 spring.thymeleaf.*

    @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

    【讨论】:

      猜你喜欢
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      相关资源
      最近更新 更多