SpringBoot16-springboot的Web开发-Spring Boot的Thymeleaf支持

    Spring Boot提供了大量的模板引擎,包含了FreeMarker,Groovy,Thymeleaf,Velocity和Mustache,Spring Boot中推荐使用Thymeleaf作为模板引擎,因为Thymeleaf提供了完美的Spring MVC的支持。

    Thymeleaf是一个java类库,它是一个xml/xhtml/html5的模板引擎,可以作为MVC的Web应用的View层。

    Thymeleaf还提供了额外的模块与Spring MVC集成,所以我们可以使用Thymeleaf完全替代JSP。

     在Spring Boot中集成Thymeleaf是通过org.springframework.boot.autoconfigure.thymeleaf包对Thymeleaf进行了自动配置,如下:



     通过ThymeleafAutoConfiguration类对集成所需的Bean进行自动配置,包括了templateResolver,templateEngine和thymeleafViewResolver的配置,源代码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.thymeleaf;

import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDialect;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.Servlet;
import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.extras.conditionalcomments.dialect.ConditionalCommentsDialect;
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.resourceresolver.SpringResourceResourceResolver;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;

@Configuration
@EnableConfigurationProperties({ThymeleafProperties.class})
@ConditionalOnClass({SpringTemplateEngine.class})
@AutoConfigureAfter({WebMvcAutoConfiguration.class})
public class ThymeleafAutoConfiguration {
    public ThymeleafAutoConfiguration() {
    }

