SpringBoot从入门到放弃,第三章

编程

SpringBoot从入门到放弃,第三章

一、静态资源映射规则

在springBoot项目中,springmvc的相关配置都在WebMvcAutoConfiguration类中

public void addResourceHandlers(ResourceHandlerRegistry registry) {

if (!this.resourceProperties.isAddMappings()) {

logger.debug("Default resource handling disabled");

return;

}

Duration cachePeriod = this.resourceProperties.getCache().getPeriod();

CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();

//===========webjars访问===================

if (!registry.hasMappingForPattern("/webjars/**")) {

customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")

.addResourceLocations("classpath:/META-INF/resources/webjars/")

.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));

}

//===========静态资源访问================

String staticPathPattern = this.mvcProperties.getStaticPathPattern();

if (!registry.hasMappingForPattern(staticPathPattern)) {

customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)

.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))

.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));

}

}

//===========静态资源存放文件路径================

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",

"classpath:/resources/",

"classpath:/static/",

"classpath:/public/"

};

1、webjars访问

所有/webjars/ ,都去classpath:/META-INF/resources/webjars/找资源

​ webjars:以jar包的方式引入静态资源。官网

引入:

<dependency>

<groupId>org.webjars</groupId>

<artifactId>jquery</artifactId>

<version>3.4.1</version>

</dependency>

目录结构:

访问:

http://localhost:8080/webjars/jquery/3.4.1/jquery.js

2、静态资源访问

/**访问当前项目的任何资源,静态资源访问文件目录:

classpath:/META-INF/resources/,

classpath:/resources/,

classpath:/static/,

classpath:/public/

/

访问:

http://localhost:8080/abc

3、欢迎页index的映射

静态资源文件夹下所有index.html页面,被/**映射

访问:

http://localhost8080/index.html 或者 http://localhost8080/

@Bean

public WelcomePageHandlerMapping welcomePageHandlerMapping(...) {

WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(

new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),

this.mvcProperties.getStaticPathPattern());

welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));

return welcomePageHandlerMapping;

}

private Optional<Resource> getWelcomePage() {

String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());

return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();

}

4、favicon图标

@Configuration

@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)

public static class FaviconConfiguration {

private final ResourceProperties resourceProperties;

public FaviconConfiguration(ResourceProperties resourceProperties) {

this.resourceProperties = resourceProperties;

}

@Bean

public SimpleUrlHandlerMapping faviconHandlerMapping() {

SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();

mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);

//所有 **/favicon.ico

mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",

faviconRequestHandler()));

return mapping;

}

@Bean

public ResourceHttpRequestHandler faviconRequestHandler() {

ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();

requestHandler

.setLocations(this.resourceProperties.getFaviconLocations());

return requestHandler;

}

}

spring.mvc.favicon.enabled=true默认启用

存放位置:静态资源文件夹下

favicon.ico

5、静态资源参数设置

@ConfigurationProperties(prefix = "spring.resources")

public class ResourceProperties {

//可以设置和资源有关的参数,如缓存时间等

}

如果想改变静态资源文件夹的路径,修改yml:

spring.resources.static-locations=classpath:/hello,classpath:/mystatic

二、模板引擎thymeleaf

1、引入thymeleaf

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

切换thymeleaf版本(旧版本的springboot切换)

<properties>

<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>

<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>

</properties>

2、Thymeleaf使用语法

官网地址

springboot对thymeleaf的自动配置文件

表示:只要我们把HTML页面放在classpath:/templates/下,就可以自动渲染了

@ConfigurationProperties(prefix = "spring.thymeleaf")

public class ThymeleafProperties {

private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

//表示:只要我们把HTML页面放在classpath:/templates/下,就可以自动渲染了

public static final String DEFAULT_PREFIX = "classpath:/templates/";

public static final String DEFAULT_SUFFIX = ".html";

}

2.1)、application.yml配置

###ThymeLeaf配置

spring:

thymeleaf:

#模板的模式,支持 HTML, XML TEXT JAVASCRIPT

mode: HTML5

#编码 可不用配置

encoding: UTF-8

#内容类别,可不用配置

content-type: text/html

#开发配置为false,避免修改模板还要重启服务器

cache: false

#配置模板路径,默认是templates,可以不用配置

prefix: classpath:/templates

##实际项目中可能会有不太严格的HTML格式,此时设置mode=HTML5将会对非严格的报错,可以参考以下配置:

spring.thymeleaf.mode=LEGACYHTML5

##你可能会发现在默认配置下,thymeleaf对.html的内容要求很严格,比如<meta charset="UTF-8" />,

##如果少最后的标签封闭符号/,就会报错而转到错误页。

#因此,建议增加下面这段:

spring.thymeleaf.mode = LEGACYHTML5

##spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好

##亲切的格式要求。

##需要注意的是,LEGACYHTML5需要搭配一个额外的库NekoHTML才可用。

<dependency>

<groupId>net.sourceforge.nekohtml</groupId>

<artifactId>nekohtml</artifactId>

<version>1.9.22</version>

</dependency>

常见的一些可以被修改的配置:

