34、请求处理-【源码分析】-Model、Map原理

34、请求处理-【源码分析】-Model、Map原理

在 Spring Boot 中,处理请求时,控制器方法可以接收 `Model` 和 `Map` 类型的参数,用于向视图传递数据。以下是 `Model` 和 `Map` 参数处理的原理分析:

1. 参数解析过程

**1.1 确定参数解析器**

当 Spring MVC 处理请求时,会遍历所有注册的 `HandlerMethodArgumentResolver` 实例,调用其 `supportsParameter` 方法,判断是否支持当前参数类型。

对于 `Model` 和 `Map` 类型的参数:

  • `ModelMethodProcessor` 和 `MapMethodProcessor` 这两个解析器会返回 `true`,因为它们支持处理这两种类型的参数。

**1.2 解析参数**

一旦确定了合适的参数解析器,就会调用其 `resolveArgument` 方法来解析参数:

  • **`ModelMethodProcessor`**

```java

@Override

public Object resolveArgument(MethodParameter parameter,

ModelAndViewContainer mavContainer,

NativeWebRequest webRequest,

WebDataBinderFactory binderFactory) throws Exception {

return mavContainer.getModel();

}

```

  • **`MapMethodProcessor`**

```java

@Override

public Object resolveArgument(MethodParameter parameter,

ModelAndViewContainer mavContainer,

NativeWebRequest webRequest,

WebDataBinderFactory binderFactory) throws Exception {

return mavContainer.getModel();

}

```

这两个解析器都返回了 `mavContainer.getModel()`,这意味着它们实际上使用的是同一个对象。

2. `ModelAndViewContainer` 的作用

`ModelAndViewContainer` 是一个重要的容器,用于存储模型数据和视图信息。在请求处理过程中:

  • **获取 `Model` 对象**

`mavContainer.getModel()` 方法会返回一个 `Model` 实例,通常是一个 `BindingAwareModelMap` 对象,它既是 `Model` 也是 `Map`。

  • **数据共享**

由于 `Model` 和 `Map` 参数都指向同一个 `BindingAwareModelMap` 对象,因此对它们的操作会互相影响。

3. 数据存储与传递

**3.1 添加数据**

在控制器方法中,通过以下方式添加数据:

  • **使用 `Model`**

```java

model.addAttribute("name", "张三");

```

  • **使用 `Map`**

```java

map.put("age", 18);

```

这些数据都会被添加到 `BindingAwareModelMap` 中。

**3.2 数据传递到视图**

请求处理完成后,Spring MVC 会将 `ModelAndViewContainer` 中的数据封装到 `ModelAndView` 对象中,然后调用视图渲染器进行渲染。

在渲染过程中,会调用 `exposeModelAsRequestAttributes` 方法:

```java

protected void exposeModelAsRequestAttributes(Map<String, Object> model,

HttpServletRequest request) throws Exception {

for (String name : model.keySet()) {

Object value = model.get(name);

if (value != null) {

request.setAttribute(name, value);

} else {

request.removeAttribute(name);

}

}

}

```

该方法会将模型数据中的所有属性添加到 `HttpServletRequest` 的请求域中,以便在视图中通过 `${name}` 表达式访问。

4. 示例代码

```java

@Controller

public class HelloController {

@GetMapping("/hello")

public String hello(Model model, Map<String, Object> map) {

model.addAttribute("name", "张三");

map.put("age", 18);

// 此时 model 和 map 指向同一个对象

System.out.println(model == map); // 输出 true

return "helloView";

}

}

```

在 `helloView.jsp` 中:

```jsp

<p>姓名:${name}</p>

<p>年龄:${age}</p>

```

5. 总结

  • **`Model` 和 `Map` 参数在 Spring Boot 中本质上是同一个对象,都是 `BindingAwareModelMap` 的实例。**

  • **通过 `Model` 或 `Map` 添加的数据最终都会被放入 `HttpServletRequest` 的请求域中,供视图访问。**

  • **这种机制简化了数据传递的过程,使得开发者可以方便地在控制器和视图之间共享数据。**


通过以上分析,我们深入理解了 Spring Boot 中 `Model` 和 `Map` 参数的处理原理,为开发 Web 应用提供了更清晰的思路。

相关推荐
毕设源码-赖学姐1 分钟前
【开题答辩全过程】以 高校体育场馆管理系统为例,包含答辩的问题和答案
java·spring boot
我真会写代码2 分钟前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
vx_Biye_Design3 分钟前
【关注可免费领取源码】房屋出租系统的设计与实现--毕设附源码40805
java·spring boot·spring·spring cloud·servlet·eclipse·课程设计
java干货7 分钟前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
_F_y7 分钟前
C语言重点知识总结(含KMP详细讲解)
c语言·开发语言
DN金猿8 分钟前
接口路径正确,请求接口却提示404
java·tomcat
毕设源码-郭学长9 分钟前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
无小道32 分钟前
Qt——常用控件
开发语言·qt
翱翔-蓝天32 分钟前
为什么“看起来很规范”的后端项目反而臃肿且性能下降
spring boot
Maynor9961 小时前
OpenClaw 玩家必备:用 AI 自动追踪社区最新动态
java·服务器·人工智能