一.发开前准备
1.创建一个SpringBoot应用,引入我们需要的模块
2.SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置,就能运行起来
3.编写业务代码
二.静态资源映射规则
在WebMvcAutoConfiguration中有着如下的配置:
1 @Override 2 public void addResourceHandlers(ResourceHandlerRegistry registry) { 3 if (!this.resourceProperties.isAddMappings()) { 4 logger.debug("Default resource handling disabled"); 5 return; 6 } 7 Integer cachePeriod = this.resourceProperties.getCachePeriod(); 8 if (!registry.hasMappingForPattern("/webjars/**")) { 9 customizeResourceHandlerRegistration( 10 registry.addResourceHandler("/webjars/**") 11 .addResourceLocations( 12 "classpath:/META-INF/resources/webjars/") 13 .setCachePeriod(cachePeriod)); 14 } 15 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); 16 if (!registry.hasMappingForPattern(staticPathPattern)) { 17 customizeResourceHandlerRegistration( 18 registry.addResourceHandler(staticPathPattern) 19 .addResourceLocations( 20 this.resourceProperties.getStaticLocations()) 21 .setCachePeriod(cachePeriod)); 22 } 23 }
1.webjars:以jar包的方式引入静态资源,可以将JQuery等前端框架使用maven依赖的形式引入进来
2.webjars中的资源访问都去如下路径: classpath:/META-INF/resources/webjars/
--例如可以在该地址中找到JQuery: localhost:8080/webjars/jquery/3.3.1/jquery.js
1 <!--前端框架--> 2 <dependency> 3 <groupId>org.webjars</groupId> 4 <artifactId>jquery</artifactId> 5 <version>3.3.1</version> 6 </dependency>
--在访问的时候只要写webjars下面资源的地址即可
3.我们可以发现在addResourceHandlers()方法只,还为这些静态资源设置了缓存时间,而我们在ResourceProperties中设置缓存时间:
1 @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false) 2 public class ResourceProperties implements ResourceLoaderAware { 3 }
4.在spring.resources中我们可以设置静态资源相关的参数,例如缓存时间,回到方法中我们在 registry.addResourceHandler(staticPathPattern) 中设置了资源映射:private String staticPathPattern = "/**";而如果我们不进行配置,则会默认去如下地址中寻找:
"classpath:/META-INF/resources/"
"classpath:/static/"
"classpath:/static/"
"/**":当前项目的根路径.
5.欢迎页的映射
1 @Bean 2 public WelcomePageHandlerMapping welcomePageHandlerMapping( 3 ResourceProperties resourceProperties) { 4 return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(), 5 this.mvcProperties.getStaticPathPattern()); 6 }
1 private String[] getStaticWelcomePageLocations() { 2 String[] result = new String[this.staticLocations.length]; 3 for (int i = 0; i < result.length; i++) { 4 String location = this.staticLocations[i]; 5 if (!location.endsWith("/")) { 6 location = location + "/"; 7 } 8 result[i] = location + "index.html"; 9 } 10 return result; 11 }
--即所有静态目录下的index.html页面
6.设置我们的首页图标
1 @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true) 2 public static class FaviconConfiguration { 3 4 private final ResourceProperties resourceProperties; 5 6 public FaviconConfiguration(ResourceProperties resourceProperties) { 7 this.resourceProperties = resourceProperties; 8 } 9 10 @Bean 11 public SimpleUrlHandlerMapping faviconHandlerMapping() { 12 SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); 13 mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); 14 mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", 15 faviconRequestHandler())); 16 return mapping; 17 } 18 19 @Bean 20 public ResourceHttpRequestHandler faviconRequestHandler() { 21 ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); 22 requestHandler 23 .setLocations(this.resourceProperties.getFaviconLocations()); 24 return requestHandler; 25 } 26 27 }
在静态资源文件夹中寻找favicon.ico
三.引入thymeleaf
在我们传统的网页开发中,通常我们会将静态网站资源修改为.jsp文件,但是我们使用springBoot默认的打包方式是jar包,我们使用的还是嵌入式的tomcat,因此默认是不支持JSP的页面的.如果我们使用纯静态的方式给我们开发会带来很大的麻烦,因此我们可以使用模板引擎例如JSP,Velocity,Freemarker,Thymeleaf;Spring推荐我们使用thymeleaf:
1.引入ThymeLeaf:
1 <!--引入Thymeleaf--> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-thymeleaf</artifactId> 5 </dependency>
2.其默认使用的2.1.6版本,其功能较少,因此我们可以使用替换较高的版本:
1 <properties> 2 <java.version>1.8</java.version> 3 <!--设置thymeleaf版本--> 4 <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> 5 <!--thymeleaf布局功能的支持程序 thymeleaf3 主程序 适配layout2 以上版本--> 6 <thymeleag-layout-dialect.version>2.1.1</thymeleag-layout-dialect.version> 7 </properties>
四.Thymeleaf使用&语法
1 @ConfigurationProperties(prefix = "spring.thymeleaf") 2 public class ThymeleafProperties { 3 4 private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8"); 5 6 private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html"); 7 8 public static final String DEFAULT_PREFIX = "classpath:/templates/"; 9 10 public static final String DEFAULT_SUFFIX = ".html";
可以发现我们只需要将html页面放置在类路径的templates下,就可以被顺利解析扩展.
1.访问success页面:
1 @RequestMapping("/success") 2 public String success(Map<String, Object> map) { 3 map.put("hello", "你好"); 4 return "success"; 5 }
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>成功!!!</h1> 9 </body> 10 </html>
2.在success中引入Thymeleaf模板引擎--导入名称空间:<html lang="en" xmlns:th="http://www.thymeleaf.org">
3.Themeleaf语法:
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>成功!!!</h1> 9 <!--获取Hello的值 th:text="${hello}" 10 如果模板引擎解析时效,或者hello的值获取失败,那么将显示当前自行填充的默认值--> 11 <div th:text="${hello}">这是显示欢迎信息</div> 12 </body> 13 </html>
(1) th:text:改变当前元素里面的文本内容
th:任意html标签属性: 我们可以用任何属性替换掉原生的值
(2)th:insert th:replace: 片段包含,类似于jsp:include
(3)th:each :遍历
(4)th: if | unless | switch | case:判断
(5)th:object th:with: 设置变量
(6)th: attr | attrprepend | attrappend : 任意属性修改,支持在前方和后方追加内容
(7)th: value | href | src | ...:修改指定属性的默认值
(8)th: text | utext | fragment | remove: 文本转义特殊字符 | 文本不转义特殊字符 | 声明片段 | 移除片段
4.Thymeleaf表达式语法:
(1)${...} :获取变量值,获取对象的属性,调用方法; 使用内置的基本对象:
#ctx: 当前的上下文对象
#vars: 当前上下文的变量
#locale: 获取上下文的区域信息
#request | response | session | servletContext: 应用于web环境
内置工具对象(详情可以参看文档):
#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).
(2)*{...}: 和${...}在功能上是一样的 th:object 进行使用,在子标签中可以省略object的前缀
(3) #{...}: 获取国际化命名
(4)@{...}:定义URL 可以免去拼串 https:localhost/hello/hi(order=${order},item=${item})
(5)~{...}: 片段引用表达式 (后文将会介绍使用方法)
5.场景应用示例
1 @RequestMapping("/success") 2 public String success(Map<String, Object> map) { 3 map.put("hello", "<h1>你好</hi>"); 4 map.put("users", Arrays.asList("张三","李四","王五")); 5 return "success"; 6 }
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>成功!!!</h1> 9 <!--获取Hello的值 th:text="${hello}" 10 如果模板引擎解析时效,或者hello的值获取失败,那么将显示当前自行填充的默认值--> 11 <div th:text="${hello}">这是显示欢迎信息</div> 12 <hr/> 13 <div th:utext="${hello}">默认显示的内容</div> 14 <hr/> 15 <!--遍历获取数组数据 16 th:each 所在的标签,每次遍历都是生成一个--> 17 <h4 th:each="user:${users}" th:text="${user}"></h4> 18 <hr/> 19 <h4> 20 <!--行内写法[[ text ]] [( utext )]--> 21 <span th:each="user:${users}" >[[ ${user} ]]</span> 22 </h4> 23 </body> 24 </html>
五.SpringMVC的自动配置
SpringBoot自动配置好了SpringMVC,以下是SpringBoot对SpringMVC的自动配置
1.自动配置了视图解析器:根据方法的返回值,得到视图对象,视图对象决定如何渲染界面(转发?重定向?)
ContentNegotiatingViewResolver:组合所有的视图解析器
如何定制:可以自己给容器中添加视图解析器,而后ContentNegotiatingViewResolver将会自动的将其组合进来
2.静态首页访问
3.自动注册了Converter(转化器): 主要完成类型转化
formatter(格式化器):页面带来的数据例如为 2019-12-1 ==> Date类型
1 @Bean 2 @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format") 3 public Formatter<Date> dateFormatter() { 4 return new DateFormatter(this.mvcProperties.getDateFormat()); 5 }
--需要在配置文件中配置日期格式化的规则
4.HttpMessageConverter:SpringMVC中用来转化HTTP请求及响应,User-JSON
HttpMessageConverters:是从容器中确定的;自己给容器中添加HttpMessageConverter,只需自己在容器中注册
5.MessageCodesResolver:定义错误代码的生成规则
6.ConfigurableWebBindingInitializer:我们可以配置自己的来替原有的,用来初始化Web数据绑定器的
7.修改SpringBoot的默认配置:SpringBoot在自动配置很多组件的时候,都有一个模式,先看容器中有没有用户自己配置的(@Bean,@Component)如果有就用用户配置的,如果没有才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
六.扩展和全面接管SpringMVC
仅仅依赖SpringBoot对SpringMVC的默认配置,是不够使用的,例如我们在SpringMVC的配置文件中可以如下使用:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 5 6 <!--将Hello请求也映射到success--> 7 <mvc:view-controller path="/hello" view-name="success"/> 8 <!--配置拦截器--> 9 <mvc:interceptors> 10 <!--拦截hello请求--> 11 <mvc:interceptor> 12 <mvc:mapping path="/hello"/> 13 <bean></bean> 14 </mvc:interceptor> 15 </mvc:interceptors> 16 </beans>
--如果我们想要保持SpringBoot对SpringMVC的默认配置,仅仅是想额外添加一些功能,我们可以添加一个自定义的Configuration配置类:
1.编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型,不能标注@EnableWebMvc:
1 package com.zhiyun.springboot.web_restfulcrud.config; 2 3 import org.springframework.context.annotation.Configuration; 4 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 5 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 6 7 /** 8 * @author : S K Y 9 * @version :0.0.1 10 * 扩展SpringMVC的功能 11 */ 12 @Configuration 13 public class MyMvcConfig extends WebMvcConfigurerAdapter { 14 @Override 15 public void addViewControllers(ViewControllerRegistry registry) { 16 //浏览器发送hello请求也来到success页面 17 registry.addViewController("/hello").setViewName("success"); 18 } 19 }
--即保留了所有的自动配置,也能使用我们扩展的自定义配置,查看其原理:
(1)WebMvcAutoConfiguration是SpringMVC的自动配置类;
(2)内部有一个静态类也继承了WebMvcConfigurerAdapter ,在该类上有着注解@Import(EnableWebMvcConfiguration.class)
(3)EnableWebMvcConfiguration类继承了DelegatingWebMvcConfiguration类,在父类中存在如下代码:
1 @Autowired(required = false) 2 public void setConfigurers(List<WebMvcConfigurer> configurers) { 3 if (!CollectionUtils.isEmpty(configurers)) { 4 this.configurers.addWebMvcConfigurers(configurers); 5 } 6 }
(4)表示了从容器中获取所有的WebMvnConfigurer.在进行配置将所有的WebMVC相关的配置都调用了一下,这样一来就可以实现一起配置.所有的容器中所有的WebMvcConfige都会一起起作用,我们的配置类也会被调用.SpringMVC的自动配置和我们的扩展配置都回起作用.
(5)全面接管SpringMVC:SpringBoot对SpringBoot的自动配置将不再生效,我们使用@EnableWebMVC注解来标注我们自己的配置类即可.此时所有SpringMVC的自动配置都失效.
(6)EnableWebMVC注解导入了一个DelegatingWebMvcConfiguration类该是WebMvcConfigurationSupport的子类,而在WebMvcAutoConfiguration类中使用了@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)注解,表示当容器中没有这个组件的时候,这样一来自动配置类才生效.
(7)在SpringBoot中会有许多的XXXConfigurer,帮助我们进行扩展配置.
原文地址:https://www.cnblogs.com/skykuqi/p/11954619.html