    @Configuration
    @ConditionalOnWebApplication
    protected static class ThymeleafResourceHandlingConfig {
        protected ThymeleafResourceHandlingConfig() {
        }

        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledResourceChain
        public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
            return new ResourceUrlEncodingFilter();
        }
    }

    @Configuration
    @ConditionalOnJava(JavaVersion.EIGHT)
    @ConditionalOnClass({Java8TimeDialect.class})
    protected static class ThymeleafJava8TimeDialect {
        protected ThymeleafJava8TimeDialect() {
        }

        @Bean
        @ConditionalOnMissingBean
        public Java8TimeDialect java8TimeDialect() {
            return new Java8TimeDialect();
        }
    }

    @Configuration
    @ConditionalOnClass({SpringSecurityDialect.class})
    protected static class ThymeleafSecurityDialectConfiguration {
        protected ThymeleafSecurityDialectConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public SpringSecurityDialect securityDialect() {
            return new SpringSecurityDialect();
        }
    }

    @Configuration
    @ConditionalOnClass({DataAttributeDialect.class})
    protected static class DataAttributeDialectConfiguration {
        protected DataAttributeDialectConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public DataAttributeDialect dialect() {
            return new DataAttributeDialect();
        }
    }

    @Configuration
    @ConditionalOnClass(
        name = {"nz.net.ultraq.thymeleaf.LayoutDialect"}
    )
    protected static class ThymeleafWebLayoutConfiguration {
        protected ThymeleafWebLayoutConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public LayoutDialect layoutDialect() {
            return new LayoutDialect();
        }
    }

    @Configuration
    @ConditionalOnMissingBean({SpringTemplateEngine.class})
    protected static class ThymeleafDefaultConfiguration {
        private final Collection<ITemplateResolver> templateResolvers;
        private final Collection<IDialect> dialects;

        public ThymeleafDefaultConfiguration(Collection<ITemplateResolver> templateResolvers, ObjectProvider<Collection<IDialect>> dialectsProvider) {
            this.templateResolvers = templateResolvers;
            this.dialects = (Collection)dialectsProvider.getIfAvailable();
        }

        @Bean
        public SpringTemplateEngine templateEngine() {
            SpringTemplateEngine engine = new SpringTemplateEngine();
            Iterator var2 = this.templateResolvers.iterator();

            while(var2.hasNext()) {
                ITemplateResolver templateResolver = (ITemplateResolver)var2.next();
                engine.addTemplateResolver(templateResolver);
            }

            if (!CollectionUtils.isEmpty(this.dialects)) {
                var2 = this.dialects.iterator();

                while(var2.hasNext()) {
                    IDialect dialect = (IDialect)var2.next();
                    engine.addDialect(dialect);
                }
            }

            return engine;
        }
    }

    @Configuration
    @ConditionalOnClass(
        name = {"org.thymeleaf.templatemode.TemplateMode"}
    )
    static class Thymeleaf3Configuration {
        Thymeleaf3Configuration() {
        }

        @Configuration
        @ConditionalOnClass({Servlet.class})
        @ConditionalOnWebApplication
        static class Thymeleaf3ViewResolverConfiguration extends AbstractThymeleafViewResolverConfiguration {
            Thymeleaf3ViewResolverConfiguration(ThymeleafProperties properties, SpringTemplateEngine templateEngine) {
                super(properties, templateEngine);
            }

            protected void configureTemplateEngine(ThymeleafViewResolver resolver, SpringTemplateEngine templateEngine) {
                Method setTemplateEngine;
                try {
                    setTemplateEngine = ReflectionUtils.findMethod(resolver.getClass(), "setTemplateEngine", new Class[]{Class.forName("org.thymeleaf.ITemplateEngine", true, resolver.getClass().getClassLoader())});
                } catch (ClassNotFoundException var5) {
                    throw new IllegalStateException(var5);
                }

                ReflectionUtils.invokeMethod(setTemplateEngine, resolver, new Object[]{templateEngine});
            }
        }

        @Configuration
        @ConditionalOnMissingBean(
            name = {"defaultTemplateResolver"}
        )
        static class DefaultTemplateResolverConfiguration extends AbstractTemplateResolverConfiguration {
            DefaultTemplateResolverConfiguration(ThymeleafProperties properties, ApplicationContext applicationContext) {
                super(properties, applicationContext);
            }

            @Bean
            public SpringResourceTemplateResolver defaultTemplateResolver() {
                SpringResourceTemplateResolver resolver = super.defaultTemplateResolver();
                Method setCheckExistence = ReflectionUtils.findMethod(resolver.getClass(), "setCheckExistence", new Class[]{Boolean.TYPE});
                ReflectionUtils.invokeMethod(setCheckExistence, resolver, new Object[]{this.getProperties().isCheckTemplate()});
                return resolver;
            }
        }
    }

    @Configuration
    @ConditionalOnMissingClass({"org.thymeleaf.templatemode.TemplateMode"})
    static class Thymeleaf2Configuration {
        Thymeleaf2Configuration() {
        }

        @Configuration
        @ConditionalOnClass({ConditionalCommentsDialect.class})
        static class ThymeleafConditionalCommentsDialectConfiguration {
            ThymeleafConditionalCommentsDialectConfiguration() {
            }

            @Bean
            @ConditionalOnMissingBean
            public ConditionalCommentsDialect conditionalCommentsDialect() {
                return new ConditionalCommentsDialect();
            }
        }

        @Configuration
        @ConditionalOnClass({Servlet.class})
        @ConditionalOnWebApplication
        static class Thymeleaf2ViewResolverConfiguration extends AbstractThymeleafViewResolverConfiguration {
            Thymeleaf2ViewResolverConfiguration(ThymeleafProperties properties, SpringTemplateEngine templateEngine) {
                super(properties, templateEngine);
            }

            protected void configureTemplateEngine(ThymeleafViewResolver resolver, SpringTemplateEngine templateEngine) {
                resolver.setTemplateEngine(templateEngine);
            }
        }

        @Configuration
        @ConditionalOnMissingBean(
            name = {"defaultTemplateResolver"}
        )
        static class DefaultTemplateResolverConfiguration extends AbstractTemplateResolverConfiguration {
            DefaultTemplateResolverConfiguration(ThymeleafProperties properties, ApplicationContext applicationContext) {
                super(properties, applicationContext);
            }

            @Bean
            public SpringResourceResourceResolver thymeleafResourceResolver() {
                return new SpringResourceResourceResolver();
            }
        }
    }
}


   通过ThymeleafProperties来配置Thymeleaf,在application.yml中以spring.thymeleaf开头来配置,通过查看ThymeleafProperties的主要源代码,我们可以看出如何设置属性以及默认配置:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.thymeleaf;

import java.nio.charset.Charset;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.MimeType;

