Java阶段三06

第3章-第7节

一、知识点

理解MVC三层模型、理解什么是SpringMVC、理解SpringMVC的工作流程、了解springMVC和Struts2的区别、学会使用SpringMVC封装不同请求、接收参数

二、目标

  • 理解MVC三层模型

  • 理解什么是SpringMVC

  • 理解SpringMVC的工作流程

  • 学会使用SpringMVC封装请求

三、内容分析

  • 重点

    • 理解MVC三层模型

    • 理解什么是SpringMVC

    • 理解SpringMVC的工作流程

    • 学会使用SpringMVC封装请求

  • 难点

    • 理解SpringMVC的工作流程

    • 学会使用SpringMVC封装请求

四、内容

1、MVC模型

1.1 MVC的概念

MVC全名Model View Controller,模型视图控制器的缩写。是一种用于设计创建Web应用程序表现层的模式。

mvc是一种架构模型,本身并没有新功能,只是对项目的一种规范,方便后期进行维护;mvc架构将模型(M),视图(V)和控制(C)割离开,这么做可以提高代码书写的效率和后期维护;

1.2 MVC详解
  • M:即model(模型) 是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。通常指数据模型,作用一般情况下用于封装数据。

  • V:即View(视图)是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操作的方式。通常指jsp或者html,用来展示数据的。视图依据模型创建。

  • C:即controller(控制器) 是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。处理用户交互部分,用来处理程序逻辑

1.3 MVC的框架(了解即可)
struts2

Struts2是一个基于MVC设计模式Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
*

SpringMVC

Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

一个好的框架要减轻开发者处理复杂问题的负担,内部有良好的扩展,并且有一个支持它的强大用户群体,恰恰 Spring MVC 都做到了。

Spring MVC 角色划分清晰,分工明细。由于 Spring MVC 本身就是 Spring 框架的一部分,可以说和 Spring 框架是无缝集成。性能方面具有先天的优越性,是当今业界最主流的 Web 开发框架,最热门的开发技能。
*

