一.Web静态资源处理
1. 默认静态资源访问路径
打开IDEA,新建一个SpringBoot项目,导入Web依赖,删除没有必要部分创建之后的项目结构如下:
在SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfiguration 这个配置类里面,我们看看这个配置的源代码,键盘按下ctrl+shift+T,输入WebMvcAutoConfiguration
在这个类中有一个addResourceHandlers方法中文意思就是添加资源处理集,具体如下:
先看第一行if语句代码,如果isAddMappings为false,就进入if语句中执行debug打印 "Default resource handling disabled"
,然后return。
将鼠标放在isAddMappings()方法上按ctrl+鼠标左键,跳转到该方法源码:
(从源码可知isAddMappings()方法其实就是返回一个addMappings变量,并且该变量存放在WebProperties类中)
在WebProperties类中100行,从addMappings上面的注释我们可知该变量的含义就是是否启用默认资源处理,默认true(是),如果没有启用就不执行下面的代码,意思就是不添加任何外部资源映射!
在88~95行位置,我们可以发现staticLocations这个就是静态资源的位置集合,初始值为CLASSPATH_RESOURCE_LOCATIONS
CLASSPATH_RESOURCE_LOCATIONS就是默认的静态资源地址(Locations of static resources. Defaults to classpath:[/META-INF/resources/, /resources/, /static/, /public/].
),默认地址如下:
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
我们在resources文件中分别创建/META-INF/resources/,resources和public文件(static已经有了就无需再创建),并分别在各个文件中创建一个index.html文件。
/META-INF/resources/中的index.html:
resources中的index.html:
public中的index.html:
static中的index.html:
运行一下我们的Web程序(访问地址为:http://localhost:8089/index.html):备注:端口这里我设置的是8089
然后我们将/META-INF/resources/中的index.html删掉,再次运行:
我们再将resources中的index.html删除掉再次运行:
我们再将static中的index.html删除掉再次运行:
从上面的操作可知访问优先级分别为(从高到低):
- /META-INF/resources/
- /resources/
- /static/
- /public/
我们试试将addMappings设置为false,然后再次访问index.html(经过上面的操作仅有public文件中还有index.html):
在application.properties中设置addMappings为false
输入addmappings会有提示:
运行效果:
从上面我们的分析可知,debug会打印出 “Default resource handling disabled”
信息,由于控制台输出的信息实在太多,这里我将控制台的信息复制到Word中通过按F5进行查找,确实如我们分析那样,addMappings=false的话就会debug打印 “Default resource handling disabled”
,然后return,就不再执行后面的代码(addResourceHandler()添加外部资源的映射的方法)!。
备注:打印debug信息只需要在resources中新建一个logback.xml(文件名不要错了)
logback.xml配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="3 seconds">
<!--设置日志输出为控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%logger{32}] %msg%n</pattern>
</encoder>
</appender>
<!--设置日志输出为文件-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>logFile.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>logFile.%d{yyyy-MM-dd_HH-mm}.log.zip</FileNamePattern>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss,SSS} [%thread] %-5level %logger{32} - %msg%n</Pattern>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
2. 第一种静态资源映射规则
分析完第一条之后我们再来分析下面这句代码:
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
从方法名我们可知是一个添加资源处理的方法,第二个参数pattern表示模式,/webjars/
,在百度上随便搜索了一下,Webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可
。
在使用SpringBoot需要使用Webjars,我们可以去官网搜索我们需要的Webjars:
具体地址:Webjars官网
Build Tool这里有Maven,我们选择Maven:
假设这里我们需要一个JQuery,我们在搜索搜索一下jquery,复制对应的Maven配置到pom.xml中去
加载一下!,该jar就被我们下载下来了!
第三个参数locations表示为地址集合(classpath:/META-INF/resources/webjars/
),我们试试访问该地址下的bower.json看看是否可以访问,地址对应路径为下面红框框部分:
这里我们只需要在路径后面加上 /webjars/jquery/3.6.0/bower.json
,就可以访问到该文件。
(注意: #spring.web.resources.add-mappings=false
一定要注释掉,不然是无法访问的!)
运行效果:
3. 第二种静态资源映射规则
最后一种添加资源处理方法,看到该方法我们可以发现第二个参数 this.mvcProperties.getStaticPathPattern()
,从方法名可知是一个静态资源的路径模式。
通过ctrl+鼠标左键,看看源码:
再进一步看看:
staticPathPattern用于静态资源的路径模式(Path pattern used for static resources.
),默认为 /**
,访问当前的项目任意资源。
我们再来看第三个参数有一个方法的参数为 this.resourceProperties.getStaticLocations()
,我们看看该方法的源码!
看到 staticLocations
,你一定会感觉很熟悉这不是前面分析的静态资源位置集合嘛,如果不在外部对该参数进行注入的话会采用默认的路径 CLASSPATH_RESOURCE_LOCATIONS
变量的集合路径。
4. 第三种自定义静态资源路径
分析到这里我们可以试想一下,在最开始访问index.html的时候, /**
表示访问项目中的所有(为 webjars
时表示 webjars
下的所有,然后对应的访问路径),第三个参数表示具体的访问路径,为了证明我们的猜想,我们在application.properties中添加 spring.web.resources.static-locations=classpath:/static/
配置,该配置表示只访问static路径下的静态资源,如果我们猜想正确的话,访问index.html会访问不到,因为index.html只在放在public文件下:
运行效果:
为了进一步验证,我们再在static目录下创建一个index.html,然后再次访问看看!
运行效果:
二.首页处理
在WebMvcAutoConfiguration类中,有一个welcomePageHandlerMapping方法该方法关于欢迎页(首页)的映射:
该方法中有一个getWelcomePage()方法,从方法名我们可知该方法是获取欢迎页面
跳转查看一下源码:
分析源码:先遍历 this.resourceProperties.getStaticLocations()
(静态资源的路径集合),然后根据路径获取 Resource indexHtml = getIndexHtml(location);
首页,如果返回indexHtml不为null就将首页返回, 如果为null(没有设置相应的首页),就获取ServletContext对象,如果该对象不为null通过该对象获取首页并返回,如果为null返回null。
getIndexHtml(location);
我们看看该方法的源码:
从上面的源码我们可知,判断一下在静态资源路径集合中是否包含index.html,如果有就当成首页放回。
在前面我们访问路径都在搜索栏后面加上index.html,从上面的分析我们可知,index.html其实就是我们的首页,我们可以直接通过网址 http://localhost:8089/
访问。
运行一下项目(确实如此):
三.网站图标
1.什么是网站图标
什么是网站图标,如下图红框框所示:
2.自定义网站图标
(1)首先先生成IOC图标(网站图标名为:favicon.ico)
在线工具
也可以将地址放在迅雷等相应下载器中进行下载!
(2) 将favicon.ico放在static文件下
(3) 关闭默认图标
在application.properties/yaml中修改 favicon.enabled=false
,有二种方式,第一种( spring.mvc.favicon.enabled=false
),第二种( spring.favicon.enabled = false
),我是第二种有效!
(4) 解决无法加载favicon.ico问题
- 项目生成后,观察target中static文件夹下是否生成了favicon.ico
- 清楚游览器缓存
这里我用的谷歌游览器,ctrl+shift+del键,点击清楚数据
- 重启游览器
- 在前端页面head标签中添加代码
方式一:
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="shortcut icon" href="/favicon.ico"/>
<link rel="bookmark" href="/favicon.ico"/>
</head>
方式二:
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="shortcut icon" th:href="@{/favicon.ico}"/>
<link rel="bookmark" th:href="@{/favicon.ico}"/>
</head>
运行效果: