要解决的问题:
- 导入静态资源…
- 首页
- jsp,模板引擎 Thymeleaf
- 装配扩展SpringMvc
- 增删改查
- 拦截器
- 国际化
一、静态资源
1、方式一
- 全局搜索 WebMvcAutoConfiguration.class,找到 addResourceHandlers分析源码
- 在浏览器上搜索webjars,随便找的个依赖(这里找的是jquery的maven依赖)
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
- 再看idea中看是否导入了依赖,通过浏览器的url及进行获取
http://localhost:8080/webjars/jquery/3.4.1/jquery.js
2、方式二
- 通过看源码可以知道:resources下有三个文件夹可以存放静态资源
- public, static, resources
- 优先级:resources>static(默认)>public
二、首页
通过源码分析,在静态资源目录下创建index.html文件就是首页
1、编写一个IndexController(方式一)
@Controller
public class IndexController {
@RequestMapping({"/","index.html"})
public String index(){
return "index";
}
}
2、通过重写Config配置
// 如果我们要扩展springmvc, 官方建议我们这样去做!
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// 视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
三、网站头像
在resources目录下创建一个命名为favicon.ico网站图标
在Spring Boot项目的issues中提出,如果提供默认的Favicon可能会导致网站信息泄露。如果用户不进行自定义的Favicon的设置,而Spring Boot项目会提供默认的图标,那么势必会导致泄露网站的开发框架。
因此,在Spring Boot2.2.x中,将默认的favicon.ico移除,同时也不再提供上述application.properties中的属性配置。
在早些版本中Spring Boot对Favicon进行了默认支持,并且通过如下配置进行关闭操作:
spring.mvc.favicon.enabled=false # 关闭默认图标设置
自定义Favicon
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Hello Favicon</title>
<!-- 链入网站图标 -->
<link rel="icon" th:href="@{/favicon.ico}" type="image/x-icon"/>
<link rel="bookmark" th:href="@{/favicon.ico}" type="image/x-icon"/>
</head>
<body>
<h1>Hello Favicon!</h1>
</body>
</html>
注意:如果图标加载不出来
代码错误
http://localhost:8080/favicon.ico
如果能访问成功,代码问题排除可能是缓存问题
- 浏览器缓存
手动清除缓存 - thymeleaf缓存
# 关闭模板引擎的缓存
spring.thymeleaf.cache=false
- 浏览器缓存
四、模板引擎 Thymeleaf
1、标准表达式语法
Thymeleaf 模板引擎支持多种表达式:
- 变量表达式:${…}
- 选择变量表达式:*{…}
- 链接表达式:@{…}
- 国际化表达式:#{…}
- 片段引用表达式:~{…}
2、变量表达式
使用 ${} 包裹的表达式被称为变量表达式,该表达式具有以下功能:
- 获取对象的属性和方法
- 使用内置的基本对象
- 使用内置的工具对象
① 获取对象的属性和方法
使用变量表达式可以获取对象的属性和方法,例如,获取 person 对象的 lastName 属性,表达式形式如下:
${person.lastName}
② 使用内置的基本对象
使用变量表达式还可以使用内置基本对象,获取内置对象的属性,调用内置对象的方法。 Thymeleaf 中常用的内置基本对象如下:
ctx :上下文对象;
vars :上下文变量;
locale:上下文的语言环境;
request:HttpServletRequest 对象(仅在 Web 应用中可用);
response:HttpServletResponse 对象(仅在 Web 应用中可用);
session:HttpSession 对象(仅在 Web 应用中可用);
servletContext:ServletContext 对象(仅在 Web 应用中可用)。
例如,我们通过以下 2 种形式,都可以获取到 session 对象中的 map 属性:
${#session.getAttribute('map')}${session.map}
③ 使用内置的工具对象
除了能使用内置的基本对象外,变量表达式还可以使用一些内置的工具对象。
- strings:字符串工具对象,常用方法有:equals、equalsIgnoreCase、length、trim、toUpperCase、toLowerCase、indexOf、substring、replace、startsWith、endsWith,contains 和 containsIgnoreCase 等;
- numbers:数字工具对象,常用的方法有:formatDecimal 等;
- bools:布尔工具对象,常用的方法有:isTrue 和 isFalse 等;
- arrays:数组工具对象,常用的方法有:toArray、length、isEmpty、contains 和 containsAll 等;
- lists/sets:List/Set 集合工具对象,常用的方法有:toList、size、isEmpty、contains、containsAll 和 sort 等;
- maps:Map 集合工具对象,常用的方法有:size、isEmpty、containsKey 和 containsValue 等;
- dates:日期工具对象,常用的方法有:format、year、month、hour 和 createNow 等。
例如,我们可以使用内置工具对象 strings 的 equals 方法,来判断字符串与对象的某个属性是否相等,代码如下。
${#strings.equals('编程帮',name)}
2、案例
- 导入启动器依旧是依赖
<!--Thymeleaf, 我们都是基于3.0开发-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
编写一个TestController的类
@Controller
public class TestController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("msg","<h1>hello springboot</h1>");
model.addAttribute("users", Arrays.asList("shuai","shenwo"));
return "test";
}
- 在templates文件夹下创建test.html ```html <!DOCTYPE html>
<!--所有的html元素都可以被 thymeleaf 替换接管: th: 元素名-->
<!--/*@thymesVar id="msg" type="java.lang.String"*/-->
<div th:text="${msg}"></div>
<div th:utext="${msg}"></div>
<hr>
<!--<h3 th:each="user:${users}">[[ ${user} ]]</h3>-->
<h3 th:each="user:${users}" th:text="${user}"></h3>
<a name="016089ac"></a>
## 五、MVC自动配置原理
全局搜索类 **WebMvcConfigurer.class**
<a name="09436858"></a>
### 修改SpringBoot的默认配置
这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种学习方式,通过源码探究,得出结论;这个结论一定是属于自己的,而且一通百通。
SpringBoot的底层,大量用到了这些设计细节思想,所以,没事需要多阅读源码!得出结论;
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;
如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!
我们要做的就是编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解;我们去自己写一个;我们新建一个包叫config,写一个类MyMvcConfig;
```java
// 如果我们要扩展springmvc, 官方建议我们这样去做!
@Configuration
// @EnableWebMvc // 这玩意就是导入了一个类,DelegatingWebMvcConfiguration:从容器中获取所有的webmvcconfig,开启之后全面接管了SpringMVC,SpringBoot对SpringMVC的自动配置全部失效,(不推荐使用)
public class MyMvcConfig implements WebMvcConfigurer {
// 视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/shuai").setViewName("test");
}
}
确实也跳转过来了!所以说,我们要扩展SpringMVC,官方就推荐我们这么去使用,既保SpringBoot留所有的自动配置,也能用我们扩展的配置!
在SpringBoot中会有非常多 xxxx Configuration 帮助我们进行扩展配置,只要看见了这个,我们就应该多留心注意~
六、页面国际化
有的时候,我们的网站会去涉及中英文甚至多语言的切换,这时候我们就需要学习国际化了!
1、配置文件编写
1、我们在resources资源文件下新建一个i18n目录,存放国际化配置文件
2、建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作;文件夹变了!
3、利用文件夹功能创建login_en_US.properties
4、接下来,我们就来编写配置,我们可以看到idea下面有另外一个视图;正常情况下,在一个视图中写入数据会自动填充到其他位置(我该功能在网上查询无果),然后手动把数据敲上去(比较麻烦)。
然后去查看我们的配置文件;
login.properties :默认
login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名
英文:
login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username
中文:
login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名
OK,配置文件步骤搞定!
2、配置文件生效探究
我们去看一下SpringBoot对国际化的自动配置!这里又涉及到一个类:MessageSourceAutoConfiguration
有兴趣可以全局搜索一下这个类,看看
我们真实 的情况是放在了i18n目录下,所以我们要去配置这个messages的路径;
spring.messages.basename=i18n.login
3、配置国际化解析
在Spring中有一个国际化的Locale (区域信息对象);里面有一个叫做LocaleResolver (获取区域信息对象)的解析器!
AcceptHeaderLocaleResolver 这个类中有一个方法
那假如我们现在想点击链接让我们的国际化资源生效,就需要让我们自己的Locale生效!
我们去自己写一个自己的LocaleResolver,可以在链接上携带区域信息!
修改一下前端页面的跳转连接:
<!-- 这里传入参数不需要使用 ?使用 (key=value)-->
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
我们去写一个处理的组件类!
//可以在链接上携带区域信息
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("l");
Locale locale = Locale.getDefault(); // 如果没有获取到就使用系统默认的
//如果请求链接不为空
if (!StringUtils.isEmpty(language)){
//分割请求参数
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
为了让我们的区域化信息能够生效,我们需要再配置一下这个组件!在我们自己的MvcConofig下添加bean;
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}