戏说 Spring MVC 框架

600 阅读5分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

Spring MVC 是 Spring 框架的一部分,和 Struts 一样都是属于 web 层框架,根据项目分层的思想,一个项目基本可以分为持久层,业务层和 web 层。而 Spring MVC 主要作用在 web 层,也叫表现层。

web 层核心的功能自然是处理用户的请求并返回数据,那我们就要介绍一下 Spring MVC 中是如何处理请求并返回数据的。首先来看一下它的大致流程。

图片

上图是框架中的大致方向,从用户发出请求开始,前端处理器接收请求,但是自己不干活,会把请求发送到不同的处理器,处理器中会调用业务方法进行处理,得到结果返回给前端控制器,控制器再将结果发送给 JSP 来渲染页面,最终将含有结果的 HTML 页面返回给浏览器。

仔细说一下,首先你要告诉我处理什么样的请求,不能来个阿猫阿狗我全接收了,这就需要我们在 web.xml 文件中配置一下什么样的请求才能进入框架。

请求是进来了,但是那是一串 URL 呀,框架需要分析这个请求呀,分析请求这个活前端控制器依旧不干,而是由处理器映射器 HandlerMapping 来处理。这个对象是 Spring MVC 提供好的,我们只需要配置一下就好,不要忘了 Spring 中强大的 IoC 功能。

处理器映射器的作用就在于,你给我一串 URL ,我来分析 URL,然后找到处理这个请求的包名+类名+方法名返回给控制器。找不到就报 404 呗。而这种 URL 和方法的映射关系,我们一般使用注解@RequestMapping 在方法的上面配置。

你以为控制器知道具体的方法以后就会执行嘛,想太多,这时候处理器适配器就出现了,这就是控制器下面的二腿子啊,它也不干活,那谁来处理啊,那肯定是我们牛逼哄哄的程序员了。

你自己配的方法的 URL ,你不写方法你还想飞不成啊!

图片

肯定是需要自己写处理 URL 的逻辑呀,有了包名+类名+方法名之后,前端控制器和处理器适配器说 “去看看这个方法在那里,处理一下”。处理器适配器一看,这不就是隔壁家的二狗子嘛,然后把二狗子叫来了,去处理一下请求吧。

好了,终于到找真正干活的人了,就是我们可爱的程序员啊,然后,不出意外的情况下,方法返回了一个结果给到前端控制器。这时候老大又发话了,“视图解析器你过来一下,给你个结果,去把结果渲染到页面上去。“

视图解析器拿到结果和页面(不一定是 JSP,但是常见的是 JSP)一顿操作,该填充的填充,就得到了一个 HTML 页面,然后这些完美的二进制通过网线就从远方的服务器传到了浏览器中供用户欣赏。

以上说的就是一个请求在 web 层中 Spring MVC 框架处理的逻辑,要注意呦,我们手写的处理器 Controller 中会调用 Service 层的东西,那就是业务层的范畴了。详细的还可以看看下面这张图。

图片

但事情哪有那么顺利呢,总会出现异常啊,什么 404,500,为了使我们的用户大人蒙在鼓里,我们还可以配置一个全局的异常处理类。只需要实现 HandlerExceptionResolver 即可,当然,我们也要在 Spring 中注册一下实现类。

这样在发生异常的时候,我们可以设置跳转到一个卡哇伊的页面,殊不知其实是系统出现问题了……

正常的和不正常的 Spring MVC 都能处理,但你以为这样就够了嘛,不,它还为我们提供了许多其它的功能。

还有什么上传图片啊,简直就是逆天啊,直接把图片当成一个参数传到后台了,当然,肯定需要一定的条件,比方说前台 form 必须有 enctype,后台接收图片的参数时必须使用 MultipartFile 接口且形参名一致,而且实现类还是固定的,我们需要注入一下 CommonsMultipartResolver 类。

还有一个拦截器的概念,这就是 AOP 编程的一个体现呀,一夫当关,万夫莫开。而我们需要做的就是在配置文件中使用标签配置一下拦截器拦截的路径和拦截器类。

<mvc:interceptor> 

在拦截器类中我们就可以处理具体的逻辑了,比方说,验证用户是否登录呀。给用户分类呀,不用的用户跳转的页面不一致。

最后说一下 Spring MVC 和 Struts2 的区别。

1、Spring MVC 的入口是一个 Servlet 即前端控制器,而 Struts2 入口是一个 Filter 过滤器。

2、Spring MVC 是基于方法开发 (一个 url 对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),Struts2 是基于类开发,传递参数是通过类的属性,只能设计为多例。

3、Struts2 采用值栈存储请求和响应的数据,通过 OGNL 存取数据, Spring MVC 通过参数解析器是将 request 请求内容解析,并给方法形参赋值,将数据和视图封装成 ModelAndView 对象,最后又将 ModelAndView 中的模型数据通过 request 域传输到页面。Jsp 视图解析器默认使用 jstl 表达式。