现在要做WEB功能,还是选择WEB模块,pom文件依赖web模块,
<dependency>
<!-- 引入web模块 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
resources配置文件,现在我先来写上一个HelloWorld
页面来发hello请求,返回一个helloworld字符串,我们来体验一下web的快速开发,有了springboot以后,
我就选完模块以后,我们是不是什么都没配,我们就直接来写就行了,我们来处理hello请求,只是HelloWorld要
写出去要加上@ResponseBody,以前的MVC都不用配了,直接来用,来测试一下这个Hello,看能不能访问,他这里说
服务器8080端口已经启动,我们来访问一下
http://localhost:8080/hello
HelloWorld没问题
package com.learn.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello() {
return "hello";
}
}
package com.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @SpringBootApplication 来标注一个主程序类,说明这是一个Sprint Boot应用
* @author Leon.Sun
*
*/
//@ImportResource(locations= {"classpath:beans.xml"})
@SpringBootApplication
public class SpringBoot02ConfigApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(SpringBoot02ConfigApplication.class,args);
}
}
直接就用就行了,接下来我们来做我们这个实验,如果我们现在是一个WEB应用,那我们main下会有一个webapp文件夹,
那我们将所有的页面,全都是导在这的,大家来看,现我们的pom是打成jar的方式,能不能给我们写页面,这也是可以的,
只不过我们的CSS文件要放哪,我们SpringBoot有规定,SpringBoot对静态资源的映射规则,这映射规则我们首先来看,
第一种规则,在咱们SpringBoot里面呢,SpringMVC的相关配置,都在WebMvcAutoConfiguration里边,而这个配置里边呢,
我们来从头往下看,多的东西我们就不看了,下边有一个addResourceHandlers
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}
}
添加资源映射,我们后来还会用到这个原理,用到的时候再来仔细讲这个原理,只不过我们来看这个关键字,
添加咱们的资源映射,第一个规则"/webjars/**",所有"/webjars/"路径访问,访问都去哪找资源呢,这里有映射请求,
webjars下的所有请求,都去这一块来找资源,都去"classpath:/META-INF/resources/webjars/"这里找资源,而什么是
webjars呢,webjars简单来说,是以jar包的方式引入资源的,以前我们要导入jquery什么,那么我们有一个webapp的文件夹,
我们把页面,script src就能引了,但是现在我们有一个webjars,可以用jar包的方式,我们来搜索一下,
https://www.webjars.org
这个网站,就来参考他,将我们的前端框架,jquery,bootstrap,他们可以以maven依赖的方式,交给我们,这样我们要用的话就
简单多了,你在这就可以拿过来,我把jquery引进来
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
只要引入jquery的webjar,让他来自动下载,来看一下jquery的webjar长什么样呢,
D:\app\repository\org\webjars\jquery\3.3.1\jquery-3.3.1.jar
注意来看,这里有META-INF,有resources目录,下边有webjar,jquery,有些是目录合起来了,这个跟我们刚才说的映射规则
是一样的
这样的话正好对应这个映射,
localhost:8080/webjars/abc
webjars下的任意请求,这个资源去哪找呢,都去这个文件夹,META-INF,resources,webjars,我们webjars没有abc,
所以找不到,我们就要jquery
localhost:8080/webjars/jquery/3.3.1/jquery.js
jquery下的3.3.1,jquery.js,就是这个访问路径,我们试一下这个访问路径能不能访问到,我们把项目重启一下,
我来访问
http://localhost:8080/webjars/jquery/3.3.1/jquery.js
我们发现js是能访问的,以后我们用webjars,访问公用的样式,那就简单多了,你要做的就是引入依赖就行了,
我们在这引入依赖,我们boot都帮你设置好了,访问的时候只要写webjars资源的名字就行了,在访问的时候,只需要
写webjars下的资源即可,我们要用webjars我们就可以这样来用,但是如果是我们自己的呢,
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware, InitializingBean {
我们在设置项里边,主要有这么几个,一个是ResourceProperties,可以设置与资源有关的参数,主要是我们的静态资源,
例如我们的缓存时间,除了webjars,下边还有一个
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}
registry添加资源映射,
/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";
那就是第二种映射规则,你访问任何路径,访问当前项目的任何资源,
private static final String[] RESOURCE_LOCATIONS;
static {
RESOURCE_LOCATIONS = new String[CLASSPATH_RESOURCE_LOCATIONS.length
+ SERVLET_RESOURCE_LOCATIONS.length];
System.arraycopy(SERVLET_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, 0,
SERVLET_RESOURCE_LOCATIONS.length);
System.arraycopy(CLASSPATH_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS,
SERVLET_RESOURCE_LOCATIONS.length, CLASSPATH_RESOURCE_LOCATIONS.length);
}
静态代码块,new了一个数组,
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
他会去这几个文件夹下,一个是类路径下的resources,classpath:/META-INF/resources/,classpath:/static/,
还有当前项目的根路径,
private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };
这几个文件夹就称为静态资源,静态资源的文件夹,你把你的静态资源保存在这几个文件夹里面,都会来这几个文件夹里找内容
第一个是类路径下的META-INF,建立resources,resources是类路径的根目录,我在他的下边再创建一个resources,
第三个是建立static,第四个是public,这几个路径都可以来存放静态资源,访问是没问题的,我把他都放在
static目录下,要怎么访问呢,你来访问项目下的任何东西,
localhost:8080/abc
你要访问abc,如果没人处理,默认去这些路径下的静态资源,去静态资源文件夹里找abc,我们当然不访问abc,我来访问
一个能用的,这是静态资源文件夹,不用加静态资源文件夹的名,本来就从他下面找的,
localhost:8080/image/1.png
我们发现也是能访问的,所以这几个目录大家注意
在这个自动配置里边,
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ResourceProperties resourceProperties) {
return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
这里翻译过来叫做欢迎页的映射,欢迎页是什么呢,其实就是我们的首页,配置欢迎页映射,我们先不管HandlerMapping,
我们先来看一下它是怎么映射的呢,HandlerMapping其实是我们SpringMVC最底层的组件,他来保存每一个请求谁来处理,
getWelcomePage获取到欢迎页,
public Resource getWelcomePage() {
for (String location : getStaticWelcomePageLocations()) {
Resource resource = this.resourceLoader.getResource(location);
try {
if (resource.exists()) {
resource.getURL();
return resource;
}
}
catch (Exception ex) {
// Ignore
}
}
return null;
}
从getStaticWelcomePageLocations这里挨个遍历,因为欢迎页挺多的,
private String[] getStaticWelcomePageLocations() {
String[] result = new String[this.staticLocations.length];
for (int i = 0; i < result.length; i++) {
String location = this.staticLocations[i];
if (!location.endsWith("/")) {
location = location + "/";
}
result[i] = location + "index.html";
}
return result;
}
这还是静态文件夹staticLocations,这个静态文件夹拼了index.html,欢迎页它是怎么设置的呢,静态文件夹下的,
所有index.html页面,他这里还配了getStaticPathPattern,被谁映射,
/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";
不就是被"/**"映射,反过来就是说,我来访问当前项目,比如我来访问localhost,
localhost:8080/
我就访问当前项目,我没有指定路径,因为他也满足"/**",静态资源下的index.html,找index页面,那我们来试一下是不是这个
效果呢,默认我来访问8080,这是一个404,没有什么首页,我想要访问怎么访问呢,比如我把首页放在public文件夹下,我就来
放一个index.html,我们就来写一个首页,我来运行一下,默认首页就过来了,所以他做了首页映射
喜欢的图标是什么呢,配置喜欢的图标,
@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);
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这个配置
来启用,即使你不配他也是启用的,他怎么放呢,我们就看"**/favicon.ico"这个关键字,
List<Resource> getFaviconLocations() {
List<Resource> locations = new ArrayList<Resource>(
this.staticLocations.length + 1);
if (this.resourceLoader != null) {
for (String location : this.staticLocations) {
locations.add(this.resourceLoader.getResource(location));
}
}
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
我们喜欢的图标路径,还是静态文件夹staticLocations,所有的"**/favicon.ico"这个都是在静态文件夹下找,我们要做我们的图标了,
你不管是访问任意层路径下的他,图标都是在我们静态文件夹下找,我就把我们的图标我也拿来,你不管那个页面下要用这个图标,
都能在静态资源文件夹下找,图标就变过来了,这就是springboot默认的做的几个资源映射,主要是有这么几个静态资源文件夹,这几个
静态文件夹以后就来放东西就行了,而且它是能够配置的,我们一直用的是staticLocations,这个staticLocations呢,其实是
ResourceProperties下的注解,我们想改变静态文件夹下的路径,
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware, InitializingBean {
spring.resources.static-locations=classpath:/hello,classpath:/learn
我给他配置类路径下的hello文件夹,如果多个配置,我们就逗号分隔,因为这个东西是一个数组,数组我们用逗号分割就行了,learn文件夹,
这样你定义了几个文件夹,再来启动一下,你前面的静态资源还能不能访问呢,我们发现就不行了
localhost:8080/
因为我们自己定义了静态文件夹的文件,我就把它注释掉,我们就不定义了,这就是Springboot对静态资源的映射处理
#debug=true
#server.port=8081
#server.context-path=/boot02
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.level.com.learn=trace
#logging.file=D:/springboot.log
logging.file=springboot.log
#logging.path=/spring/log
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd} ==== [%thread] %-5level ==== %logger{50} ==== %msg%n
#spring.resources.static-locations=classpath:/hello,classpath:/learn