SpringBoot4

mac2024-08-03  58

SpringBoot4_Web开发

1. 简介

使用SpringBoot搭建项目的步骤:

创建SpringBoot应用,选中我们需要的模块 ,如web模块、mybatis模块SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来自己编写业务代码

2. SpringBoot对静态资源的映射规则

SpringBoot中有一个ResourceProperties类,其对静态资源进行了详细的配置

@ConfigurationProperties( prefix = "spring.resources", ignoreUnknownFields = false ) public class ResourceProperties { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}; private String[] staticLocations; private boolean addMappings; private final ResourceProperties.Chain chain; private final ResourceProperties.Cache cache; public ResourceProperties() { this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS; this.addMappings = true; this.chain = new ResourceProperties.Chain(); this.cache = new ResourceProperties.Cache(); } public String[] getStaticLocations() { return this.staticLocations; }

从以上代码可以看出,其规定了4个静态资源的路径,分别是:

classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/

然后ResourceProperties的构造器将这四个路径赋值给staticLocations

项目目录下,main文件夹下的java目录和resources都是类路径的根目录,需要在这两个文件夹下建立以上四种目录结构,项目就能完成对现有静态资源的访问

2.1 /webjars/**

我们创建一个项目,SpringBoot为我们自动配置了太多东西,主要是WebMvcAutoConfiguration类的作用,我们仔细查看这个类,里面有一个addResourceHandlers函数

public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); if (!registry.hasMappingForPattern("/webjars/**")) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } #静态资源文件夹映射 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } } }

从上面的代码,可以清楚的看到,针对所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源。

举例:引入jquery.3.4.1

首先在pom文件中添加webjars依赖,可以去WebJars官网查找

添加完依赖后,在项目的依赖库里就可以找到它

我们在浏览器输入localhost:8080/webjars/jquery/3.4.1/jquery.js,可以正常访问到。其实它真实的访问路径就是classpath:/META-INF/resources/webjars/jquery/3.4.1/jquery.js。

2.2 /**

另外,函数addResourceHandlers()中有如下代码

String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); }

点开getStaticPathPattern()

继而查看函数addResourceHandlers()中的getStaticLocations()

足以说明以"/**" 访问当前项目的任何资源,都去静态资源的文件夹(也就是上面提到的四个路径)找映射

2.3 欢迎页

在WebMvcAutoConfiguration类中,还有对欢迎页的配置

@Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern()); welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider)); return welcomePageHandlerMapping; } private Optional<Resource> getWelcomePage() { String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations()); return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst(); } private Resource getIndexHtml(String location) { return this.resourceLoader.getResource(location + "index.html"); }

主要是如下这句

WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());

其中getStaticPathPattern()就是我们在2.2所说的/**请求;

this.getWelcomePage()指定从getStaticLocations()中查找静态资源。

我们在resources根目录下的public文件夹里放入index.html

访问localhost:8080,就能访问到public文件夹里的index.html

3. 模板引擎

我们用Spring做web项目,可以使用jsp,但是SpringBoot是不支持jsp的。如果想使用SpringBoot做web项目,就要用到模板引擎。常见的模板引擎有JSP、Velocity、Freemarker、Thymeleaf

如果前端页面需要用到动态的数据,模板引擎就可以把Template和Data结合,从而生成还有动态数据的页面。

SpringBoot中使用的模板引擎是Thymeleaf。

3.1 引入Thymeleaf

如果要使用Thymeleaf,需要在pom文件中引用

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‐boot‐starter-thymeleaf</artifactId> </dependency>

添加如上引用之后,发现springboot默认引入的thymeleaf版本为2.2.0

如果嫌弃springboot默认引入的thymeleaf版本过低,可以在pom文件的properties标签中进行修改。

<properties> <java.version>1.8</java.version> <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version> ... </properties>

注意:thymeleaf 3.0以上版本与thymeleaf‐layout‐dialect 2.0 以上版本适配; thymeleaf 2.0以上版本与thymeleaf‐layout‐dialect 1.0 以上版本适配。

3.2 Thymeleaf的使用

引入Thymeleaf后,SpringBoot已经自动帮我们配置好了Thymeleaf。

在引入的依赖中查看sping-boot-autoconfigure包,看到Thymeleaf已经导入进来了。

查看ThymeleafProperties,有如下代码

public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING; public static final String DEFAULT_PREFIX = "classpath:/templates/"; public static final String DEFAULT_SUFFIX = ".html"; private boolean checkTemplate = true; private boolean checkTemplateLocation = true; private String prefix = "classpath:/templates/"; private String suffix = ".html"; private String mode = "HTML";

我们可以发现,默认前缀为classpath:/templates/,默认后缀为.html

于是我在类路径下的templates新建一个success.html文件,在HelloController类中添加如下代码

@RequestMapping("/success") public String success(){ return "success"; }

通过访问localhost:8080/success,能正常跳转到success页面。

3.3 语法规则

要使用Thymeleaf,在html标签中添加``xmlns:th`属性,在编辑html页面的时候,IDE会给我们做出thymeleaf相关的提示

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

可以使用th:*替换原生属性的值,如div标签中的id属性:<div th:id="div1"></div>。

其中th:*属性的优先级如下所示:

2. 表达式

Thymeleaf中的标准表达式如下

Simple expressions: Variable Expressions: ${…} 1)、获取对象的属性、调用方法 2)、使用内置的基本对象 3)、内置的一些工具对象Selection Variable Expressions: *{…} 选择表达式:和${}在功能上是一样Message Expressions: #{…} 获取国际化内容Link URL Expressions: @{…} 定义URLFragment Expressions: ~{…} 片段引用表达式 Literals:(字面量) Text literals: ‘one text’ , ‘Another one!’ ,…Number literals: 0 , 34 , 3.0 , 12.3 ,…Boolean literals: true , falseNull literal: nullLiteral tokens: one , sometext , main ,… Text operations: (文本操作) String concatenation: +Literal substitutions: |The name is ${name}| Arithmetic operations: (数学运算) Binary operators: + , - , * , / , %Minus sign (unary operator): - Boolean operations:(布尔运算) Binary operators: and , orBoolean negation (unary operator): ! , not Comparisons and equality: (比较运算) Comparators: > , < , >= , <= ( gt , lt , ge , le )Equality operators: == , != ( eq , ne ) Conditional operators: 条件运算(三元运算符) If-then: (if) ? (then)If-then-else: (if) ? (then) : (else)Default: (value) ?: (defaultvalue) Special tokens: (特殊操作) No-Operation: _

4. SpringMVC自动配置

4.1 Spring MVC Auto-configuration

我们查看SpringBoot的官方文档,他对Spring MVC Auto-configuration的介绍如下,我们对其做一些解释

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.

The auto-configuration adds the following features on top of Spring’s defaults:

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

自动配置了视图解析器ContentNegotiatingViewResolver:组合所有的视图解析器我们可以自己给容器中添加一个视图解析器;自动的将其组合进来

Support for serving static resources, including support for WebJars

静态资源文件夹路径

Automatic registration of Converter, GenericConverter, and Formatter beans.

Converter:转换器Formatter:格式化器我们可以自己添加格式化器 转换器,只需要放在容器中即可

Support for HttpMessageConverters

HttpMessageConverter:SpringMVC用来转换Http请求和响应的HttpMessageConverters:是从容器中确定;获取所有的HttpMessageConverter自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)

Automatic registration of MessageCodesResolver 定义错误代码生成规则

Static index.html support.

Custom Favicon support

Automatic use of a ConfigurableWebBindingInitializer bean 我们可以配置一个ConfigurableWebBindingInitializer来替换默认的

4.2 扩展SpringMVC

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

我们如果不用SpringBoot 时,可能会编写一下代码

<mvc:view‐controller path="/santiago" view‐name="success"/> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/hello"/> <bean></bean> </mvc:interceptor> </mvc:interceptors>

根据以上SpringBoot官方文档,我们可以编写一个WebMvcConfigurer类型的配置类,从而实现上面的功能

@Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/santiago").setViewName("success"); } }

既保留了所有的自动配置,也能用我们扩展的配置

4.3 全面接管SpringMVC

如果想全面接管SpringMVC,只需要在我们自己定义的配置类上加上注解@EnableWebMvc,SpringMVC所有的自动配置就会失效。

我们查看这个注解探究一下原理:

@EnableWebMvc的核心 @Import({DelegatingWebMvcConfiguration.class}) public @interface EnableWebMvc { } 而DelegatingWebMvcConfiguration又继承自WebMvcConfigurationSupport这个WebMvcConfigurationSupport是什么都东西呢?我们查看WebMvcAutoConfiguration,发现容器中没有WebMvcAutoConfiguration这个组件的时候,这个自动配置类WebMvcConfigurationSupport才生效 。

使用@EnableWebMvc的后果就是直接导入了WebMvcConfigurationSupport,而WebMvcAutoConfiguration不会生效。且WebMvcConfigurationSupport只提供了简单的SpringMVC功能,其中视图解析器、拦截器等功能还需要我们自己配置。所以说@EnableWebMvc注解要谨慎使

5. 如何修改SpringBoot的默认配置

模式:

SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如 果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置
最新回复(0)