实习------SpringMVC 框架学习

Spring MVC 是什么 (了解)

Spring MVC(全称 Spring Web MVC)是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架,是 Spring 为表示层(UI)开发提供的一整套完备的解决方案。Spring MVC 使用 MVC 架构模式的思想,将 Web 应用进行职责解构,把一个复杂的 Web 应用划分成模型(Model)、控制器(Contorller)以及视图(View)三层,有效地简化了 Web 应用的开发,降低了出错风险,同时也方便了开发人员之间的分工配合。

注:三层架构分为表示层(UI)、业务逻辑层(BLL)、数据访问层(DAL),表示层则包含前台页面和后台 Servlet

Spring MVC 各层的职责如下:

  • Model:负责对请求进行处理,并将结果返回给 Controller;

  • View:负责将请求的处理结果进行渲染,展示在客户端浏览器上;

  • Controller:是 Model 和 View 交互的纽带;主要负责接收用户请求,并调用 Model 对请求处理,然后将 Model 的处理结果传递给 View。

Spring MVC 本质是对 Servlet 的进一步封装,其最核心的组件是 DispatcherServlet,它是 Spring MVC 的前端控制器,主要负责对请求和响应的统一地处理和分发。Controller 接收到的请求其实就是 DispatcherServlet 根据一定的规则分发给它的。

Spring MVC 框架内部采用松耦合、可插拔的组件结构,具有高度可配置性,比起其他的 MVC 框架更具有扩展性和灵活性。此外,Spring MVC 的注解驱动(annotation-driven)和对 REST 风格的支持,也是它最具有特色的功能。

Spring MVC 的常用组件

Spring MVC 的常用组件如下表。

组件

提供者

描述

DispatcherServlet

框架提供

前端控制器,它是整个 Spring MVC 流程控制中心,负责统一处理请求和响应,调用其他组件对用户请求进行处理。

HandlerMapping

框架提供

处理器映射器,根据请求的 url、method 等信息查找相应的 Handler。

Handler

开发人员提供

处理器,通常被称为 Controller(控制器)。它可以在 DispatcherServlet 的控制下,对具体的用户请求进行处理。

HandlerAdapter

框架提供

处理器适配器,负责调用具体的控制器方法,对用户发来的请求来进行处理。

ViewResolver

框架提供

视图解析器,其职责是对视图进行解析,得到相应的视图对象。常见的视图解析器有 ThymeleafViewResolver、InternalResourceViewResolver 等。

View

开发人员提供

视图,它作用是将模型(Model)数据通过页面展示给用户。

Spring MVC 的特点

Spring MVC 具有以下特点:

  • Spring MVC 是 Spring 家族原生产品,可以与 IoC 容器等 Spring 基础设施无缝对接;

  • Spring MVC 支持各种视图技术,例如 JSP、Thymeleaf、 JSP 和 FreeMaker 等。

  • Spring MVC 基于原生的 Servlet 实现,通过功能强大的前端控制器 DispatcherServlet,对请求和响应进行统一处理;

  • Spring MVC 对表示层各细分领域需要解决的问题全方位覆盖,并提供一整套全面的解决方案;

  • 代码清新简洁,大幅度提升开发效率;

  • 内部组件化程度高,可插拔式组件即插即用,想要使用什么功能,配置相应组件即可;

  • 性能卓著,尤其适合现代大型、超大型互联网项目的开发。

MVC 设计模式 (了解)

MVC 模式,全称为 Model-View-Controller(模型-视图-控制器)模式,它是一种软件架构模式,其目标是将软件的用户界面(即前台页面)和业务逻辑分离,使代码具有更高的可扩展性、可复用性、可维护性以及灵活性。

通常情况下,一个完整的 Java Web 应用程序,其结构如下图所示。

实习------SpringMVC 框架学习_第1张图片

图1:Java Web 应用的结构

MVC 模式将应用程序划分成模型(Model)、视图(View)、控制器(Controller)等三层,如下图所示。

实习------SpringMVC 框架学习_第2张图片

