SpringMVC01_MVC的执行和注解开发

一、SpringMVC概述

​ SpringMVC 是 Spring 框架的一个模块,因此 SpringMVC 无需和 Spring 进行整合就可以使用。SpringMVC 是一个基于 MVC 的 Web 框架,即 Spring Web MVC。Spring Web MVC 和 Struts2 都属于表现层的框架,它是 Spring 框架的一部分。

copy
<!-- 引入 Spring 框架的 WebMVC 的依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.5.RELEASE</version> </dependency>

(一)SpringMVC 的执行流程

​ 1.用户发起请求,请求被 servlet 拦截后,转发给 MVC 框架

​ 2.SpringMVC 中的 DispacherServlet 核心控制器,接受请求并转发给 HandlerMapping

​ 3.HandlerMapping 负责解析请求根据请求信息和配置信息找到匹配的 Controller 类,如果配置了拦截器会按照顺序执行拦截器中的 preHandler 方法

​ 4.找到匹配的 Controller 后会把请求参数传递给 Controller 里面的方法

​ 5.Controller 里面的方法执行完成之后会返回一个 ModeAndView 对象(视图名称和需要传递给视图的模型数据)

​ 6.视图解析器根据名字找到视图并把数据模型填充到视图内,再渲染成 HTML 内容,返回网页。

image-20230420164010301

(二)Spring MVC 入门案例

​ 1.从 mvn 模板新建一个 webapp,添加如下依赖

copy
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.26</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.15</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies>

​ 2.在 web.xml 中配置前端控制器

​ 可以引入 spring-beans.xml 的头文件,MVC 是 Spring 中的模块,所以 SpringMVC 和 Spring 有着相同的头部信息。

​ 配置 DispatcherServlet 时,需要为其 contextConfigLocation 属性指定要加载的 SpringMVC 的配置 文件。该文件中指定 SpringMVC 框架需要使用的处理器映射器、处理器适配器、视图解析器等组件。、

​ 如果 DispatcherServlet 初始化时没有为 contextConfigLoaction 属性指定要加载的文件,那么前端控制器就默认加载类路径下的以 DispatcherServlet 的 Servlet 名称-servlet.xml 格式的配置文件。

copy
<!-- 配置前端控制器 --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--配置初始化参数,为 contextConfigLocation 属性指定要加载的 SpringMVC 的配置文件, 如果不配置,则默认加载 DispatcherServlet 的 ServletName 为名称的配置文件,例如: SpringMVC-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> </servlet>

​ 3.配置前端控制器映射

​ 下面的 url-pattern 表示凡是以 action 结尾的任何请求都会被这个 DispacherServlet 所解析

copy
<!-- 配置前端控制器的映射 --> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>

​ 4.处理器映射器

​ SpringMVC 提供了 一个 BeanNameUrlHandlerMapping 的处理器映射器类。该类的作用是将容器中 Java Bean 的 name 属性当作 url 来进行匹配,改类是 SpringMVC 框架使用,因此不需要为该 Bean 配置 id。

​ BeanNameUrlHandlerMapping:根据 bean 名称匹配 URL 地址,即下面的 Handler 处理器。

copy
<!-- 配置处理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

​ 5.配置处理器适配器

​ MVC 框架提供了 SimpleControllerHandlerAdapter 处理器适配器类,用于执行相应的 Handler 类。Handler 类就是我们需要编写的代码。

copy
<!-- 配置处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

​ 6.配置处理器适配器

copy
<!-- 配置 Handler 处理器 --> <bean name="/book_list.action" class="com.ls.springmvc.controller.BookController"/>

​ 7.编写 Handler 处理器

copy
@Data @Accessors(chain = true) public class Book { private Long id; private String name; private Double price; } public class BookController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView(); ArrayList<Book> books = new ArrayList<>(); for (int i = 0; i < 10; i++) { books.add(new Book().setId(Long.valueOf(i)).setName("spring"+i).setPrice(100.00+i)); } modelAndView.addObject("bookList",books); modelAndView.setViewName("bookList"); return modelAndView; } }