# THYMELEAF (ThymeleafAutoConfiguration)

spring.thymeleaf.cache=true

spring.thymeleaf.check-template=true

spring.thymeleaf.check-template-location=true

spring.thymeleaf.enabled=true

spring.thymeleaf.enable-spring-el-compiler=false

spring.thymeleaf.encoding=UTF-8

spring.thymeleaf.excluded-view-names=

spring.thymeleaf.mode=HTML

spring.thymeleaf.prefix=classpath:/templates/

spring.thymeleaf.reactive.chunked-mode-view-names=

spring.thymeleaf.reactive.full-mode-view-names=

spring.thymeleaf.reactive.media-types=

spring.thymeleaf.suffix=.html

spring.thymeleaf.template-resolver-order=

spring.thymeleaf.view-names=

2.2)、导入thymeleaf的名称空间

<html xmlns:th="http://www.thymeleaf.org">

2.3)、语法

文本内容(覆盖):<div th:text="${hello}">默认文本内容</div>

替换原生属性值:<div id="aa" class="bb" th:id="#{cc}" th:class="${dd}"></div>

①、 赋值、字符串拼接

+:字符串拼接字体串

简化字符中拼接操作:(使用”|”包围字符串,不需要对字符串使用”’”)

<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />

<span th:text=""The name of the user is " + ${user.name}" ></span>

<span th:text=""The name of the user is " + ${user.name} + "_" + ${user.age}"> </span>

<span th:text="|Welcome to our application, ${user.name}!|"></span>

等价于

<span th:text=""Welcome to our application, " + ${user.name} + "!"">

②、数字输出和计算

<span th:text="2013">1492</span>

<span th:text="2013 + 2">1494</span>

<span th:if="${user.isAdmin()} == false"> false </span>

<span th:if="${user.other} == null"> null</span>

③、算术表达式

*二进制运算 +, -, , /, %

布尔表达式 true, false, !, not

以及 and, or

<span th:text="${user.age} % 2 == 0"> </span>			结果:true

<span th:text="true"> </span> 结果:true

<span th:text="!(${user.age} % 2 == 0)"> </span> 结果:false

<span th:text="(${user.age} % 2 == 0) and true"> </span>结果:true

④、比较操作符

比较 >, <, >=, <= (gt, lt, ge, le)

判断 ==, != (eq, ne)

<span th:if="${user.age} &gt; 18"> 大人 </span>

<span th:if="${user.age} != 18"> 大人_no_equality </span>

⑤、条件操作符

If-then: (if) ? (then)

If-then-else: (if) ? (then) : (else)

<span th:text="${user.age}%2 == 0 ? "even""> </span>

<span th:text="${user.age}%2 == 0 ? "even" : "odd""> </span>

<span th:if="${member.age lt 18}">

未成年人!

</span>

<span th:if="${member.name eq "啊三"}">

欢迎小三来访问!

</span>

##不满足判断条件

<span th:unless="${member.age gt 18}">

你还不满18岁,不能够看电影!

</span>

##switch分支判断

<span th:switch="${member.uid}">

<p th:case="100"> uid为101的员工来了 </p>

<p th:case="99"> uid为102的员工来了 </p>

<p th:case="*"> 没有匹配成功的数据! </p>

</span>

⑥、调用对象的成员变量的属性

<input type="text" name="userName" th:value="${family.father.name}" />

⑦、调用map对象的属性

通过map的key从hashMap获取对象的属性name值: 可以使用”.”或者使用”[]”获取对象值

<input type="text" name="userName" th:value="${hashMap.hashMapKey.name}" />

等价于

<input type="text" name="userName" th:value="${hashMap["hashMapKey"].name}" />

⑧、调用list对象的属性

<input type="text" name="userName" th:value="${family.childList[0].name}" />

⑨、调用属性的方法

<input type="text" name="userName" th:value="${family.father.name.toUpperCase()}" />

⑩、获取原生对象

<p th:text="${#httpServletRequest.getRemoteAddr()}"/>

<p th:text="${#httpServletRequest.getAttribute("requestMessage")}"/>

<p th:text="${#httpSession.getId()}"/>

<p th:text="${#httpServletRequest.getServletContext().getRealPath("/")}"/>

⑪、生成URL地址@{}

th:href生成的值替换的href值 @{}

url中加入变量值(orderId=${id})做为url的请求参数

<!-- th:href生成的值替换<a>的href值; (orderId=${id})做为url的请求参数 -->

<a th:href="@{http://localhost:8080/order/details(orderId=${id})}">view</a>

结果:

<a href="http://localhost:8080/order/details?orderId=123">view</a>

<!-- 生成:/order/details?orderId=123 -->

<a th:href="@{/order/details(orderId=${id})}">view</a>

结果:

<a href="/order/details?orderId=123">view</a>

<!-- 替换url中变量值,生成/order/123/details -->

<a th:href="@{/order/{orderId}/details(orderId=${id})}">view</a>

结果:

<a href="/order/123/details">view</a>

⑫、表达式工具对象

<body>

<p th:text="${#dates.format(mydate,"yyyy-MM-dd")}"/>

