目录:
-
- [SpringMVC 的 "整合支持" ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发")](#SpringMVC 的 “整合支持” ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发"))
-
- [1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些"自动配置",自动把相关的类加入到IOC容器中 )](#1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些“自动配置”,自动把相关的类加入到IOC容器中 ))
- [2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些"功能拓展" )](#2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些”功能拓展“ ))
-
- [2.1 项目基础环境搭建](#2.1 项目基础环境搭建)
- [2.2 功能拓展实现 ( MVC拓展功能 ):](#2.2 功能拓展实现 ( MVC拓展功能 ):)
-
- [① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" )](#① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" ))
- [② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加"拦截器",默认情况下,SpringBoot不会自动为项目配置一个"拦截器" )](#② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加“拦截器”,默认情况下,SpringBoot不会自动为项目配置一个“拦截器” ))
作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!
该文章参考学习教材 为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章
文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!
(侵权可联系我,进行删除,如果雷同,纯属巧合)
- 通常在 Web 开发中,会涉及 静态资源的** 访问支持** 、视图解析器 的配置 、 转换器 和 格式化器 的定制 、文件上传下载 等功能,甚至还需要考虑 到与Web服务器关联 的 Servlet相关组件 的定制。
- Spring Boot框架 支持整合一些 常用Web框架 ,从而实现Web开发 ,并 默认支持Web开发中的一些** 通用功能**。
SpringMVC 的 "整合支持" ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发")
- 为了在SpringBoot 中 实现并简化Web开发 ,SpringBoot 为一些**常用的Web开发框架**提供了 整合支持,例如 Spring MVC、Spring WebFlux 等框架 ,使用 SpringBoot进行Web开发 时,只需要在 项目 中 引入 对应 Web开发框架 的 依赖启动器 即可。
1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些"自动配置",自动把相关的类加入到IOC容器中 )
在Spring Boot项目 中,一旦引入 了 Web依赖启动器 : spring-boot-starter-web ,那么SpringBoot 整合Spring MVC框架
默认实现的一些 xxxAutoConfiguration 自动配置类 就会** 自动生效** ( 通过配置类 把相关的类 加入到IOC容器 中 ) ,几乎 可以在无任何额外配置 的情况下 进行Web 开发。
SpringBoot为整合** SpringMVC框架 实现Web开发** ,主要提供了以下 自动化配置的功能特性 :
(1)内置 了两个视图解析器 : ContentNegotiatingViewResolver 和 BeanNameViewResolver 。
(2) 支持静态资源以及 WebJars 。
(3)自动注册了** 转换器和 格式化器** 。(4)支持 Http消息转换器 。
(5)自动注册 了**消息代码解析器**。
(6)支持静态项目首页 index.html 。
(7)支持** 定制应用图标 favicon.ico**。
(8)自动** 初始化** Web数据绑定器 : ConfigurableWebBindingInitializer。Spring Boot 整合Spring MVC 进行 Web开发 时 提供了很多默认配置,而且 大多数时候 使用 默认配置 即 可满足开发需求。
例如,Spring Boot整合Spring MVC 进行Web开发 时,不需要额外配置视图解析器。
2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些"功能拓展" )
- 导入web场景依赖启动器后 ,Spring Boot会为MVC开发 进行很多"自动化配置 ",但在 实际开发中 还需要进行关于MVC开发 的 功能拓展 ,下面将通过一个具体的案例讲解Spring Boot整合Spring MVC框架 中的 MVC功能拓展 。
对一些 功能进行扩展实现。
2.1 项目基础环境搭建
基础环境搭建 :
MyLocalResolver.java :
javapackage com.myh.chapter_10.config; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.LocaleResolver; import org.thymeleaf.util.StringUtils; import java.util.Locale; @Configuration public class MyLocalResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { String l = httpServletRequest.getParameter("l"); String header = httpServletRequest.getHeader("Accept-Language"); Locale locale = null; if (!StringUtils.isEmpty(l)) { String[] split = l.split("_");//根据-进行字符串拆分 locale = new Locale(split[0], split[1]); } else { String[] splits = header.split(","); String[] split = splits[0].split("-"); locale = new Locale(split[0], split[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } @Bean //将该方法的返回值对象交给IOC容器管理 public LocaleResolver localeResolver() { return new MyLocalResolver(); } }
LoginController.java :
javapackage com.myh.chapter_10.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.Calendar; @Controller public class LoginController { @GetMapping("/toLoginPage") public String toLoginPage(Model model) { //参数类型为Model类型,该类型可以返回文本给前端 model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); return "login"; //String的返回值类型可以返回一个视图 } }
login.properties :
propertieslogin.tip=请登录 login.username=用户名 login.password=密码 login.rememberme=记住我 login.button=登录
login_en_US.properties :
propertieslogin.tip=Please sign in login.username=Username login.password=Password login.rememberme=Remember me login.button=Login
login_zh_CN.properties :
propertieslogin.tip=请登录 login.username=用户名 login.password=密码 login.rememberme=记住我 login.button=登录
login.html :
html<!DOCTYPE html> <!-- 让该页面支持 --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"> <title>用户登录页面</title> <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/login/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin"> <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72"/> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">请登录</h1> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <input type="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"/>[[#{login.rememberme}]]</label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" th:test="#{login.button}">登录</button> <p class="mt-5 mb-3 text-muted">@<span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p> <a class="btn btn-sm" th:href="@{/toLoginPage(l='zh_CN')}">中文</a> <a class="btn btn-sm" th:href="@{/toLoginPage(l='en_US')}">English</a> </form> </body> </html>
pom.xml :
xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.myh</groupId> <artifactId>chapter_10</artifactId> <version>0.0.1-SNAPSHOT</version> <name>chapter_10</name> <description>chapter_10</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <!-- <build>--> <!-- <plugins>--> <!-- <plugin>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-maven-plugin</artifactId>--> <!-- </plugin>--> <!-- </plugins>--> <!-- </build>--> </project>
运行项目后 ,访问 http://localhost:8080/toLoginPage 能查看到项目的登录页面login.html ,如下所示 :
2.2 功能拓展实现 ( MVC拓展功能 ):
在 SpringBoot 中提供 了很多关于 MVC 的 "自动化配置 ",很多 MVC对象 都 默认配置好 / 大部分MVC内容SpringBoot 都给你 自动默认配置 好了,很多的 MVC功能 / MVC效果都是可以** 免配置直接使用的 ( 如: 实现的页面跳转 ) ,但此时 如果想要使用** 一些 拓展功能 / 实现功能的拓展 :可以通过 WebMvcConfigurer 这个 接口来实现,WebMvcConfigurer 接口 有很多 方法 ,** 该接口** 中的 方法 可用于 "MVC功能拓展"。
"MVC功能拓展功能① " : 注册 "视图管理器" :
视图管理器 " 可以 将"多个url"自动映射到指定 的"视图页面 "上 , 通过 WebMvcConfigurer接口的 addViewController( ViewControllerRegistry registry )方法 即可创建"视图管理器" ,达到想要的需求效果。
"MVC功能拓展功能② " :自定义 "拦截器 " :
自定义一个拦截器 ( 用于拦截url请求 ) ,在SpringBoot的MVC 中用这个 自定义的 "拦截器" 替代 SpringBoot中 "默认的拦截器"。
"MVC功能拓展功能③ " :注册 "格式化器" :
... ( 其他MVC拓展功能 )
( WebMvcConfigurer接口 中的每一个方法 都可用于拓展MVC功能 )
① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" )
"视图管理器" 能解决的需求 : 可以 将"多个url"自动映射到指定 的"视图页面 "上 ,例如 : 通过配置"视图管理器 " 可以让 /toLoginPage请求 和 /login.html请求 都"自动映射 "到login.html 这个页面中。
创建 视图管理器 的 操作步骤/流程为 :
① 首先 创建一个** 类实现WebMvcConfigurer接口**
② 在 类 中重写该 接口的 addViewController( ViewControllerRegistry registry**)方法** 。
③ 在方法体 中通过ViewControllerRegistry对象 中的 setViewName( )方法来** 决定哪些url能访问指定的" 视图页面**"。视图管理器 的例子如:
在"项目基础环境搭建"代码 的基础上添加如下代码 :
MyMVCconfig.java :
javapackage com.myh.chapter_10.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 在SpringBoot中提供了很多关于MNC的"自动化配置",很多MVC对象都默认配置好/大部分MVC内容SpringBoot都给你自动默认配置好了,很多的 * MNC功能/MVC效果都是可以免配置直接使用的(如:实现的页面跳转),但此时如果想要使用一些拓展功能/实现功能的拓展:可以通过 * WebMvcConfigurer这个接口来实现,WebMvcConfigurer接口有很多方法,该接口中的方法可用于"MVc功能拓展。 * * MVC拓展功能① : 视图管理器 : * 现在你想要实现无论用户访问/toLoginPage 还是 访问/login.html 还是其他ulr 都能跳转到 login.html这个页面,这时候就可以调用 * WebMvcConfigurer接口 的 addViewControllers(ViewControllerRegistry registry) 方法来来创建"视图管理器"的方式来实现"上面要求的效果" * ( 通过"视图管理器"可以实现多个url访问到同一个"视图页面",但通过这种方式是无法在后端中传递"参数"给"视图页面的",这时可用拓展功能中的 "过滤器": 来赋值/传递之给"指定的视图页面" ) * */ @Configuration //比较给类为"配置类",同时将给类加入到IOC容器中 public class MyMVCconfig implements WebMvcConfigurer { //该类实现了用于MVC功能拓展的"WebMvcConfigurer接口" /** * SpringBoot中的关于MVC的拓展功能一 : 视图管理器 * 具体的操作为: * ①首先创建一个类实现WebMvcConfigurer接口(改接口的作用: 通过该接口中的方法来拓展MVC功能) * ②在类中重写WebMvc中关于能实现"视图管理器"效果的addViewController(ViewControllerRegistry registry)方法 * ③在方法体中通过ViewControllerRegistry对象中的方法来决定哪些url能访问指定的"视图页面" */ //添加"视图管理器" (属于SpringBoot中的MVC的"拓展功能") @Override public void addViewControllers(ViewControllerRegistry registry) { //让 /toLoginPage 这个请求自动映射到 login.html这个页面中 registry.addViewController("/toLoginPage222").setViewName("login"); //让 /login.html 这个请求自动映射到 login.html这个页面 registry.addViewController("/login222.html").setViewName("login"); } }
在MyMVCconfig 实现了接口 WebMvcConfigurer的 addViewControllers ( ViewControllerRegistry registry ) 方法。在** addViewControllers( )方法内部** ,使用ViewControllerRegistry 的 addViewControlle( )方法 分别定义了 /toLoginPage222 和 /login222.htm 的请求控制,并使用setViewName ("login ')方法 将路径映射为** login.html页面** 。定制完MVC 的 视图管理器功能后,就可以进行效果测试了,项目启动成功后,在浏览器上分别访问http://localhost:8080/toLoginPage222 和 http://localhost:8080/login222.html 效果如下图所示 :
从上图的运行效果可以看出,使用 WebMvConfigurer接口定义的** 用户请求控制方法也实现了 用户请求控制跳转的效果** ,相比于传统的请求处理方法而言 ,这种方法 更加简洁、直观和** 方便** 。同时也可以看出,使用这种方式无法获取后台处理的数据 ,例如登录页面中的年份。
需要说明的是,使用WebMveConfigurer接口 中的addViewControllers(ViewControllerRegistry registry)方法定制视图控制 ,只适合较为简单 的无参数视图Get方式 的请求跳转,对于 有参数 或需要 业务处理的** 跳转需求** , 最好还是采用传统方式处理请求 。
注意点 :
使用"视图管理器 "的方式来通过多url路径 来访问 到"指定视图页面 " , 有 如上图所示的 问题 ,这时可用 MVC拓展功能 中的 : 创建拦截器 ,在拦截器 中给"指定视图 "传递数据。
② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加"拦截器",默认情况下,SpringBoot不会自动为项目配置一个"拦截器" )
注册自定义拦截器 。WebMvcConfigurer接口提供了许多** MVC开发相关方法** ,例如,添加 "拦截器" 方法 addInterceptors( )方法 、添加 "格式化器" 方法 addFormatters( ) 等。
注册自定义拦截器 代码例子如 :
在 项目基础环境搭建 代码的基础上 添加如下代码 :
MyInterceptor.java : ( 自定义的"拦截器")
javapackage com.myh.chapter_10.config; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.util.Calendar; /** 自定义的拦截器,用于替代SpringBoot中MVC的默认的"拦截器" ,可通过实现HandlerInterceptor接口来自定义一个拦截器 : 用于拦截"指定的请求" 和 对"指定的请求"放行 */ @Component //将该类加入到IOC容器中 public class MyInterceptor implements HandlerInterceptor { //实现HandlerInterceptor接口 /** * preHandle : 预处理方法 : * url请求发出后,先执行"拦截器"中的preHandle()方法,再执行controller中的方法 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { /** * request.getRequestURI() : 获取并返回"发送请求"的客户端请求的 "URI字符串"。 * * URI(统一资源标识符) : uri为url的一部分,但不包括协议和 主机名(域名或IP地址) * 例如,如果请求的完整 URL 是 http://www.example.com/some/info.html 那么 request.getRequestURI()方法 * 将返回 /some/info.html * ---上面的内容即为uri(统一资源标识符) */ String uri = request.getRequestURI(); //获得请求中的"统一资源标识符/uri" Object loginUser = request.getSession().getAttribute("LoginUser");//如果已登录,会在session中的添加一个LoginUser属性 /* 用户请求/admin开头路径时,判断用户是否登录 */ //判断uri是否以/admin开头 if (uri.startsWith("/admin") && null == loginUser) { //进入这里面表明用户还未登录,拦截器将不对该url放行,同时重定向到login.html页面(同时跳转到login.html页面) response.sendRedirect("/toLoginPage"); return false; } //没进if语句中,表明其要么不是/admin请求开头,要么是没登录的用户,对其放行 return true; } /** * postHandle : 该方法会在执行"控制器方法"之后执行,但在"渲染视图页面"之前执行。可以通过此方法对请求域中的"模型和视图"做出进一步的修改 * url请求发出后,先执行"拦截器"中的preHandle()方法,再执行controller中的方法,然后就是执行postHandle()方法, 然后就是"渲染视图页面",最后执行afterCompletion()方法 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //想request域中存放当前年份用于"前端页面"动态展示 request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); } /** * afterCompletion : 该方法在 "整个请求完成" 后执行,即"视图渲染"结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等。 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } //接下来将该自定义的"拦截器"添加到SpringBoot中,通过WebMvcConfigurer接口中的 addInterceptors()方法为将该拦截器加入到SpringBoot中 }
WebMvcConfigurer.java : ( 自定义的"拦截器")
javapackage com.myh.chapter_10.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 在SpringBoot中提供了很多关于MNC的"自动化配置",很多MVC对象都默认配置好/大部分MVC内容SpringBoot都给你自动默认配置好了,很多的 * MNC功能/MVC效果都是可以免配置直接使用的(如:实现的页面跳转),但此时如果想要使用一些拓展功能/实现功能的拓展:可以通过 * WebMvcConfigurer这个接口来实现,WebMvcConfigurer接口有很多方法,该接口中的方法可用于"MVc功能拓展。 * * MVC拓展功能 (其中之一) : 自定义"拦截器" */ @Configuration //比较给类为"配置类",同时将给类加入到IOC容器中 public class MyMVCconfig implements WebMvcConfigurer { //该类实现了用于MVC功能拓展的"WebMvcConfigurer接口" /** * 使用 addInterceptors(InterceptorRegistry registry) 方法将"自定义拦截器" 加入到 SpringBoot中 */ @Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { /* addPathPatterns() : 要拦截的url路径 excludePathPatterns() : 不进行拦截的url路径 */ registry.addInterceptor(myInterceptor) .addPathPatterns("/**") .excludePathPatterns("/login.html"); } }
项目启动成功后,在浏览器上分别访问http://localhost:8080/admin 自动跳转 到了 用户登录页面 ,同时在 页面中动态显示 出了 当前年份 ,这就说明了定制 的"自定义拦截器 " 生效。
需要说明的是 ,Spring Boot 在整合Spring MVC 过程中提供了许多默认自动化配置 和特性 ,开发者可以通过Spring Boot 提供的 WebMvcConfigurer接口 对 MVC功能 进行 定制和扩展。
如果开发者不想使用Spring Boot整合MVC 时提供的一些 默认配置 ,而是想要 绝对 的 自定义管理 ,那么可以编写 一个 @Configuration注解配置类 ,同时添加 @EnableWebMvc注解 来 关闭Spring Boot提供 的 所有关于MVC功能的** 默认配置**。