图2:MVC 模式

分层

描述

Model(模型)

它是应用程序的主体部分,主要由以下 2 部分组成:

  • 实体类 Bean:专门用来存储业务数据的对象,它们通常与数据库中的某个表对应,例如 User、Student 等。

  • 业务处理 Bean:指 Service 或 Dao 的对象,专门用于处理业务逻辑、数据库访问。

一个模型可以为多个视图(View)提供数据,一套模型(Model)的代码只需写一次就可以被多个视图重用,有效地减少了代码的重复性,增加了代码的可复用性。

View(视图)

指在应用程序中专门用来与浏览器进行交互,展示数据的资源。在 Web 应用中,View 就是我们常说的前台页面,通常由 HTML、JSP、CSS、JavaScript 等组成。

Controller(控制器)

通常指的是,应用程序的 Servlet。它负责将用户的请求交给模型(Model)层进行处理,并将 Model 层处理完成的数据,返回给视图(View)渲染并展示给用户。

在这个过程中,Controller 层不会做任何业务处理,它只是 View(视图)层和 Model (模型)层连接的枢纽,负责调度 View 层和 Model 层,将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。

MVC模式 VS 三层架构

和 MVC 模式类似,三层架构同样将系统划分成了 3 层:

  • 表示层(UI):用来实现与用户的交互,接收用户请求,并将请求交给业务逻辑层(BLL)和数据访问层(DAL)进行处理,最后将处理结果返回给用户。

  • 业务逻辑层(BLL):起到承上启下的作用,接收表示层传递来的请求,并针对业务对数据进行处理,以实现业务目标。

  • 数据访问层(DAL):用于实现与数据库的交互和访问,例如从数据库中获取数据、保存或修改数据库中的数据等。

虽然三层架构和 MVC 模式一样,都是将应用划分成了 3 层,但它们的划分方式是不同的。

下图展示了三层架构的划分方式,我们可以很清楚地分辨出它与 MVC 模式的不同。

实习------SpringMVC 框架学习_第3张图片

图3:三层架构

从上图可以看出,三层架构是由表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三个层次构成的,而 MVC 则是由视图(View)层、控制(Controller)层以及模型(Model)层,且它们之间并不是一一对应的。

三层架构和 MVC 模式中各层对应关系如下:

  • 三层架构中的表示层(UI)包含 HTML、JSP 等前台页面以及后台的 Servlet,即它相当于 MVC 模式中的 View 层 + Controller 层。

  • 三层架构中的业务逻辑层(BLL),则只包含了 Service 接口及其实现类(Servicelmpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Dao 和实体类。

  • 三层架构中的数据访问层(DAL),则只包含了 Dao 接口及其实现类(DaoImpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Service 和实体类。

三层架构将应用中的各个模块划分为表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)等三层,各层之间采用接口相互访问,并通过实体类作为数据传递的载体。不同的实体类一般对应于数据库中不同的数据表,且实体类的属性与数据库表的字段名一一对应 。

从上面的划分方式来看,三层架构和 MVC 模式确实是不一样的,但从它们的核心来看,两者又是一样的,它们的核心都是“分层、解耦”。

MVC 的工作流程

MVC 的工作流程如下:

  1. 用户发送请求到服务器;

  1. 在服务器中,请求被控制层(Controller)接收;

  1. Controller 调用相应的 Model 层处理请求;

  1. Model 层处理完毕将结果返回到 Controller;

  1. Controller 再根据 Model 返回的请求处理结果,找到相应的 View 视图

  1. View 视图渲染数据后最终响应给浏览器

MVC 的优点

MVC 模式具有以下优点:

  • 降低代码耦合性:在 MVC 模式中,三层之间相互独立,各司其职。一旦某一层的需求发生了变化,我们就只需要更改相应层中的代码即可,而不会对其他层中的代码造成影响。

  • 有利于分工合作:在 MVC 模式中,将应用系统划分成了三个不同的层次,可以更好地实现开发分工。例如,网页设计人员专注于视图(View)层的开发,而那些对业务熟悉的开发人员对 Model 层进行开发,其他对业务不熟悉的开发人员则可以对 Controller 层进行开发。

  • 有利于组件的重用在 MVC 中,多个视图(View)可以共享同一个模型(Model),大大提高了系统中代码的可重用性。

MVC 的不足

MVC 模式存在以下不足之处:

  • 增加了系统结构和实现的复杂性:对于简单的应用,如果也严格遵循 MVC 模式,按照模型、视图与控制器对系统进行划分,无疑会增加系统结构的复杂性,并可能产生过多的更新操作,降低运行效率。

  • 视图与控制器间的联系过于紧密:虽然视图与控制器是相互分离的,但它们之间联系却是十分紧密的。视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了它们的独立重用。

  • 视图对模型数据的低效率访问:视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

MVC 并不适合小型甚至中型规模的项目,花费大量时间将 MVC 应用到规模并不是很大的应用程序中,通常会得不偿失,因此对于 MVC 设计模式的使用要根据具体的应用场景来决定

Spring MVC 和 Struts2的区别(了解)

一、拦截机制的不同

  Struts2是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype,然后通过setter,getter吧request数据注入到属性。Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了,只能设计为多例。

  SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。

  Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。

二、底层框架的不同

  Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

三、性能方面

  Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。所以,SpringMVC开发效率和性能高于Struts2。

四、配置方面

  spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高。

附注:拦截器与过滤器的区别

  1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。

  1. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

  1. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

  1. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

  1. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

*Spring MVC 视图解析器(熟悉)

好文参考:https://www.cnblogs.com/lixiuming521125/p/16000192.html

好文参考:https://www.cnblogs.com/diumyself/p/16223554.html

好文参考:https://blog.csdn.net/howeres/article/details/124941519

好文参考:https://blog.csdn.net/Eaeyson/article/details/125205228

Spring MVC 执行流程 (熟悉)

Spring MVC 执行流程如图 1 所示。

实习------SpringMVC 框架学习_第4张图片

图1:Spring MVC 工作流程

SpringMVC 的执行流程如下

  1. 用户通过浏览器发起一个 HTTP 请求,该请求会被 DispatcherServlet(前端控制器)拦截;

  1. DispatcherServlet 调用 HandlerMapping(处理器映射器)找到具体的处理器(Handler)及拦截器,最后以 HandlerExecutionChain 执行链的形式返回给 DispatcherServlet。

  1. DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);

  1. HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(即 Controller 控制器)对请求进行处理;

  1. Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC 的底层对象,包括 Model 数据模型和 View 视图信息);

  1. HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;

  1. DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;

  1. ViewResolver 解析完成后,会将 View 视图并返回给 DispatcherServlet;

  1. DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);

  1. 视图负责将结果显示到浏览器(客户端)。

Spring MVC 常用组件

Spring MVC 的常用组件共有 6 个,它们分别是: DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器)、ViewResolver(视图解析器)和 View(视图)。

下表对各个组件的功能说明如下

组件

提供者

说明

DispatcherServlet(前端控制器)

由框架提供

它是 Spring MVC 的核心,其本质就是一个 Servlet。

前端控制器,它是整个 Spring MVC 流程控制中心,负责统一处理请求和响应,调用其他组件对用户请求进行处理。

它负责将所有的请求进行统一分发,相当于一个 Spring MVC 的流程控制中心,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。

HandlerMapping(处理器映射器)

由框架提供

负责根据请求的 url、method 等信息查找响应的 Handler 处理器(即 Controller 控制器方法)。

Handler(处理器)

由开发人员提供

也就是我们常说的 Controller 控制器,负责在 DispatcherServlet 的控制下,对具体的用户请求进行处理。

HandlerAdapter(处理器适配器)

由框架提供

它负责根据 HandlerMapping 映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)方法。

ViewResolver(视图解析器)

由框架提供

通过 ModelAndView 对象中的 View 信息对逻辑视图名进行解析,将其解析成真正的视图 View(例如 ThymeleafView、InternalResourceView、RedirectView 等),并返回给 DispatcherServlet。

