深入理解Spring MVC上

Spring MVC 是一种基于 Spring 框架的 Web 框架,它提供了一种基于 Model-View-Controller(MVC)的设计模式,用于构建 Web 应用程序。在 Spring MVC 中,Controller 接受并处理 HTTP 请求,并将其转发给适当的 Service、Repository 或其他组件进行处理。处理完成后,Controller 将结果返回给 View 层,View 层将结果渲染成 HTML 页面返回给客户端。

Spring MVC 框架提供了一些内置的组件,例如 HandlerMapping、DispatcherServlet、ViewResolver 等,这些组件可以帮助开发者快速构建 Web 应用程序。

HandlerMapping 负责将客户端请求映射到处理请求的控制器(Controller)上。当一个请求到达 Spring 应用时,HandlerMapping会根据请求的 URL和其它条件来确定调用哪个控制器的哪个方法来处理请求。

DispatcherServlet是一个中央调度器,负责协调处理客户端请求、分发请求到对应的控制器(Controller)以及返回响应。DispatcherServlet 基于 Servlet API 提供了一个入口,它会拦截所有的客户端请求,并将请求发送到适当的处理程序进行处理。其主要作用如下:

  1. 接收客户端请求并进行处理:DispatcherServlet 监听客户端请求,并负责将请求发送到适当的处理程序进行处理。

  1. 委派请求到适当的处理程序:DispatcherServlet 使用 HandlerMapping 将请求映射到适当的处理程序。

  1. 处理请求并生成响应:DispatcherServlet 负责协调处理程序执行请求,并将结果返回给客户端。

在 Spring MVC 中,DispatcherServlet 可以配置多个,并且每个 DispatcherServlet 可以使用不同的配置文件,处理不同的 URL 请求。

ViewResolver 负责将控制器(Controller)返回的逻辑视图名(如 "index"、"login" 等)解析成实际的视图(View)对象,以便渲染成最终的响应内容并返回给客户端。具体来讲,ViewResolver负责两项任务:

  1. 解析逻辑视图名:当控制器处理完请求后,返回一个逻辑视图名,而不是实际的视图对象。因此,ViewResolver 的第一个作用就是将逻辑视图名解析成实际的视图对象,以便后续进行渲染和返回。

  1. 提供视图的查找和解析策略:ViewResolver 可以配置多个实现,每个实现都有不同的查找和解析策略,比如根据请求路径、请求参数、请求头等来决定哪个视图实现去处理请求。在 Spring MVC 中,ViewResolver 是一个接口,具体的实现有多种,比如 InternalResourceViewResolver、FreeMarkerViewResolver、VelocityViewResolver 等,它们分别对应了不同的视图技术,比如 JSP、FreeMarker、Velocity 等。

需要注意的是,DispatcherServlet和ViewResolver 只是 Spring MVC 框架中的一部分,它并不是 Spring 框架本身的核心组件。而 Spring 框架的核心组件是 ApplicationContext,它提供了 Spring 的核心功能,包括依赖注入、AOP 等。DispatcherServlet ,ViewResolver需要和 ApplicationContext 是协同工作的,加载和管理 Spring MVC 的相关组件和配置。

下面通过例子来实际看下在spring中DispatcherServlet和ViewResolver如何和ApplicationContext协同工作,加载和管理Spring MVC的相关组件和配置。在 Spring 中,ApplicationContext 可以通过加载 Spring MVC 配置文件(如 XML 文件)来管理 Spring MVC 的相关组件和配置。加载 Spring MVC 配置文件时,需要使用 org.springframework.web.servlet.DispatcherServlet 类作为前端控制器,并将其配置为 Web 应用程序的Servlet。具体步骤是:

1.在 Web 应用程序的 web.xml 文件中定义一个 Servlet,名称为 DispatcherServlet,并将其映射到一个 URL,以便它能够处理传入的 HTTP 请求。

在 DispatcherServlet 的初始化参数中指定 Spring MVC 配置文件的路径,这可以通过在 web.xml 文件中为 DispatcherServlet 添加 <init-param> 元素来完成。具体配置内容如下图所示:在spring-mvc-config.xml文件中指定了controller组件,viewResolver和interceptor。

在程序启动部分,添加代码使用了 AnnotationConfigWebApplicationContext 类来加载 Spring MVC 配置文件,并将其设置为 DispatcherServlet 的上下文。

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.example.config");
ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(context));
registration.setLoadOnStartup(1);
registration.addMapping("/");

上面的代码片段是采用xml文件配置方式,如果是spring boot,因为spring boot可以自动加载配置,会更加简单。具体来说是:Spring Boot使用@SpringBootApplication注解标记的主类(通常是一个包含main方法的类)被用作应用程序上下文的根。当应用程序启动时,Spring Boot会创建一个Spring应用程序上下文,并自动加载所有在classpath中的bean定义。这些bean定义包括@Configuration注解标记的配置类、@Component注解标记的组件以及其他Spring Boot自动配置类。

对于Spring MVC相关组件和配置,Spring Boot会自动加载WebMvcAutoConfiguration自动配置类,并为应用程序提供必要的基础设施。WebMvcAutoConfiguration包括一系列的自动配置类,它们用于配置视图解析器、处理器映射、HTTP消息转换器、静态资源处理等功能。这些自动配置类可以通过在应用程序的配置文件中进行配置和修改。