@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");
    private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML5";
    private Charset encoding;
    private MimeType contentType;
    private boolean cache;
    private Integer templateResolverOrder;
    private String[] viewNames;
    private String[] excludedViewNames;
    private boolean enabled;

    public ThymeleafProperties() {
        this.encoding = DEFAULT_ENCODING;
        this.contentType = DEFAULT_CONTENT_TYPE;
        this.cache = true;
        this.enabled = true;
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public boolean isCheckTemplate() {
        return this.checkTemplate;
    }

    public void setCheckTemplate(boolean checkTemplate) {
        this.checkTemplate = checkTemplate;
    }

    public boolean isCheckTemplateLocation() {
        return this.checkTemplateLocation;
    }

    public void setCheckTemplateLocation(boolean checkTemplateLocation) {
        this.checkTemplateLocation = checkTemplateLocation;
    }

    public String getPrefix() {
        return this.prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return this.suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

    public String getMode() {
        return this.mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }

    public Charset getEncoding() {
        return this.encoding;
    }

    public void setEncoding(Charset encoding) {
        this.encoding = encoding;
    }

    public MimeType getContentType() {
        return this.contentType;
    }

    public void setContentType(MimeType contentType) {
        this.contentType = contentType;
    }

    public boolean isCache() {
        return this.cache;
    }

    public void setCache(boolean cache) {
        this.cache = cache;
    }

    public Integer getTemplateResolverOrder() {
        return this.templateResolverOrder;
    }

    public void setTemplateResolverOrder(Integer templateResolverOrder) {
        this.templateResolverOrder = templateResolverOrder;
    }

    public String[] getExcludedViewNames() {
        return this.excludedViewNames;
    }

    public void setExcludedViewNames(String[] excludedViewNames) {
        this.excludedViewNames = excludedViewNames;
    }

    public String[] getViewNames() {
        return this.viewNames;
    }

    public void setViewNames(String[] viewNames) {
        this.viewNames = viewNames;
    }
}


实战:

1,新建一个spring boot项目,修改pom.xml,代码如下:

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

	<groupId>com.jack</groupId>
	<artifactId>springboot2web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springboot2web</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!--<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>-->
		<!--thymeleaf依赖-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
			<version>1.5.6.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>


上面主要添加了thymeleaf的依赖,然后会自动包含spring-boot-starter-web的依赖


2,示例java bean

  此类用来在模板页面展示数据用,包含name属性和age属性:

package com.jack.web.pojo;

/**
 * 人的java bean
 */
public class Person {
    private String name;
    private Integer age;

    public Person() {
        super();
    }

    public Person(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}



3,脚本样式静态文件

   根据默认原则,脚本样式,图片等静态文件应放置在src/main/resources/static下,这里引入了Bootstrap和jQuery,如下:

 



4,演示页面

    根据默认原则,页面应该放置在src/main/resources/templates下。在src/main/resources/templates下新建index.html,代码如下:

<!DOCTYPE html>
<html   xmlns="http://www.w3.org/1999/xhtml"
        xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1"/>
    <link th:href="@{bootstrap/css/bootstrap.min.css}" rel="stylesheet"/>
    <link th:href="@{bootstrap/css/bootstrap-theme.min.css}" rel="stylesheet"/>
    <title>Thymeleaf</title>
</head>
<body>

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">访问model</h3>
    </div>
    <div class="panel-body">
        <span th:text="${singlePerson.name}"></span>
    </div>
</div>

<div th:if="${not #lists.isEmpty(people)}">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">列表</h3>
        </div>
        <div class="panel-body">
            <ul class="list-group">
                <li class="list-group-item" th:each="person:${people}">
                    <span th:text="${person.name}"></span>
                    <span th:text="${person.age}"></span>
                    <button class="btn" th:οnclick="'getName(\''+${person.name}+'\');'">获得名字</button>
                </li>
            </ul>
        </div>
    </div>
</div>

<script th:src="@{jquery-3.2.1.min.js}" type="text/javascript"/>
<script th:src="@{bootstrap/bootstrap.min.js}"></script>
<script th:inline="javascript">
    var single = [[${singlePerson}]];
    console.log(single.name+"/"+single.age);
    function getName(name) {
        console.log(name);
    }
</script>
</body>
</html>

5,编写一个controller,准备数据

package com.jack.web.controller;

import com.jack.web.pojo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
public class ThymeleafController {
    @RequestMapping("/thymeleaf")
    public String index(Model model){
        Person single = new Person("jack", 11);
        List<Person> people = new ArrayList<Person>();
        Person p1 = new Person("xx", 12);
        Person p2 = new Person("yy", 13);
        Person p3 = new Person("zz", 14);
        people.add(p1);
        people.add(p2);
        people.add(p3);
        model.addAttribute("singlePerson",single);
        model.addAttribute("people",people);
        return "index";
    }
}



6,修改application.yml

server:
  port: 9090


7,运行

   在浏览器输入http://localhost:9090/thymeleaf,效果如图所示:


单击“获得名字”选项,效果如图所示:





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值