View(视图)

View 对象本身由框架提供,但视图所对应的前端页面(例如 JSP、HTML)则需要开发人员自行编写

将 Model 模型数据通过页面展示给用户。

@Controller 和@RequestMapping 注解(熟悉)

@Controller 注解

@Controller 注解可以将一个普通的 Java 类标识成控制器(Controller)类,示例代码如下。

package net.biancheng.controller;

import org.springframework.stereotype.Controller;

@Controller
public class IndexController {
    // 处理请求的方法
}

在一个类上添加@Controller注解,表明了这个类是一个控制器类,可以支持同时处理多个请求。Spring使用扫描机制查找应用程序中所有用了这个注解的控制器类。分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,而使用@RequestMapping注解的方法才是真正处理请求的处理器

注意:这里注意@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。单单使用@Controller 标记在一个类上还不能真正意义上的说它就是Spring MVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。

Spring MVC 是通过组件扫描机制查找应用中的控制器类的,为了保证控制器能够被 Spring MVC 扫描到,我们还需要在 Spring MVC 的配置文件中使用 标签,指定控制器类的基本包(请确保所有控制器类都在基本包及其子包下),示例代码如下。


@RequestMapping 注解

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。

Spring MVC 的前端控制器(DispatcherServlet)拦截到用户发来的请求后,会通过 @RequestMapping 注解提供的映射信息找到对应的控制器方法,对这个请求进行处理。

@RequestMapping 注解的使用方式

@RequestMapping 既可以标注在控制器类上,也可以标注在控制器方法上。

1. 修饰方法

当 @RequestMapping 注解被标注在方法上时,value 属性值就表示访问该方法的 URL 地址。当用户发送过来的请求想要访问该 Controller 下的控制器方法时,请求路径就必须与这个 value 值相同,示例代码如下。

@Controller
public class HelloController {

    @RequestMapping("/login")
    public String welcome() {
        return "login";
    }
}
2. 修饰类

当 @RequestMapping 注解标注在控制器类上时,value 属性的取值就是这个控制器类中的所有控制器方法 URL 地址的父路径。也就是说,访问这个 Controller 下的任意控制器方法都需要带上这个父路径。

@Controller
@RequestMapping(value = "/springmvc")
public class HelloController {

    @RequestMapping("/login")
    public String welcome() {
        return "login";
    }
}

例如,在上面的控制类中,用户想要访问 HelloController 中的 welcome() 方法,请求的地址就必须带上父路径“/springmvc”,即请求地址必须为“/springmvc/login”。

@RequestMapping 注解的属性

@RequestMapping 注解中提供了多个可用属性,下面我们就对其中几个比较常用的属性进行介绍。

1. value 属性

在 @RequestMapping 注解中,value 属性用来设置控制器方法的请求映射地址。所有能够匹配到该请求映射地址的请求,都可以被该控制器方法处理,示例代码如下。

@RequestMapping(value = "/register")

value 属性是 @RequestMapping 注解的默认属性,如果我们在 @RequestMapping 注解中只设置了一个 value 属性,则该属性名可以被省略,示例代码如下。

//省略 value 属性名
@RequestMapping( "/register")

2. name 属性

name 属性相当于方法的注释,用于解释这个方法是用来干什么的,使方法更易理解。

例如,下面的代码表示 getUsers() 方法是一个用来获取用户信息的控制器方法。

@RequestMapping(value = "toUser",name = "获取用户信息")
public String getUsers() {
    ……
}

3. method 属性

method 属性用来设置控制器方法支持的请求方式。如果一个控制器方法没有设置 @RequestMapping 注解的 method 属性,则说明该控制器方法支持全部请求类型,可以处理所有类型的请求。

method 属性的取值是一个 RequestMethod 类型的数组,表示一个控制器方法支持多种方式的请求,常用的请求方式有 GET、POST、DELETE、PUT 等。