​ 8.配置视图解析器

​ MVC 框架中提供了 InternalResourceViewResolver 视图解析器类,该类为 SpringMVC 框架使用,因此只需要将其配置到 Spring 容器中即可,不需要提供 id 属性。

​ prefix 属性:用于配置物理视图 url 路径中固定的前缀部分。

​ suffix 属性:用于配置物理视图 url 路径中固定的后缀路径。

​ 所以上面的处理器的全名称应该为 modelAndView.setViewName("/WEB-INF/jsp/bookList.jsp");

copy
<!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>

9.编写 JSP

​ 注意有的版本的 isELIgnored 是 false 也有的是 true,所以直接在头声明。将所有的 JSP 页面放到 web-inf 下,因为浏览器不能直接请求 web-inf 下的页面,只能通过后端程序完成请求转发,方便在后台控制。

copy
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> 图书列表:${bookList} </body> </html>

10.打包发布

​ 成功显示

​ 这一部分配置比较多,所以需要结合 MVC 的执行流程来看才能更清楚。

image-20230420170212506

(三) 非注解的映射器、适配器

1.映射器

​ 前面我们使用处理器映射器 BeanNameUrlHandlerMappinp 配置处理器映射器,但是她不能对 bean 的 url 进行集中管理,SpringMVC提供了可以进行 url 与 bean 映射的映射器 SimpleUrlHandlerMapping ,需要为其属性 mappings 提供一个 Properties 集合对象。其中 Properties 属性对象的 key 值就是 url,value 值就是 handler bean 的 id 属性值。

​ 更改配置如下所示,其中 HelloController 依然是实现了 Controller。

copy
<!-- 配置处理器映射器 --> <!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/person.action">personController</prop> <prop key="/hello.action">helloController</prop> </props> </property> </bean> <!-- 配置 Handler 处理器 --> <bean id="personController" class="com.ls.controller.PersonController"/> <bean id="helloController" class="com.ls.controller.HelloController"/>

image-20230422171732898

2.适配器

​ SpringMVC 还提供了另外一种非注解的处理器适配器 HttpRequestHandlerAdapter,其中包含两个主要的方法,supports 方法返回一个布尔类型的值,用于判断只有 HttpRequestHandler 类型的对象才可以被当作 Handler 来执行。HttpRequestHandler 是 SpringMVC 框架提供的一个接口,只要实现了该接口的类都可以被当作 Handler 对象来执行。handle 方法执行一 个 Handler 对象,并返回一个 ModelAndView 逻辑视图。

copy
<!-- 配置处理器映射器 --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/book.action">bookController</prop> </props> </property> </bean> <!-- 配置处理器适配器 --> <!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>--> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/> <!-- 配置 Handler 处理器 --> <!-- <bean id="personController" class="com.ls.controller.PersonController"/>--> <!-- <bean id="helloController" class="com.ls.controller.HelloController"/>--> <bean id="bookController" class="com.ls.controller.BookController"></bean>

​ 需要编写的 Controller 实现 HttpRequestHandler

copy
public class BookController implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Book接收请求"); } }

image-20230422203347934

二、注解形式开发

​ 上面那些混个脸熟即可,主要理解处理过程,平时开发应该没人用罢

(一)配置映射器和适配器

​ SpringMVC 框架为了简化使用,提供了 mvc 命名空间。该空间下提供了 mvc:annotation-driven 元素,用于简化注解方式的映射器、适配器在 spring-mvc.xml 文件中的配置。

​ 不仅可以替代上面两个 bean 类的配置,而且 mvc:annotation-driven 的驱动类还默认加载了多个参数绑定的方法,比如 json 转换解析器就默认加载。

​ 引入 mvc 命名空间之后,在配置文件中配置注解的适配器和映射器,并配置自动扫描包。