区别
  • Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截, 一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现 restful url,而struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url, 而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。

  • SpringMVC的方法之间基本上独立的,独享request response数据,请求数据通过参数获取, 处理结果通过ModelMap交回给框架,方法之间不共享变量,而Struts2搞的就比较乱,虽然方法之间也是独立的, 但其所有Action变量是共享的,这不会影响程序运行,却给我们编码 读程序时带来麻烦, 每次来了请求就创建一个Action,一个Action对象对应一个request上下文。

  • Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map, 供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。

  • 拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式, 这样导致Struts2的配置文件量还是比SpringMVC大。

  • SpringMVC的入口是servlet,而Struts2是filter(这里要指出,filter和servlet是不同的。 以前认为filter是servlet的一种特殊),这就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。

  • SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可, 而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去, 使用起来也相对不方便。

  • SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。

  • SpringMVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高( 当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。

  • SpringMVC开发效率和性能高于Struts2。

  • SpringMVC可以认为已经100%零配置

2、SpringMVC

2.1 主要组件
  • 前端控制器(DispatcherServlet)

    用户请求达到前端控制器,它就相当于mvc模式的c,dispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户请求,dispatcherServlet的存在降低了组件之间的耦合性

  • 请求处理器映射(HandlerMapping)

    根据用户请求找到Handler,即处理器,SpringMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等

  • 处理器适配(HandlerAdapter)

    通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行

  • 处理器(Handler)

    开发中要编写的具体业务控制器,由DispatcherServlet把用户请求转发到Handler,由Handler对具体的用户请求进行处理

  • 视图解析器(ViewResolver)

    ViewResolver负责将处理结果生成view视图。首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户

  • 视图(View)

    SpringMVC提供了很多view视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。

2.2 工作流程
  1. 用户通过浏览器发起 HttpRequest 请求到前端控制器 (DispatcherServlet),前端控制器是所有请求的入口,但前端控制器不能处理业务请求,它只是一个请求的转发。

  2. 谁来处理业务请求呢?Handler处理器来真正处理业务请求,那么问题来了,前端控制器如何来找到这个Handler处理器呢?处理器映射器记录的就是请求的url和处理的方法之间的映射关系,这个映射关系是怎么建立起来的呢?就是通过@RequestMapping这个注解来建立起来的,这个映射关系就相当于一个Map(key-value这种形式),key就是请求的url,value就是处理的Handler。现在,DispatcherServlet 将用户请求发送给处理器映射器 (HandlerMapping)

  3. 处理器映射器会根据你请求的url来找对应的处理器 ,找不到就会报错,如果找到之后,这时,它就会返回一个处理器执行链 ,这个处理器执行链里面除了有Handler之外,还有拦截器(这儿我们可以开发自己的拦截器),然后返回给前端控制器

  4. 前端控制器依然不能处理这个业务请求,它这时做的还有另外一件事情,因为返回Handler,它也不知道这个Handler是什么类型,因为在spring mvc中Handler除了可以是注解形式的之外,其实还可以是非注解形式的(非注解形式我们一般不用),前端控制器并不知道这个Handler到底是什么类型的,那就没办法执行它,那总得找个东西执行,这时它就会把这个事交给另外一个组件来处理,这个组件就叫处理器适配器,这个处理器适配器就是来适配不同类型的Handler。它就会根据你不同类型的Handler来选择不同类型的适配器来执行它。

  5. 假如当前Handler是注解形式的,那么它就会选择注解形式的处理器适配器来执行这个Handler 。Handler就执行了,也就是说我们Controller类中的那个方法就执行了,方法执行之后,里面的业务就处理了。

  6. 业务处理之后,最后返回一个ModelAndView。处理器适配器拿到这个结果是没有用的,它的作用就是执行这个Handler,把这个Handler执行完之后,它的事就做完了。

  7. 做完之后,拿到这个返回结果,那么它会原封不动地把这个返回结果扔给前端控制器,这时处理器适配器的事就做完了。

  8. 前端控制器拿到这个ModelAndView,它还是没有办法处理,它还是不能返回html,这时它要找到相应的jsp,因为ModelAndView即包含模型又包含视图,这个视图指定我们要用谁来渲染这个数据。我们要渲染数据,这时它就要找一个视图解析器来解析这个视图,由于这个视图也有很多种(我们最常见的视图是jsp,除了jsp,其实还有其他的,比如说还可以是报表,还可以是pdf,还可以是freemaker等),它会找不同的视图解析器来处理。因为现在我们最常用的视图是jsp,所以它就找到jsp对应的视图解析器。

  9. 找到这个视图解析器,它来把这个视图解析,解析完了之后它会返回一个View对象。

  10. 最后我们再调用这个视图解析器的渲染视图这个过程,渲染视图这个过程其实就是对于我们的jsp来说,就是把这个数据渲染成html。

  11. 最终渲染成html之后,就响应给用户

3、SpringMVC的使用

3.1 引入依赖
java 复制代码
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
</dependency>
3.2 配置web.xml
java 复制代码
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!-- 配置spring mvc的核心控制器 -->
    <servlet>
        <servlet-name>SpringMVCDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置初始化参数,用于读取SpringMVC的配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 配置servlet的对象创建的时间点:应用加载时创建。
        如果该元素的值为负数或者没有设置,则容器会当servlet被请求的时候加载。
        如果值为正整数时或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,越先被加载-->
        <load-on-startup>1</load-on-startup>
​
    </servlet>
    <!-- 所有的请求都会执行对应的这个方法 -->
    <servlet-mapping>
        <servlet-name>SpringMVCDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
3.3 配置springmvc.xml
java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
​
    <!-- 配置创建 spring 容器要扫描的包 -->
    <context:component-scan base-package="com.company"></context:component-scan>
​
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

学习后端服务器语言:

1.怎么配置接口路径 √

2.怎么编写请求方法 √

3.怎么获取参数 √

4.怎么响应数据 √

3.4 编写controller
  • @RequestMapping注解

    建立请求URL和处理方法之间的对应关系

    • 作用到类上:第一级访问路径

    • 作用到方法上:第二级访问路径

java 复制代码
// 当用户请求路径的时候,对应的方法就会被执行
// 路径的匹配方式是一级路径+二级路径
@Controller
@RequestMapping("/user") // 配置一级路径
public class UserController {
    @RequestMapping({"/queryAll"}) // 配置二级路径,
    public void queryAll() {
        System.out.println(getClass().getName() + " queryAll");
    }
​
    @RequestMapping("/create")
    public void create() {
        System.out.println(getClass().getName() + " create");
    }
​
    @RequestMapping() // 二级路径也可以不写
    public void user() {
        System.out.println(getClass().getName() + " user");
    }
}
3.5 请求类型设置
3.5.1 GET请求
@GetMapping
java 复制代码
@GetMapping("/delete")
@RequestMapping的method属性(也可以不配置,默认就是GET)
java 复制代码
@RequestMapping(value = "/update", method = RequestMethod.GET)
public void update() {
    System.out.println(getClass().getName() + " update");
}
3.5.2 POST请求
@PostMapping
java 复制代码
@PostMapping("/delete")
@RequestMapping的method属性
java 复制代码
@RequestMapping(value = "/update", method = RequestMethod.POST)
public void update() {
    System.out.println(getClass().getName() + " update");
}
3.6 获取参数
3.6.1 配置过滤器解决post请求中文乱码 web.xml
java 复制代码
<!--配置解决中文乱码过滤器-->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--初始化参数-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
3.6.2 通过HttpServletRequest参数获取
@GetMapping
public void query(HttpServletRequest req) {
    System.out.println(req.getParameter("name"));
}
3.6.3 直接在方法上定义形参

参数要和前端传的参数名一样

java 复制代码
@GetMapping("/create")
public void query(String name, Integer age) {
    System.out.println(name);
    System.out.println(age);
}
// 也可以手动指定
// 如果@RequestParam指定的参数默认是必须传的,如果没有会报错,需要加上个required=false
@GetMapping("/create")
public void query(String name, @RequestParam(value = "sex", required = false) Integer age) {
    System.out.println(name);
    System.out.println(age);
}
3.6.4 使用实体类接收

参数名和属性名匹配,会自动赋值

java 复制代码
@PostMapping("/update")
public void query(Student s) {
    System.out.println(s.getName());
    System.out.println(s.getId());
    System.out.println(s.getSex());
}
3.6.5 从路径获取
java 复制代码
@GetMapping("/delete/{name}") // 表示一个动态的值
public void query(@PathVariable String name) {
    System.out.println(name);
}
3.7 Restful风格规范

Restful 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制

增、删、改、查分别和POST、DELETE、PUT、GET

传统写法

增:xxx/user/create post

删:xxx/user/delete get

改:xxx/user/update post

查:xxx/user/query post/get
*

Restful风格

增:xxx/user post

删:xxx/user delete

改:xxx/user put

查:xxx/user get

java 复制代码
@GetMapping() 
public void user() {}
​
@PutMapping()
public void update() {}
​
@DeleteMapping()
public void delete() {}

4、小结

本章节我们学习了MVC三层模型、理解了什么是SpringMVC、SpringMVC的工作流程、学会使用SpringMVC封装不同请求、接收参数,可以发现使用SpringMVC写一个接口可以使用javaWeb方便多了,所以这也是为什么SSM比较流行的一个原因之一了。

下移章节我们将会对SpringMVC的后续内容继续学习,掌握SpringMVC的开发方式。

相关推荐
猷咪8 分钟前
C++基础
开发语言·c++
IT·小灰灰9 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧11 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q11 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳012 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾12 分钟前
php 对接deepseek
android·开发语言·php
vx_BS8133016 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683616 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计29 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673741 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos