文章目录
准备工作
我们接下来准备使用SpringBoot开发一个restful的应用,首先我们通过Idea创建向导帮我们创建SpringBoot应用,勾选我们需要的模块,这里我们还是只勾选一个web场景,后面需要啥再添加。
SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来,只需要注意在业务代码中就可以了。
SpringBoot对静态资源的映射配置规则
使用webjars
- 首先SpringBoot的有个叫
webjars
的东西,所有通过pom.xml
引入的静态资源,都在/webjars/**
下(这个在静态资源的自动配置类中可以找到),也就是说SpringBoot会自动去classpath:/META-INF/resources/webjars/
找资源,webjars以jar
包的方式引入静态资源(也就是说,我们都可以通过http://localhost:8080/webjars/xx
访问对应的静态资源) - 怎么通过pom.xml引入静态资源呢?我们可以去webjars的资源库中找,需要什么静态资源的jar基本都可以在这里找到。我们在项目导入如下依赖:
<!-- 引入jquery-webjar -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
- 我们引入JQuery之后,在JQuery的依赖包下边,可以看到webjars内容:
- 引入了jQuery的静态资源,我们启动项目,来试一下能不能通过对应的路径访问,我这里使用的路径是
http://localhost:8080/webjars/jquery/3.4.1/jquery.js
,在访问的时候只需要写webjars下面资源的名称即可
使用resources
- 如果我们想要用自己的静态资源,不想使用webjars的东西,怎么做呢?
"/**"
访问当前项目的任何资源,都去(静态资源的文件夹)找映射,也就是说,我们通过http://localhost:8080/xxx.js
去静态资源文件夹里面找xxx,如果我们没有配置相关,就会默认去下面这几个文件夹中找- “classpath:/META‐INF/resources/”,
- “classpath:/resources/”,
- “classpath:/static/”,
- “classpath:/public/”
- “/”:当前项目的根路径
即通过“/**”
访问的静态资源,SpringBoot会去上面这几个找资源,这些也就是SpringBoot默认的静态资源文件夹
- 创建两个存放静态资源的文件夹public,resources来演示一遍,
- 随便将Chart.min.js放置在三个文件夹中的一个,然后通过
http://localhost:8080/Chart.min.js
可以访问到
配置欢迎页映射
- 欢迎页; 静态资源文件夹下的所有
index.html
页面;被"/**"
映射; - 也就是说我们直接访问
http://localhost:8080/
就直接访问静态资源文件夹中的index.html
,相当于我们以前SpringMVC下面的index.jsp
,大家可以在三个静态资源文件夹中的一个下创建index.html
,然后直接运行就行了,这里不在演示。 - 同样的所有的
/favicon.ico
默认都是在静态资源下找,当然,如果我们不想要使用SpringBoot默认的静态资源文件夹,我们还可以在配置文件中定义静态资源的映射,如下
spring.web.resources.static-locations=classpath:/cz/,classpath:/hello/
spring.web.resources.static-locations相当于一个数组,当有多个文件夹的时候,直接使用逗号隔开就行。
如果自己定义了静态资源映射之后,默认的文件夹就都不生效了,相当于原来的那些访问方式都不生效了
模板引擎
JSP、Velocity、Freemarker、Thymeleaf等等,模板引擎的本质思想是一样的,只是语法不大一致而已。比如说以freemarker为例,如下图。
- SpringBoot推荐的Thymeleaf,不用JSP,因为Thymeleaf语法更加简单,功能更加强大,如何导入呢,依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 这里引入的是SpringBoot默认的
Thymeleaf
依赖版本,如果我们要切换版本怎么切换,如下,加上对应版本号就可以了
<properties>
<thymeleaf.version></thymeleaf.version>
<thymeleaf-layout-dialect.version></thymeleaf-layout-dialect.version>
</properties>
使用Thymeleaf语法
- 在使用
Thymeleaf
语法之前,我们先来实验一下,我们只要把HTML页面放在templates目录下就可以了,Thymeleaf
就会自动渲染 - 编写
Hellocintroller
@Controller
public class HelloController {
//查出数据在页面显示
@RequestMapping("/success")
public String success(Map<String, Object> map) {
map.put("success", "你好");
return "success";
}
}
- 在
templates
中编写成功页面success.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功</h1>
<!--th:text 将div里面的文本内容设置为 -->
<div th:text="${success}"></div>
</body>
</html>
xmlns:th="http://www.thymeleaf.org"
引入的名称空间,这样我们写代码的时候,idea就会有提示
- 编写好之后启动项目,我们通过访问
localhost:8080/success
来访问success.html
页面,访问之后结果如下
语法规则
对于Thymeleaf语法的具体使用可以去看看Thymeleaf的官方文档,我这只说一下常用的。
th:text
;改变当前元素里面的文本内容;
-th
:任意html属性;来替换原生属性的值
- 表达式
Simple expressions:(表达式语法)
Variable Expressions: ${...}:获取变量值;OGNL;
1)、获取对象的属性、调用方法
2)、使用内置的基本对象:
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object.
${session.foo}
3)、内置的一些工具对象:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
补充:配合 th:object="${session.user}:
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
Message Expressions: #{...}:获取国际化内容
Link URL Expressions: @{...}:定义URL;
@{/order/process(execId=${execId},execType='FAST')}
Fragment Expressions: ~{...}:片段引用表达式
<div th:insert="~{commons :: main}">...</div>
Literals(字面量)
Text literals: 'one text' , 'Another one!' ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal 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 , or
Boolean 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: _
SpringMVC自动配置
- SpringBoot集成了SpringMVC,所以里面自然自动配置了SpringMVC运行的相关基本依赖,那么SpringBoot引入了SpringMVC那些依赖呢?这里我大致进行一下介绍。Spring Boot为Spring MVC提供了自动配置,可与大多数应用程序完美配合。可以去官方文档查看
以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration
)
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发、重定向))
- ContentNegotiatingViewResolver:组合所有的视图解析器的;
- 如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来;
-
Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars
-
Static
index.html
support. 静态首页访问 -
Custom
Favicon
support (see below). favicon.ico
-
自动注册了
Converter
,GenericConverter
,Formatter
的beans.- Converter:转换器; public String hello(User user):类型转换使用Converter
Formatter
格式化器; 2021.01.01==Date;
自己添加的格式化器转换器,我们只需要放在容器中即可
@Bean
@ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}
-
Support for
HttpMessageConverters
(see below).-
HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json;
-
HttpMessageConverters
是从容器中确定;获取所有的HttpMessageConverter;自己给容器中添加
HttpMessageConverter
,只需要将自己的组件注册容器中(@Bean,@Component
)
-
-
Automatic registration of
MessageCodesResolver
(see below).定义错误代码生成规则 -
Automatic use of a
ConfigurableWebBindingInitializer
bean (see below).我们可以配置一个
ConfigurableWebBindingInitializer
来替换默认的;(添加到容器)
初始化WebDataBinder;
请求数据=====JavaBean;
org.springframework.boot.autoconfigure.web:web的所有自动场景;
If you want to keep Spring Boot MVC features, and you just want to add additional MVCconfiguration (interceptors, formatters, view controllers etc.) you can add your own
@Configuration
class of typeWebMvcConfigurerAdapter
, but without@EnableWebMvc
. If you wish to provide custom instances ofRequestMappingHandlerMapping
,RequestMappingHandlerAdapter
orExceptionHandlerExceptionResolver
you can declare aWebMvcRegistrationsAdapter
instance providing such components.
If you want to take complete control of Spring MVC, you can add your own@Configuration
annotated with@EnableWebMvc
.
拓展SpringMVC
- 编写一个springmvc的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:view-controller path="/hello" view-name="success"></mvc:view-controller>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
- 在config包下创建一个
MyMvcConfig
的类,实现WebMvcConfigurer
接口,就可以对SpringBoot中关于SpringMVC相关配置进行扩展了。WebMvcConfigurer
可以用来扩展SpringMVC的功能,需要什么在里面实现什么方法就可以了,比如我们扩展一下视图转换器,如下
@Configuration
public class MyMvcConfig implements WebMvcConfigurer{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /cz 请求来到 success
registry.addViewController("/cz").setViewName("success");
}
}
访问localhost:8080/cz会跳转到success页面,这样实现了既保留了使用原有的配置,又能使用我们自己的方式扩展配置
-
原理:
WebMvcAutoConfiguration
是SpringMVC的自动配置类- 在做其他自动配置时会导入
@Import(**EnableWebMvcConfiguration**.class)
- 容器中所有的
WebMvcConfigurer
都会一起起作用; - 我们的配置类也会被调用;
-
效果:SpringMVC的自动配置和我们的扩展配置都会起作用;
如果我们再在配置类上加上@EnableWebMvc
注解,是啥意思呢,也就是说我们将全面接管SpringMVC在SpringBoot中的配置,在SpringBoot中有关SpringMVC所有的默认配置都会失效,需要我们自行配置,比如上面我们默认webjars
进行访问静态资源等等,都会失效
@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer{
//....
}
为什么加上@EnableWebMvc
自动配置就失效了;我们来分析一下:
@EnableWebMvc
的核心
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
- 点进
DelegatingWebMvcConfiguration
类中查看
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
- 然后来看SpringMVC的自动配置类。
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({
Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({
DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
- 我们可以发现
@EnableWebMvc
将WebMvcConfigurationSupport
组件导入进来 - 导入的
WebMvcConfigurationSupport
只是SpringMVC最基本的功能;
如何修改SpringBoot的默认配置
- SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(
@Bean、@Component
)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)
将用户配置的和自己默认的组合起来; - 在SpringBoot中会有非常多的
xxxConfigurer
帮助我们进行扩展配置 - 在SpringBoot中会有很多的
xxxCustomizer
帮助我们进行定制配置