springboot系列--web相关知识探索一

devtools/2024/9/25 0:31:28/

一、web知识探索概述

一、探索大纲

 二、SpringMVC原理流程图

二、springmvc自动配置

springboot在底层自动帮我们配置好了mvc所需要的各个组件。当然,我们也可以自己定制化相关组件。

可参考官方文档:

 三、静态资源探究

一、静态资源存放位置

静态资源一般是存放在当前类路径下(classpath),在 Spring Boot 中既指程序在打包前的/java/目录加上/resource目录,也指程序在打包后生成的/classes/目录。两者实际上指的是同一个目录,里面包含的文件内容一模一样。

一、只要静态资源放在类路径下: /static(或 /public 或 /resources 或 /META-INF/resources )的目录

访问 : 当前项目根路径/ + 静态资源名  就能访问到对应路径下的静态资源。

二、原理:

当前项目根路径/ + 静态资源名,为什么就能访问到静态资源,springboot是怎么知道我们只要找静态资源,而不是找请求呢。

1、首相,可以准备一张叫做a.jpg的图片放置到/static路径下,然后再准备一个接口,请求路径就是当前项目根路径/ + a.jpg,然后请求当前项目根路径/ + a.jpg   这个路径会发现,这个时候返回的是a接口返回的数据。

2、原理就是,请求的时候资源默认映射到/**,也就是说请求根据当前项目根路径/,然后找这个路径下所有的接口,看看那个接口的路径是a.jpg的,看看Controller能不能处理,不能处理的话,就将所有请求又都交给静态资源处理器,静态资源处理器就会到指定路径下找一个叫 a.jpg的资源,如果静态资源也找不到则响应404页面。

二、改变默认的静态资源路径

一、静态资源访问前缀

默认情况下是无前缀的,如果需要改变,可以在yaml配置中加入:

spring:
  mvc:
    static-path-pattern: /res/**

二、改变资源存放位置

 静态资源默认是存放在/static(或 /public 或 /resources 或 /META-INF/resources )的目录下,我们也可以改变他的位置,这个时候就只能放在a这个目录下才能访问到了,放在其他位置上一律访问不到。如果想加入更多文件夹位置,只需要在数组中用逗号隔离就可以。

spring:

  resources:
    static-locations: [classpath:/a/]

三、webjars资源

一、什么是webjars

其实就是把js、css这些东西,弄成了一个jar包,导入到项目中使用。比如:在pom文件中导入对应的jqery文件jar包,就可以在项目中使用。

二、访问路径 

按照官方文档所说,如果需要访问对应的webjar中的资源,路径需要从/webjars/**开始,然后拼接上webjar下面的文件路径以及目标名,即http://localhost:8080/webjars/jquery/3.5.1/jquery.js

四、欢迎页支持

Spring Boot 支持静态和模板化的欢迎页面。它首先在配置的静态内容位置查找 index.html 文件。如果没有找到,它会寻找 index 模板(例如写一个能够处理index请求idea接口,最终跳回index页面)。如果找到任何一个,它会自动用作应用程序的欢迎页面。

访问项目根路径就可以访问到欢迎页。

一、静态资源路径下 index.html

   1、 可以配置静态资源路径,但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致welcome page功能失效

  resources:
    static-locations: [classpath:/haha/]

二、controller能处理/index

五、自定义Favicon 

favicon.ico 放在静态资源目录下即可。以后访问每个页面都会显示这个图标

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致 Favicon 功能失效

四、静态资源配置原理 

一、SpringBoot启动默认加载 META-INF/spring.factories 路径下的所有xxxAutoConfiguration 类(自动配置类),这个时候SpringMvc功能的自动配置类 WebMvcAutoConfiguration就被加载到容器中。

二、springboot加载了WebMvcAutoConfiguration后给容器中配置了那些组件,可参考WebMvcAutoConfiguration类。

一、OrderedHiddenHttpMethodFilter组件,主要是兼容rest风格请求

@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter",name = {"enabled"},matchIfMissing = false
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();
}

二、OrderedFormContentFilter组件,表达内容过滤器

@Bean
@ConditionalOnMissingBean({FormContentFilter.class})
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter",name = {"enabled"},matchIfMissing = true
)
public OrderedFormContentFilter formContentFilter() {return new OrderedFormContentFilter();
}

三、 WebMvcAutoConfigurationAdapter内部配置类。

一、@EnableConfigurationProperties注解在这个类的作用

在这个类上方有一个注解@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class}),说明这个配置文件的相关属性和这三个类进行了绑定,也就是说我们可以在yaml文件中配置绑定的数据,这个配置文件对应的组件就会产生不同的功能。

1、WebMvcProperties==spring.mvc

2、ResourceProperties==spring.resources

3、WebProperties==spring.web

二、有参构造器赋值 

这个WebMvcAutoConfigurationAdapter类只有一个有参构造器,也就是说这个类的成员属性都是通过这个有参构造器赋值的。 有参构造器所有参数的值都会从容器中找


//WebProperties webProperties;可以获取和spring.resources绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath  
//ServletRegistrationBean   给应用注册Servlet、Filter....public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {this.mvcProperties = mvcProperties;this.beanFactory = beanFactory;this.messageConvertersProvider = messageConvertersProvider;this.resourceHandlerRegistrationCustomizer = (ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.dispatcherServletPath = dispatcherServletPath;this.servletRegistrations = servletRegistrations;this.mvcProperties.checkConfiguration();}

 三、WebMvcAutoConfigurationAdapter内部配置类里面往容器中加入了视图解析器

@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix(this.mvcProperties.getView().getPrefix());resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;
}

四、EnableWebMvcConfiguration内部配置类

一、资源处理的默认规则

这个类绑定了@EnableConfigurationProperties({WebProperties.class}),其中成员属性通过有参构造方法进行复制,会在容器中找到对应类型的值。

// ResourceProperties 继承了WebProperties.Resources资源类        
public EnableWebMvcConfiguration(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, WebProperties webProperties, ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ListableBeanFactory beanFactory) {this.resourceProperties = (WebProperties.Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());this.mvcProperties = mvcProperties;this.webProperties = webProperties;this.mvcRegistrations = (WebMvcRegistrations)mvcRegistrationsProvider.getIfUnique();this.resourceHandlerRegistrationCustomizer = (ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.beanFactory = beanFactory;}

 静态资源处理规则主要是这个方法:

        protected void addResourceHandlers(ResourceHandlerRegistry registry) {super.addResourceHandlers(registry);// 如果addMappings为false,则禁用了静态资源,默认为true,else才是静态资源请求规则if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");} else {ServletContext servletContext = this.getServletContext();// 这个方法是先从缓存中获取webjars,单位为秒,并且注册一下路径作为访问规则,这个只是webjar的规则this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");// 这个是先从缓存中获取静态资源,并且注册一下路径作为访问规则,若没有再yaml中配置默认是/**,例如localhost:80/a.jpg,就会默认在指定路径下查找,代码有设置默认值,这里就不放了。如果再yaml文件中配置了,就会按照配置的路劲来。this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {registration.addResourceLocations(this.resourceProperties.getStaticLocations());if (servletContext != null) {// 这里是如果有在yaml文件中配置,static-path-pattern属性,就会按照配置上的来。registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});}});}}

spring:

  resources:
    add-mappings: false   禁用所有静态资源规则

默认静态资源访问路径

二、欢迎页规则

当前类下会由一个方法注入欢迎页配置规则。请求进来会经过前端控制器,然后前端控制器就会去请求处理器映射器,通过处理器映射器找到能够处理的handle,然后通过反射去调用。而欢迎页的处理则是在处理器映射器这一步做了业务处理。

        @Beanpublic WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {// 主要规则在这个有参构造方法里面,this.getWelcomePage()这个路径和静态资源路径,系统给以同一个默认路径。this.mvcProperties.getStaticPathPattern()这个默认是/**WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());return welcomePageHandlerMapping;}
    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {// 如果欢迎页不为空,同时请求路径符合/** (指的就是项目根路径/index.html,其中index.html指的就是欢迎页,项目根路径指的就是localhost:80,或者是域名),这个时候就能访问到欢迎页,也就是说如果yaml配置了static-path-pattern: /res/**就无法访问到欢迎页if (welcomePage != null && "/**".equals(staticPathPattern)) {logger.info("Adding welcome page: " + welcomePage);this.setRootViewName("forward:index.html");} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {// 如果只有欢迎页,但是请求路径不符和,则会去调用Controller找到/index结尾的接口logger.info("Adding welcome page template: index");this.setRootViewName("index");}}


http://www.ppmy.cn/devtools/116733.html

相关文章

vue和thinkphp路由伪静态配置

vue路由伪静态配置&#xff1a; location / { try_files $uri $uri/ /index.html; } thinkphp 路由伪静态配置 location ~* (runtime|application)/{ return 403; } location / { if (!-e $request_filename){ rewrite ^(.*)$ /index.php?s$1 last; break; } }

「DAOI R1」Magic

「DAOI R1」Magic 题目背景 -1,-1,2 题目描述 乔木 来到了大魔王的面前&#xff0c;他决定使用魔法击败魔王。 给定一个整数 n n n&#xff0c;表示有 n n n 个魔法阵&#xff0c;在每个魔法阵上都存在着一定的魔力值 a i a_i ai​。 你每次可以选择三个魔法阵 i , j ,…

Maya---机械模型制作

材质效果&#xff08;4&#xff09;_哔哩哔哩_bilibili 三角面 四边面 多边面 *游戏允许出现三角面和四边面 游戏中一般是低模&#xff08;几千个面&#xff09; 动漫及影视是高模 机械由单独零件组合而成&#xff0c;需独立制作 低面模型到高面模型 卡线是为了将模型保…

Qt-拖放

概述 拖放提供了一种简单的可视化机制&#xff0c;用户可以使用它在应用程序之间和应用程序内部传输信息。拖放功能类似于剪贴板的剪切和粘贴机制。 本文档描述了基本的拖放机制&#xff0c;并概述了在自定义控件中启用它的方法。Qt的许多控件也支持拖放操作&#xff0c;如it…

element-ui多个消息提示只显示最后一个

在使用 Element UI 的 Message 消息提示时&#xff0c;默认情况下&#xff0c;如果你连续调用多个 Message 方法&#xff0c;它们会依次显示&#xff0c;直到用户关闭或它们自动消失。但是&#xff0c;如果你希望只保留最后一个消息提示&#xff0c;即每当新消息出现时&#xf…

算法【Java】—— 位运算

位运算总结 位运算的运算符&#xff1a;按位与&#xff08;&&#xff09;&#xff0c;按位或&#xff08;|&#xff09;&#xff0c;按位异或&#xff08;^&#xff09;&#xff0c;按位取反&#xff08;~&#xff09;&#xff0c;还有移位操作符 <<&#xff0c;>…

WEB攻防-JavaWweb项目JWT身份攻击组件安全访问控制

知识点&#xff1a; 1、JavaWeb常见安全及代码逻辑&#xff1b; 2、目录遍历&身份验证&逻辑&JWT&#xff1b; 3、访问控制&安全组件&越权&三方组件&#xff1b; 演示案例&#xff1a; JavaWeb-WebGoat8靶场搭建使用 安全问题-目录遍历&身份认…

Flink 中 Checkpoint 的底层原理和机制

Flink 的 Checkpoint 机制是 Apache Flink 在流式处理中的一个核心特性&#xff0c;保证了分布式数据流处理系统的 容错性。通过定期保存 状态快照&#xff08;checkpoint&#xff09;&#xff0c;即使在发生故障时&#xff0c;Flink 也可以恢复到之前的状态&#xff0c;确保处…