<p th:text="${#dates.format(mydate,"yyyy-MM-dd HH:mm:ss.SSS")}"/>

<hr/>

<p th:text="${#strings.replace("www.baidu.cn",".","$")}"/>

<p th:text="${#strings.toUpperCase("www.baidu.cn")}"/>

<p th:text="${#strings.trim("www.baidu.cn")}"/>

<hr/>

<p th:text="${#sets.contains(names,"boot-0")}"/>

<p th:text="${#sets.contains(names,"boot-9")}"/>

<p th:text="${#sets.size(names)}"/>

<hr/>

<p th:text="${#sets.contains(ids,0)}"/>

<p th:text="${ids[1]}"/>

<p th:text="${names[1]}"/>

</body>

⑬、迭代

<!-- 常用的迭代 th:each 用法 -->

<tr th:each="user : ${userList}">

<td th:text="${user.name}"></td>

<td th:text="${user.age}"></td>

<td th:text="${user.isAdmin}"></td>

</tr>

##获取迭代的中间的状态,定义在iterStat中

index :当前节点的索引,从0开始

size : 迭代节点总数

even/odd:当前是偶数/奇数行,boolean值

first/last:当前是每天/最后一个元素

<!-- 获取迭代的中间的状态,定义在iterStat中-->

<tr th:each="user,iterStat : ${userList}">

<!-- index: 当前迭代的索引 -->

<td th:text="${iterStat.index }"></td>

<!-- first: 当前元素是第一个元素; last: 当前元素是最后个元素 -->

<td th:text="${iterStat.first } ? "第一个元素":(${iterStat.last} ? "最后一个元素":"")" ></td>

<!-- -->

<td th:text="${iterStat.odd} ? "odd" : "even"" ></td>

<td th:text="${user.name}"></td>

<td th:text="${user.age}"></td>

<td th:text="${user.isAdmin}"></td>

</tr>

⑭、条件语法

**th:if th:unless **

<!-- th:if:如果值是true,则打印<span>整个节点  -->

<span th:if="${user.isAdmin}" th:text="${user.name} + "是管理员""> </span>

<!-- th:unless: 和th:if是相反功能,如果值为false,则打印<span>整个节点 -->

<span th:unless="not ${user.isAdmin}" th:text="${user.name} + "是管理员""> </span>

<!-- th:switch / th:case -->

<div th:switch="${user.name}">

<p th:case=""admin"">User is an administrator</p>

<!-- *: case的默认的选项 -->

<p th:case="*">User is some other thing</p>

</div>

⑮、模板template

在web开发中,我们经常会将公共头,公共尾,菜单等部分提取成模板供其它页面使用。在thymeleaf中,通过th:fragment、th:include、th:replace、参数化模板配置、css选择器加载代码块等实现。

公共页 /templates/template/footer.html

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<meta charset="UTF-8" />

<body>

<!-- th:fragment 定义用于加载的块 -->

<span th:fragment="copy"> 2017 hry loaded by fragment=copy</span>

<span id="copy-section"> 2017 hry loaded by id=copy-section</span>

<!-- 定义模板时,可以传入参数 -->

<span th:fragment="frag(month, date) ">

<span th:text=""welcome hry come in " + ${month} + "-" + ${date}"></span>

</span>

</body>

</html>

通过th:include在本页中加载以上的代码块copy :

templatename::selector:”::”前面是模板文件名,后面是选择器

::selector:只写选择器,这里指fragment名称,则加载本页面对应的fragment

templatename:只写模板文件名,则加载整个页面

<!--  语法说明  "::"前面是模板文件名,后面是选择器 -->

<div th:include="template/footer::copy"></div>

<!-- 只写选择器,这里指fragment名称,则加载本页面对应的fragment -->

<div th:include="::#thispage"></div>

<!-- 只写模板文件名,则加载整个页面 -->

<div th:include="template/footer"></div>

<!--本页面的加载块-->

<span id="thispage">

div in this page.

</span>

通过th:fragment和css选择器加载代码块

<!-- 这里加载”th:fragment 定义用于加载的块“ -->

<div th:include="template/footer::copy"></div>

<!-- 这里加载”id=copy-section“的节点 -->

<div th:include="template/footer::#copy-section"></div>

th:include 和 th:replace

## th:include:加载模板的内容: 读取加载节点的内容(不含节点名称),替换div内容

## th:replace:替换当前标签为模板中的标签,加载的节点会整个替换掉加载他的div

<!-- 加载模板的内容: 读取加载节点的内容(不含节点名称),替换<div>的内容 -->

<div th:include="template/footer::copy">1</div>

结果:

<div> 2017 hry loaded by fragment=copy</div>

<!-- 替换当前标签为模板中的标签: 加载的节点会整个替换掉加载他的<div> -->

<div th:replace="template/footer::copy">2</div>

结果:

<span> 2017 hry loaded by fragment=copy</span>

调用模板时传递参数

<div th:include="template/footer::frag(${month},${date})">...</div>

以上是 SpringBoot从入门到放弃,第三章 的全部内容, 来源链接: utcz.com/z/510739.html

回到顶部