SpringBoot_web开发-webjars&静态资源映射规则

现在要做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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值