例如,控制器方法只支持 GET 方式的请求,代码如下。

@RequestMapping(value ="/toUser",method = RequestMethod.GET)

我们也可以为同一个控制器方法指定支持多种类型的请求。例如,一个方法既支持 GET 方式的请求,也支持 POST 方式的请求,代码如下。

@RequestMapping(value = "/toUser",method = {RequestMethod.GET,RequestMethod.POST})

4. params 属性

params 属性用于指定请求中的参数,只有当请求中携带了符合条件的参数时,控制器方法才会对该请求进行处理。

我们可以通过以下 4 种表达式来对请求的参数进行配置。

序号

表达式

含义

"param"

请求中必须携带名为 param 的参数

"!param"

与表达式 ① 的含义完全相反,请求中不能携带名为 param 的参数

"param=value"

请求中必须携带名为 param 的参数,且参数的取值必须为:value

"param!=value"

与表达式 ③ 的含义完全相反,请求中不能携带参数:param = value。

params 属性的取值是一个字符串类型的数组,表示只有请求中同时携带了 params 属性指定的全部参数时,控制器方法才会对该请求进行处理。

例如,控制器方法 testParam() 的代码如下:

@RequestMapping(value = "/testParam", params = {"name=C语言中文网", "url=http://c.bianheng.net"})
@ResponseBody
public String testParam() {
    return "success";
}

以上代码表示,只有当请求中同时携带 name 和 url 两个请求参数,且参数值必须分别为 “C语言中文网” 和“http://c.biancheng.net”时,控制器方法 testParam() 才会对该请求进行处理 。

5. headers 属性

headers 属性用于设置请求中请求头信息,只有当请求中携带指定的请求头信息时,控制器方法才会处理该请求。

我们可以通过以下 4 种表达式来指定请求中的请求头信息。

序号

表达式

含义

"header"

请求必须携带请求头信息:header

"!header"

与表达式 ① 的含义完全相反,请求中不能携带请求头信息:header

"header=value"

请求中必须携带请求头信息:header=value 。

"header!=value"

与表达式 ③ 的含义完全相反,请求中不能携带请求头信息:header=value。

header 属性是一个字符换类型的数组,表示只有当请求同时携带数组中规定的所有头信息时,控制器方法才会对该请求进行处理。

例如,控制器方法 method() 的代码如下。

@RequestMapping(value = "toUser",headers = "Referer=http://c.biancheng.net")
public String metnod() {
    ……
}

在以上代码中,只有当请求的头信息中包含“Referer=http://c.biancheng.net”时,控制器方法 method() 才会处理该请求。

Spring MVC 传递参数 (熟悉)

1、使用Model对象(常用)

(1)使用model对象往前台传递数据 attribute

实习------SpringMVC 框架学习_第5张图片

(2)在jsp中接收从后台传递过来的参数

实习------SpringMVC 框架学习_第6张图片

2、使用HttpServletRequest对象

(1)使用HttpServletRequest对象往前台传递数据

实习------SpringMVC 框架学习_第7张图片

(2)jsp中接收,同上!!!

3、使用Map对象

把Model改成Map即可。

Spring MVC 重定向和转发(熟悉)

请求转发(Forward)

请求转发是一种在服务器内部的资源跳转方式,简单来说,当客户浏览器发送http请求到web服务器中,web服务器接受请求后调用内部servlet方法完成请求处理和转发资源给同一个web容器下的另一资源做处理,最后将目标资源response给客户

工作原理及特点

实习------SpringMVC 框架学习_第8张图片

比如图中web容器(Tomcat)有两个资源(A和B),若浏览器请求资源A的时候,资源A处理了一部分,然后跳转到资源B,让资源B接着处理,资源B处理完成后做出响应到客户端。资源A跳转到资源B的这个过程就叫转发。

实现代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //获取请求转发器对象,调用forward()方法,请求转发
    RequestDispatcher requestDispatcher = request.getRequestDispatcher("跳转资源的路径").forward(requset,response);
}