copy
xmlns:mvc="http://www.springframework.org/schema/mvc" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" <!--配置注解形式的适配器和映射器--> <mvc:annotation-driven/> <!--自动扫描包--> <context:component-scan base-package="com.ls"></context:component-scan>

​ 我是新建了一个 mvc 的配置文件,头文件是差不多的,不过不要忘了如果修改的话在 web.xml 里面把读取配置文件的信息改了,md就因为忘了改耽误半小时,,,,,,

image-20230424193804168

copy
<!--配置注解形式的适配器和映射器--> <mvc:annotation-driven/> <!--自动扫描包--> <context:component-scan base-package="com.ls"></context:component-scan> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>

(二)编写 Handler

​ 注解@Controller 标记的类,Spring 容器自动加载该 Bean 类并进行管理。对于该 Bean 中的使用注解 @RequestMapping 修饰的方法会进行自动映射。映射的 url 路径需要在 @RequestMapping 注解中定义。

​ 使用注解方式的映射器就不需要在 xml 中配置 url 和 Handler 之间的映射关系,让应用的配置信息得到极大的简化。

copy
@Data @Accessors(chain = true) public class Car { private Integer id; private String name; } //--------------------------------------------------------------------------------- @Controller @RequestMapping("/car") public class CarController { @RequestMapping("/list.action") public ModelAndView list() { System.out.println("查询车辆列表"); ArrayList<Car> cars = new ArrayList<>(); for (int i = 0; i < 10; i++) { cars.add(new Car().setId(i+1).setName("宏光"+i)); } ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("carList"); modelAndView.addObject("carList",cars); return modelAndView; } }

​ 随便来个页面测试

copy
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>CarList</title> </head> <body> ${carList} </body> </html>

image-20230424193014305

​ 使用注解方式编写的 Handler,在项目中开发业务模块时,一个业务模块下的增、删、改、查等相关联的 操作,不用再分散到各个类中,而是集中到一个 Controller 类中来完成。业务变的不再分散,在业务模块中增加新的功能也变的更加灵活与方便。

三、Controller、Service、Mapper和POJO

​ 之前写博客的时候一直混乱搞不清这几个哥们的具体作用,找了一些不错的博主回答:原文链接

(一)Entity层:实体层 数据库在项目中的类

​ Entity层是实体层,也就是所谓的model,也称为pojo层,是数据库在项目中的类,该文件包含实体类的属性和对应属性的set、get方法;

(二)DAO层: 持久层 主要与数据库进行交互

​ DAO层=mapper层,现在用Mybatis逆向工程生成的mapper层,其实就是dao层。DAO层会调用entity层,DAO中会定义实际使用到的方法,比如增删改查。DAO 层的数据源和数据库连接的参数都是在配置文件中进行配置的,配置文件一般在同层的XML文件夹中。数据持久化操作就是指,把数据放到持久化的介质中,同时提供增删改查操作。

(三)Service层:业务层 控制业务

​ Service层主要负责业务模块的逻辑应用设计。先设计放接口的类,再创建实现的类,然后在配置文件中进行配置其实现的关联。service层调用dao层接口,接收dao层返回的数据,完成项目的基本功能设计。

​ 封装Service层的业务逻辑有利于业务逻辑的独立性和重复利用性。

(四)Controller层:控制层 控制业务逻辑

​ Controller层负责具体的业务模块流程的控制,controller层负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
​ Controller层像是一个服务员,他把客人(前端)点的菜(数据、请求的类型等)进行汇总什么口味、咸淡、量的多少,交给厨师长(Service层),厨师长则告诉沾板厨师(Dao 1)、汤料房(Dao 2)、配菜厨师(Dao 3)等(统称Dao层)我需要什么样的半成品,副厨们(Dao层)就负责完成厨师长(Service)交代的任务。

posted @   Purearc  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示
🚀