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进行了自动配置,如下:

SpringBoot16-springboot的Web开发-Spring Boot的Thymeleaf支持_第1张图片


     通过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 templateResolvers;
        private final Collection dialects;

        public ThymeleafDefaultConfiguration(Collection templateResolvers, ObjectProvider> 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,代码如下:



	4.0.0

	com.jack
	springboot2web
	0.0.1-SNAPSHOT
	jar

	springboot2web
	Demo project for Spring Boot

	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.6.RELEASE
		 
	

	
		UTF-8
		UTF-8
		1.8
	

	
		
		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
			1.5.6.RELEASE
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	





上面主要添加了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,如下:

 SpringBoot16-springboot的Web开发-Spring Boot的Thymeleaf支持_第2张图片



4,演示页面

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




    
    
    
    
    Thymeleaf



访问model

列表


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 people = new ArrayList();
        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,效果如图所示:

SpringBoot16-springboot的Web开发-Spring Boot的Thymeleaf支持_第3张图片

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

SpringBoot16-springboot的Web开发-Spring Boot的Thymeleaf支持_第4张图片




你可能感兴趣的:(spring,boot)