RequestDispatcher requestDispatcher = request.getRequestDispatcher("跳转资源的路径").forward(requset,response);

特点

1. 请求转发资源间共享数据,图中资源A处理了一部分数据后把其他数据转交给资源B处理,所以在这过程中资源之间数据是共享的。

2. 浏览器地址栏路径不发生变化,只能转发到当前服务器的内部资源,浏览器只做了一次请求。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

Response完成重定向(Redirect)

重定向(Redirect)是一种资源跳转的方式,一般用来解决登录进入主页、跨域访问、系统维护等等都使用重定向技术,比如当系统进行维护时,用户若发起请求,系统将会告诉浏览器重定向访问指定的url。

简单来说,当浏览器发起请求给资源A时,资源A发现浏览器发起的请求自身处理不了,但是知道资源B可以处理,这时候资源A就会告诉浏览器说这次请求处理不了,请找资源B处理并且告诉资源B的访问路径,浏览器会自动去请求资源B。

工作原理及特点

实习------SpringMVC 框架学习_第9张图片

客户浏览器发送http请求后,web服务器中资源A接受请求后无法处理,资源A将会发送302状态码响应及对应新的location(资源B)给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址。

实现代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //旧方法
    //response.setStatus(302);
    //response.setHeader("location","资源B的路径");
    
    //其中资源B的路径需要添加虚拟目录
    response.sendRedirect("资源B的路径");
}

response.sendRedirect("资源B的路径");

特点

1. 浏览器地址栏路径发生变化

2. 可以重定向到任意位置的资源(服务器内部、外部均可)

3. 浏览器发起两次请求,不能在多个资源使用request共享资源

重定向和请求转发的区别

  • 转发和重定向是两种不同的请求处理方式,转发是服务器行为,重定向是客户端行为

  • 请求转发过程中,数据在同一个web服务器中得到共享,因为浏览器只做了一次访问请求,浏览器地址栏路径不发生变化,为同一个request域;而重定向中,浏览器做了两次请求,浏览器地址栏路径发生变化,请求并不是同一个request域。

Spring MVC怎么样设定重定向和转发的?

一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理。如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和redirect: 当成指示符,其后的字符串作为 URL 来处理。

(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"

@RequestMapping("/springMvc")
@Controller
public class handler {
    //测试转发
    @RequestMapping("/testRedirect")
    public String testRedirect(){
        System.out.println("testRedirect");
        return "forward:/index.jsp";
    }
 
}

(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

@RequestMapping("/springMvc")
@Controller
public class handler {
    //测试重定向
    @RequestMapping("/testRedirect")
    public String testRedirect(){
        System.out.println("testRedirect");
        return "redirect:/index.jsp";
    }
 
}

*@ModelAttribute 注解 (熟悉)

好文参考:https://www.cnblogs.com/bigdatalearn/p/6c1cabd5c64bf43d8dcc303e07d1fe8b.html

好文参考:https://blog.csdn.net/weixin_45007916/article/details/107880908

Spring MVC 类型转换器(了解)

为什么仅仅通过一些注解,控制器方法就能够得到各种类型的参数,其实这都要归功于 Spring MVC 的类型转换机制。

Spring 提供了一种 Converter(类型转换器)的类型转换工具。在 Spring MVC 中,它的作用是在控制器方法对请求进行处理前,先获取到请求发送过来的参数,并将其转换为控制器方法指定的数据类型,然后再将转换后的参数值传递给控制器方法的形参,这样后台的控制器方法就可以正确地获取请求中携带的参数了。

内置的类型转换器

Spring MVC 框架默认提供了许多内置的类型转换器,主要包括以下几种类型。

1)标量转换器

名称

作用

StringToBooleanConverter

String 到 boolean 类型转换

ObjectToStringConverter

Object 到 String 转换,调用 toString 方法转换

StringToNumberConverterFactory

String 到数字转换(例如 Integer、Long 等)

NumberToNumberConverterFactory

数字子类型(基本类型)到数字类型(包装类型)转换

StringToCharacterConverter

String 到 Character 转换,取字符串中的第一个字符

NumberToCharacterConverter

数字子类型到 Character 转换

CharacterToNumberFactory

Character 到数字子类型转换

StringToEnumConverterFactory

String 到枚举类型转换,通过 Enum.valueOf 将字符串转换为需要的枚举类型

EnumToStringConverter

枚举类型到 String 转换,返回枚举对象的 name 值

StringToLocaleConverter

String 到 java.util.Locale 转换

PropertiesToStringConverter

java.util.Properties 到 String 转换,默认通过 ISO-8859-1 解码

StringToPropertiesConverter

String 到 java.util.Properties 转换,默认使用 ISO-8859-1 编码

2)集合、数组相关转换器

