java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringMVC request域效果

SpringMVC中实现request域效果的几种方式

作者:步行cgn

本文一次讲清HttpServletRequest、Model、ModelMap、ModelAndView、Map参数、@ModelAttribute、RedirectAttributes等所有方式,帮你根据场景选择最合适的写法,感兴趣的可以了解一下

request 域的本质是“一次请求内共享数据”。在 Spring MVC 中,除了直接用 HttpServletRequest.setAttribute(),还有多种封装方式,底层最终都会把数据放入 request 域。下面按使用方式分类说明。

一、原生 HttpServletRequest

最直接的方式,Controller 方法声明 HttpServletRequest 参数,手动 setAttribute。

@GetMapping("/demo")
public String demo(HttpServletRequest request) {
    request.setAttribute("msg", "操作成功");
    return "demo";
}

JSP 或 Thymeleaf 中通过 ${msg} 读取。这种方式最底层,不依赖 Spring 的封装,但代码略显繁琐。

二、Model 接口

Model 是 Spring MVC 提供的模型接口,addAttribute() 添加的数据会自动放入 request 域。

@GetMapping("/demo")
public String demo(Model model) {
    model.addAttribute("msg", "操作成功");
    model.addAttribute("user", new User("张三"));
    return "demo";
}

Model 是一个接口,实际实现是 ExtendedModelMap,底层继承 ModelMap。

三、ModelMap

ModelMap 是 Model 的实现类,用法与 Model 基本一致,但它是具体类,提供了一些额外方法。

@GetMapping("/demo")
public String demo(ModelMap modelMap) {
    modelMap.addAttribute("msg", "操作成功");
    modelMap.put("user", new User("张三"));
    return "demo";
}

ModelMap 继承 LinkedHashMap<String, Object>,所以也可以用 put() 方法。日常开发中 Model 和 ModelMap 可以互换,推荐用 Model,面向接口。

四、ModelAndView

ModelAndView 同时封装了模型数据和视图名称,作为方法的返回值。

@GetMapping("/demo")
public ModelAndView demo() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("demo");
    mav.addObject("msg", "操作成功");
    mav.addObject("user", new User("张三"));
    return mav;
}

addObject() 添加的数据最终也会放入 request 域。ModelAndView 适合需要同时控制视图和数据的场景,但现代 Spring MVC 更推荐直接返回视图名 + Model 参数,代码更简洁。

五、直接使用 Map 参数

Spring MVC 支持在 Controller 方法中声明 Map<String, Object> 参数,添加到 Map 中的数据会被当作模型数据放入 request 域。

@GetMapping("/demo")
public String demo(Map<String, Object> map) {
    map.put("msg", "操作成功");
    map.put("user", new User("张三"));
    return "demo";
}

底层 Spring 会把这个 Map 包装成 Model 使用。这种方式写起来简洁,但语义不如 Model 明确,团队中如果约定用 Model,就不建议混用。

六、@ModelAttribute 注解

@ModelAttribute 有两种用法,都会把数据放入 request 域。

1. 标注在方法参数上

方法参数对象会被自动放入 Model,key 默认是类型名首字母小写。

@GetMapping("/demo")
public String demo(@ModelAttribute("user") User user) {
    // user 对象自动放入 request 域,key 为 "user"
    return "demo";
}

2. 标注在方法上

被 @ModelAttribute 标注的方法会在每个 Controller 方法执行前调用,返回值自动放入 Model,常用于准备公共数据。

@ModelAttribute("categories")
public List<Category> categories() {
    return categoryService.listAll();
}

@GetMapping("/demo")
public String demo() {
    // 可以直接在视图中使用 ${categories}
    return "demo";
}

这种方式适合全局共享的模型数据,比如下拉框选项、菜单数据。

七、RedirectAttributes(重定向场景)

RedirectAttributes 专门用于重定向时传递数据,它有两种添加方式,行为不同。

@PostMapping("/save")
public String save(User user, RedirectAttributes redirectAttributes) {
    userService.save(user);
    redirectAttributes.addAttribute("id", user.getId());        // 拼到 URL 上
    redirectAttributes.addFlashAttribute("msg", "保存成功");    // 暂存后取出
    return "redirect:/detail";
}

严格来说,RedirectAttributes 不是 request 域,但它是重定向场景下最常用的传参方式,需要和 request 域区分开。

八、@RequestAttribute(读取 request 域)

前面几种都是“写入”request 域。如果需要“读取”request 域中的数据,可以用 @RequestAttribute。

@GetMapping("/target")
public String target(@RequestAttribute("msg") String msg) {
    return "target";
}

通常配合请求转发使用:前一个请求 setAttribute,转发到目标方法,目标方法用 @RequestAttribute 读取。

九、各方式对比

方式写入 request 域返回值类型适用场景
HttpServletRequest✅视图名需要操作原生 Servlet API
Model✅视图名最常用,推荐
ModelMap✅视图名需要 Map 风格 API
ModelAndView✅ModelAndView同时控制视图和数据
Map 参数✅视图名简洁写法,语义略弱
@ModelAttribute 参数✅视图名表单对象绑定并放入模型
@ModelAttribute 方法✅任意全局公共模型数据
RedirectAttributes重定向场景重定向路径重定向传参,非严格 request 域

十、底层关系

Model、ModelMap、ModelAndView、Map 参数、@ModelAttribute,最终都会汇聚到 ModelAndViewContainer 的 Model 中。视图渲染时,Spring 会把 Model 中的数据遍历放入 HttpServletRequest 的 attributes 中,然后交给视图解析器渲染。

所以它们的效果等价:视图里都能用 ${key} 取到值,请求结束后数据随 request 一起销毁。

区别只在于写法、返回值和适用场景,运行时没有本质差异。

十一、怎么选

场景推荐方式
普通 Controller 返回视图 + 数据Model
需要同时控制视图名和数据ModelAndView
表单对象绑定并回显@ModelAttribute 参数
多个方法共享的公共数据@ModelAttribute 方法
需要操作原生 Servlet APIHttpServletRequest
重定向后传递一次性提示RedirectAttributes.addFlashAttribute()
读取转发过来的 request 域数据@RequestAttribute

日常开发中,Model 是最常用、最推荐的方式。ModelAndView 适合老项目或需要显式控制视图的场景。@ModelAttribute 方法适合准备全局数据。RedirectAttributes 只在重定向场景使用,且要注意它和 request 域的区别。

到此这篇关于SpringMVC中实现request域效果的几种方式的文章就介绍到这了,更多相关SpringMVC request域效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文