Spring MVC 如何体现 Model-View-Controller 各自的职责?它们之间是如何协作的?

Spring MVC 中的组件与 MVC 角色的对应:

  1. Controller (控制器):

    • 体现: 主要由我们开发时编写的带有 @Controller@RestController 注解的 Java 类及其内部的方法(通常称为 Handler 方法)来体现。
    • 职责:
      • 接收请求: 通过 @RequestMapping 及其变体 (@GetMapping, @PostMapping 等) 注解,将特定的 HTTP 请求(URL、HTTP 方法、参数等)映射到对应的 Handler 方法。DispatcherServlet 会根据 HandlerMapping 的结果找到这个 Controller 方法。
      • 处理用户输入: 解析请求中的数据,如查询参数 (@RequestParam)、路径变量 (@PathVariable)、请求体 (@RequestBody)、表单数据等,并将它们绑定到方法的参数上。
      • 调用业务逻辑 (与 Model 交互): 调用注入的 Service 层或其他业务逻辑组件来执行实际的业务操作、数据处理或数据获取。
      • 准备模型数据: 将处理结果或需要展示的数据(即 Model 数据)封装起来,以便传递给 View。这通常通过向方法参数中的 Model 对象添加属性,或者构建并返回一个 ModelAndView 对象来实现。
      • 选择视图: 返回一个逻辑视图名(String 类型),或者返回一个包含逻辑视图名和模型数据的 ModelAndView 对象。对于 RESTful 服务 (@RestController 或方法上使用 @ResponseBody),Controller 直接返回需要序列化的对象(如 POJO),此时响应体本身扮演了视图的角色。
  2. Model (模型):

    • 体现: 在 Spring MVC 中,Model 的体现是多方面的:
      • 数据载体 (Data Carrier): 最直接的体现是 Controller 传递给 View 的数据。Spring MVC 提供了 Model 接口(及其实现如 ModelMap)或 ModelAndView 类来充当这个数据容器。我门将需要展示的数据放入这些容器中。
      • 业务状态与逻辑 (Business State & Logic): 更深层次上,Model 代表了应用程序的核心。这通常是 Controller 调用的 Service 层和 Repository/DAO 层 Bean。这些 Bean 封装了业务规则、数据持久化逻辑以及应用程序的状态。Controller 与这些 Bean 交互来读取或修改应用状态。
      • 领域对象 (Domain Objects): Controller 处理或传递的普通 Java 对象(POJO),如 User, Product, Order 等,它们代表了业务领域中的实体。
    • 职责:
      • 封装数据: 持有需要传递给视图的数据(通过 ModelModelAndView)。
      • 执行业务逻辑: Service/Repository 层负责处理业务规则、数据验证、与数据库交互等核心任务。
      • 维护应用状态: 代表了应用程序当前的数据状态。
  3. View (视图):

    • 体现:
      • 视图模板: 各种模板引擎的文件,如 JSP 文件、Thymeleaf 模板 (.html)、Freemarker 模板 (.ftl) 等。
      • Spring 的 View 接口: Spring MVC 定义了一个 View 接口,以及针对不同视图技术的具体实现(如 JstlView, ThymeleafView)。ViewResolver 负责将逻辑视图名解析为具体的 View 实例。
      • 直接响应内容: 对于 RESTful 服务,由 HttpMessageConverter(如 Jackson 处理 JSON)将 Controller 返回的对象序列化后的内容(JSON, XML 等)也可以看作是一种特殊的视图。
    • 职责:
      • 呈现数据: 获取 Controller 传递过来的模型数据(从 ModelModelAndView 中提取)。
      • 渲染用户界面: 使用模型数据填充视图模板,生成最终的 HTML、JSON、XML 或其他格式的响应内容,呈现给用户。
      • 不包含业务逻辑: 视图应该尽量保持简单,只负责展示逻辑。

它们之间的协作流程 (由 DispatcherServlet 驱动):

  1. 请求入口: HTTP 请求到达 DispatcherServlet
  2. 寻找处理器: DispatcherServlet 查询 HandlerMapping,根据请求信息(URL, HTTP Method 等)找到能够处理该请求的 Controller 方法 (Handler)。
  3. 适配与调用: DispatcherServlet 通过 HandlerAdapter 来调用选定的 Controller 方法。HandlerAdapter 负责处理方法参数的解析和数据绑定(例如,将请求参数注入到 @RequestParam 标记的参数,将 JSON 请求体反序列化到 @RequestBody 标记的对象)。
  4. Controller 处理: Controller 方法执行:
    • 接收解析后的请求数据。
    • 调用 Service 层等(与 Model 交互)执行业务逻辑。
    • 将结果数据放入 Model 对象(或 ModelAndView)。
    • 返回逻辑视图名(String)或 ModelAndView 对象(或直接返回数据对象给 @ResponseBody)。
  5. 视图解析 (非 @ResponseBody): 如果 Controller 返回的是逻辑视图名或 ModelAndViewDispatcherServlet 会将逻辑视图名交给 ViewResolver
  6. 获取具体视图: ViewResolver 根据逻辑视图名解析得到具体的 View 实例(例如,一个指向特定 JSP 文件的 JstlView 对象)。
  7. 数据渲染: DispatcherServlet 将 Controller 准备好的 Model 数据传递给 View 实例。View 实例使用这些数据渲染最终的响应(例如,JSP 引擎执行 JSP 文件并生成 HTML)。
  8. REST 响应 (@ResponseBody): 如果 Controller 方法使用了 @ResponseBody 或属于 @RestControllerHandlerAdapter 会使用合适的 HttpMessageConverter 将返回的对象序列化为特定格式(如 JSON)并直接写入响应体。此过程通常跳过视图解析和 View 渲染步骤。
  9. 响应返回: DispatcherServlet 将最终生成的响应(渲染后的 HTML 或序列化后的数据)返回给客户端。

通过这种方式,Spring MVC 利用 DispatcherServlet 作为前端控制器,协调 HandlerMapping, HandlerAdapter, Controller, Model, ViewResolver, View 等组件,清晰的实现了 MVC 模式的功能分离,使得我们在开发时可以专注于各自的部分,构建出易于维护的 Web 应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰糖心书房

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

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

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

打赏作者

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

抵扣说明:

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

余额充值