名称

作用

ArrayToCollectionConverter

任意数组到任意集合(List、Set)转换

CollectionToArrayConverter

任意集合到任意数组转换

ArrayToArrayConverter

任意数组到任意数组转换

CollectionToCollectionConverter

集合之间的类型转换

MapToMapConverter

Map之间的类型转换

ArrayToStringConverter

任意数组到 String 转换

StringToArrayConverter

字符串到数组的转换,默认通过“,”分割,且去除字符串两边的空格(trim)

ArrayToObjectConverter

任意数组到 Object 的转换,如果目标类型和源类型兼容,直接返回源对象;否则返回数组的第一个元素并进行类型转换

ObjectToArrayConverter

Object 到单元素数组转换

CollectionToStringConverter

任意集合(List、Set)到 String 转换

StringToCollectionConverter

String 到集合(List、Set)转换,默认通过“,”分割,且去除字符串两边的空格(trim)

CollectionToObjectConverter

任意集合到任意 Object 的转换,如果目标类型和源类型兼容,直接返回源对象;否则返回集合的第一个元素并进行类型转换

ObjectToCollectionConverter

Object 到单元素集合的类型转换

Spring MVC 对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换。因此,通常情况下 Spring MVC 提供的这些类型转换器可以满足开发人员大多数的类型转换需求的。

注意:在使用内置类型转换器时,请求参数输入值需要与接收参数类型相兼容,否则会报 400 错误。

Spring MVC 数据格式化(了解)

在实际的项目开发中,经常会涉及到一些需要进行格式化的数据,例如金额、日期等。以金额为例,当金额为 10 万元时,在比较正式的场合往往要写成 ¥100000;而日期也可以被写作多种格式,例如 yyyy-MM-dd、yyyy-MM-dd hh:ss:mm 等。这些数据都要经过一定的格式化处理才能够正常使用。

Formatter 接口

Spring 提供了一个 Formatter 接口, T 表示目标数据类型,它被称为格式化转换器

Formatter 的作用与 Converter(类型转换器)相似,都是可以将一种数据类型转换成另一种数据类型。但不同的是,Formatter 的源类型必须是 String 类型,而 Converter 的源类型可以是任意数据类型

内置格式化转换器

Spring MVC 默认提供了多个内置的格式化器,通过它们,我们可以轻松地实现对日期(Date)类型和数值(Number)类型数据的格式化工作,具体如下。

内置格式化器

说明

NumberFormatter

实现 Number 与 String 之间的解析与格式化。

CurrencyFormatter

实现 Number 与 String 之间的解析与格式化(带货币符号)。

PercentFormatter

实现 Number 与 String 之间的解析与格式化(带百分数符号)。

DateFormatter

实现 Date 与 String 之间的解析与格式化。

虽然 Formatter 与 Converter 存在一定的差异,但格式化转换本质上还是属于“类型转换”的范畴,因此在 Spring MVC 中 Formatter(格式化转换器)实际上是委托给 Converter 机制实现的

Spring 的格式化模块中定义了一个 FormattingConversionService 类,它是 ConversionService 接口(类型转换器的服务接口)的实现类。它与其他的类型转换器实现类不同,它不仅具有类型转换功能,还具有格式化转换功能。