如下图所示:创建一个Spring MVC的配置类,该类可以使用@Configuration注解进行标注,并通过@EnableWebMvc启用Spring MVC的相关功能。在该配置类中自定义了ViewResolver和ResourceHandlers;另外,创建了Controller来返回视图逻辑名称,在 Controller 中返回 "hello" 作为逻辑视图名,ViewResolver 会将其解析为 "/WEB-INF/views/hello.jsp"。在主程序Application class中,因为添加了@SpringBootApplication注解,所以Spring的ApplicationContext会自动加载和管理Spring MVC的相关组件和配置,包括视图解析器、静态资源处理程序、控制器类等。

可以看到不管是xml配置方式,还是Java注解配置方式,在实际项目中可能都需要自定义配置ViewResolver,那么Spring提供了哪些ViewResolver呢?Spring提供了常用的六种ViewResolver:

InternalResourceViewResolver:是 Spring MVC 中最常用的视图解析器。它将逻辑视图名解析为 JSP、HTML、FreeMarker或其他模板,通常用于在 Web 应用程序中生成 HTML 响应。使用 InternalResourceViewResolver 可以配置前缀和后缀来指定视图的文件路径和扩展名。在配置的过程中,Spring MVC 会将逻辑视图名称添加到前缀和后缀之间,从而生成最终的视图路径。

ResourceBundleViewResolver :是一个支持国际化的视图解析器。它使用 Java Properties 文件来保存视图解析器的配置信息,同时支持根据区域设置(Locale)加载不同的视图。

XmlViewResolver: 是一个基于 XML 配置文件的视图解析器。它通过解析 XML 文件中的元素来生成 View 实例,并将其添加到视图解析器中。

VelocityViewResolver :是一个用于解析 Velocity 模板的视图解析器。它将逻辑视图名解析为 Velocity 模板文件,并将其渲染为 HTML。

FreeMarkerViewResolver :是一个用于解析 FreeMarker 模板的视图解析器。它将逻辑视图名解析为 FreeMarker 模板文件,并将其渲染为 HTML。

在前后端不分离的情况下,更多的场景是controller中返回视图名称,视图解析器将视图名称转换成实际的视图对象,进行渲染、显示。现在,大部分项目都是前后端分离的情况,对于后端的controller更多的是返回JSON格式或者text格式的数据,那么对于这类场景,spring mvc是如何处理的呢?

实际上,在Spring MVC中,视图解析器(View Resolver)和消息转换器(Message Converter)是两个关键组件,用于将控制器返回的数据转换为合适的格式并渲染到客户端。视图解析器主要负责根据控制器返回的视图名称(View Name)来定位视图,并将模型数据(Model Data)与视图进行合并渲染。消息转换器主要负责将控制器返回的数据转换为客户端需要的格式,如JSON、XML等。Spring MVC中自带了很多消息转换器,如MappingJackson2HttpMessageConverter(用于将对象转换为JSON)、StringHttpMessageConverter(用于将字符串转换为文本格式)等。当控制器返回JSON格式的数据时,Spring MVC会使用MappingJackson2HttpMessageConverter将数据转换为JSON格式,并将其渲染到客户端。此时,视图解析器并不会介入处理。因为JSON格式的数据并不需要进行视图渲染,所以Spring MVC会直接将JSON格式的数据返回给客户端。当然,如果控制器返回的数据格式不是JSON,而是HTML、XML等格式,则Spring MVC会根据配置的视图解析器(View Resolver)来定位视图,并将数据与视图进行合并渲染。在这个过程中,消息转换器不会介入处理。Spring MVC包含以下几种Message Converter组件:

  1. ByteArrayHttpMessageConverter:用于处理字节数组数据,例如图片和文件。

  1. StringHttpMessageConverter:用于处理文本字符串数据。

  1. ResourceHttpMessageConverter:用于处理org.springframework.core.io.Resource对象。

  1. SourceHttpMessageConverter:用于处理javax.xml.transform.Source对象。

  1. FormHttpMessageConverter:用于处理application/x-www-form-urlencoded和multipart/form-data格式的表单数据。

  1. MappingJackson2HttpMessageConverter:用于处理JSON格式的数据,并将其转换为Java对象。

  1. MappingJackson2XmlHttpMessageConverter:用于处理XML格式的数据,并将其转换为Java对象。

  1. Jaxb2RootElementHttpMessageConverter:用于处理XML格式的数据,并将其转换为Java对象,基于JAXB实现。

Spring MVC默认情况下会注册上述所有的Message Converter组件,以便能够处理不同的请求和响应数据类型。当Spring MVC收到请求时,会根据请求头信息中的Content-Type来选择合适的Message Converter进行处理,并将请求数据转换为Java对象。同样,当Spring MVC发送响应时,也会根据响应头信息中的Accept来选择合适的Message Converter进行处理,并将Java对象转换为响应数据。

以上就是对Spring MVC中主要概念的梳理,下一篇博客将用spring官网提供的spring mvc showcase的代码为例子,详细介绍spring mvc中常见场景如何实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taoli-qiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值