1 Sprig MVC的整合支持
在Web开发中,会涉及到静态资源的访问支持、视图解析器的配置、转换器和格式化器的定制、文件上传下载等功能,甚至还需要考虑到与Web服务器关联的Servlet相关组件的定制,Spring Boot框架支持整合一些常用Web框架从而实现Web开发,并默认支持Web开发中的一些通用功能。
本章将对Spring Boot实现Web开发中涉及到的一些常用功能进行详细讲解。
1.1 Spring MVC自动配置介绍
在Spring Boot项目中,一旦引入了Web依赖启动器spring-boot-starter-web,那么Spring Boot整合Spring MVC框架默认实现的一些XxxAutoConfiguration自动配置类就会自动生效,几乎可以在无任何额外配置的情况下进行Web开发。
-
Spring Boot 整合Spring MVC的自动化配置功能特性
①内置了两个视图解析器:ContentNegotiatingViewResolver和BeanNameViewResolver;
②支持静态资源以及WebJars;
③自动注册了转换器和格式化器;
④支持Http消息转换器;
⑤自动注册了消息代码解析器;
⑥支持静态项目首页index.html;
⑦支持定制应用图标favicon.ico;
⑧自动初始化Web数据绑定器ConfigurableWebBindingInitializer。
1.2 Spring MVC功能扩展实现
下面通过一个具体的案例讲解Spring Boot整合Spring MVC框架实现Web开发的扩展功能。
-
步骤1:项目基础环境搭建
使用Spring Initializr方式创建名称为chapter05的Spring Boot项目,并在Dependencies依赖选择中选择Web模块下的web依赖启动器和Template Engines模块下的Thymeleaf依赖启动器。效果如图所示:
选择存储路径后点Finish完成项目创建。
-
步骤2:我们在charpter04项目上进一行开发,首先完成项目复制。
-
在IDEA中,找到chapter05项目里的src-main-java下内容删除
-
找到chapter04项目里的src-main-java下com文件夹,复制
-
在IDEA中,找到chapter05项目里的src-main-java,选择JAVA文件夹,Ctrl+V粘贴,如图:
-
- 同样方法,把resources整个文件夹里的内容复制到chapter05项目下的resources文件夹,如图,选择Overwrite for all,一次性把所有内容复制过来。
- 正常复制,还需要考虑pox.xml中是否有添加的内容,这里无更多内容,可以不复制pom.xml,至此,完成整个项目复制。启动项目启动类:Chapter04Application,成功运行访问http://localhost:8080/toLoginPage,效果如下图:
-
步骤3:功能扩展实现
-
1、注册视图管理器,在config包下创建一个实现WebMvcConfigurer接口的配置类MyMVCconfig,用于对MVC框架功能扩展,MyMVCconfig.java代码如下:
package com.itheima.config; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration //让下面的实现类声明为配置类,能被Spring Boot扫描到并生成实例存到容器中 public class MyMVCconfig implements WebMvcConfigurer { //添加视图管理 @Override public void addViewControllers(ViewControllerRegistry registry) { //请求toLoginPage映射路径或者Login.html页面都会自动映射到Login.html页面 registry.addViewController( "toLoginPage").setViewName("login"); registry.addViewController("login.html").setViewName("login"); } }
为了便于测试,我们把com.itheima.controller下的LoginController.java里的指向路径注释掉(RequestMapping("/toLoginPage"))(注释或取消注释快捷键:CTRL+SHIFT+/)
重新启动项目启动类,项目启动成功后,在浏览器上分别访问http://localhost:8080/toLoginPage和 http://localhost:8080/login.html, 两个均指向同一页面,效果如图:
-
可以看出,因为使用MyMVCconfig.java,所以两者访问一致,但也因为跳过使用LoginController.java,所以我们定义的public String toLoginPage(Model model)没有使用,则login.html中的${currentYear}"没有相关值 ,故显示为null
-
2、在config包下注册自定义拦截器MyInterceptor,实现HandlerInterceptor拦截器接口,MyInterceptor.java中编写如下方法:
package com.itheima.config; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Calendar; @Component public class MyInterceptor implements HandlerInterceptor { //步骤1:重写preHandle方法,preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //用户请求/admin开头路径时,判断用户是否登录 String uri = request.getRequestURI(); Object loginUser = request.getSession().getAttribute("loginUser"); if (uri.startsWith("/admin") && null == loginUser) { response.sendRedirect("/toLoginPage");//跳转到toLoginPage return false; } return true; } //重写postHandle,获得currentYear赋值 //postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); } //afterCompletion无需进行操作,可不重写 }
-
3、在自定义配置类MyMVCconfig中,重写addInterceptors()方法注册自定义的拦截器,示例代码如下:
@Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/login.html"); }
方法中使用addPathPatterns("/**")方法拦载所有路径请求,交给myInterceptor拦截器处理,excludePathPatterns("/login.html")则是对login.html路径的请求进行了放行处理。
最后,重启项目,启动成功后,在浏览器上访问http://localhost:8080/admin:
可以看到,路径自动跳转到了用户登录页面,同时动态显示年份,说明此次定制的自定义拦截器生效。
需要说明的是,Spring Boot在整合Spring MVC过程中提供了许多默认自动化配置和特性,开发者可以通过Spring Boot提供的WebMvcConfigurer接口对MVC功能进行定制和扩展。如果开发者不想使用Spring Boot整合MVC时提供的一些默认配置,而是想要绝对的自定义管理,那么可以编写一个@Configuration注解配置类,同时添加@EnableWebMvc注解关闭Spring Boot提供的所有关于MVC功能的默认配置。
2 Spring Boot 整合Servlet三大组件
-
使用组件注册方式整合Servlet
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
-
步骤1:在项目chapter05中创建包com.itheima.servletComponent的包,并在该包下创建一个自定义Servlet类MyServlet.java,示例代码如下:
package com.itheima.servletComponent; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //步骤4:把实例类配置到spring容器中 @Component //步骤1:继承HttpServlet public class MyServlet extends HttpServlet { //步骤2:重写doGet方法,技巧:输入doGet,找到后回车,再完善代码 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("Hello mysevlet");//借助resp对象输出一句话 } //步骤3:重写doPost方法,技巧:输入doPost,找到后回车,再完善代码:调用doGet即可 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
步骤2:创建Servlet组件配置类。在项目com.itheima.config包下创建一个Servlet组件配置类Serl
-