Spring MVC 还专门为 FormattingConversionService 提供了一个名为 FormattingConversionServiceFactroyBean 的工厂类,它主要作用就是在 Spring 上下文中构造 FormattingConversionService 的实例。

除此之外,FormattingConversionServiceFactroyBean 还为以下 2 个格式化注解提供了支持,使得我们可以更加方便地使用 Spring MVC 内置的格式化器,对数据进行格式化转换。

格式化注解

说明

@DateTimeFormat 注解

使用该注解,能够实现对日期类型数据的格式化

@NumberFormat 注解

使用该注解,能够实现对数值类型数据的格式化

我们知道,只要 Spring MVC 的配置文件中配置一个 标签,Spring MVC 在启动时就会自动初始化一个 FormattingConversionServiceFactoryBean 类型的实例:ConversionService。

也就是说,我们只要在 Spring MVC 配置文件中配置了 标签,就可以直接在 Spring MVC 项目中使用 @NumberFormat 注解和 @DateTimeFormat 注解,对 Number 类型和 Date 类型数据进行格式化转换。

日期格式化

@DateTimeFormat 注解可对 java.util.Date、java.util.Calendar、java.long.Long 等时间类型的数据进行标注,以实现对日期类型的数据进行格式化处理。

@DateTimeFormat 注解主要包含以下 3 个属性。

属性

类型

说明

pattern

String

用于指定解析或格式化日期时间的模式,其常用取值包括 yyyy-MM-dd、yyyy-MM-dd hh:mm:ss 等。

iso

DateTimeFormat.ISO

用于指定解析或格式化日期时间的 ISO 模式,其取值有 4 种:

  • DATE:yyyy-MM-dd

  • TIME:hh:mm:ss:SSSZ

  • DATE_TIME:yyyy-MM-dd hh:mm:ss:SSSZ

  • NONE:无

style

String

用于指定日期时间的格式。

该属性由两个字符组成,第一个字符表示日期的格式,第二个字符表示时间的格式。

  • S:短日期/时间格式

  • M:中日期/时间格式

  • L:长日期/时间格式

  • F:完整日期/时间格式

其默认值为“SS”,即日期和时间都采用短格式。

数值格式化

@NumberFormat 注解可以用来格式化任何数字基本类型(如 int、long 等)或 java.lang.Number 类型的实例(如 BigDecimal、Integer 等)。

@NumberFormat 注解拥有两个互斥的属性,如下表。

属性

类型

说明

style

NumberFormat.Style

该属性用于指定数值的样式类型,其取值有以下 4 种:

  • DEFAULT:默认类型

  • NUMBER:正常数值类型

  • PERCENT:百分数类型

  • CURRENCY:货币数值类型

pattern

String

该属性用于自定义数值的样式星星,例如 #,###

代码演示:http://c.biancheng.net/spring_mvc/9678.html

Spring MVC 表单标签库(了解)

我们在进行 Spring MVC 项目开发时,一般会使用 EL 表达式和 JSTL 标签来完成页面视图的开发。其实 Spring 也有自己的一套表单标签库,通过 Spring 表单标签,可以很容易地将模型数据中的命令对象绑定到 HTML 表单元素

在使用 SpringMVC 的时候我们可以使用 Spring 封装的一系列表单标签,这些标签都可以访问到 ModelMap 中的内容。我们需要先在 JSP 中声明使用的标签,具体做法是在 JSP 文件的顶部加入以下指令:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

表单标签

使用 Spring MVC 的 form 标签主要有两个作用,第一是它会自动的绑定来自 Model 中的一个属性值到当前form对应的实体对象,默认是 command 属性,这样我们就可以在 form 表单体里面方便的使用该对象的属性了。第二是它支持我们在提交表单的时候使用除 GET 和 POST 之外的其他方法进行提交,包括 DELETE 和 PUT 等。

  
    
Name:
Age:

文本框

使用标签来渲染一个 HTML 文本框,等同于:

密码框

使用 标签来渲染一个 HTML 密码框,等同于:

文本域

使用标签来渲染一个 HTML 文本域,等同于: