方法参数与共享域
大约 4 分钟
handler 方法参数
SpringMVC 提供了一系列允许的handler方法参数类型,当方法中声明了这些类型的形参时,SpringMVC会自动封装对象并注入,其中包括原生Servlet API对象和一些SpringMVC的扩展对象。
见:Method Arguments :: Spring Framework
| Controller method argument 控制器方法参数 | Description |
|---|---|
jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse | 请求/响应对象 |
jakarta.servlet.http.HttpSession | 强制存在会话。因此,这样的参数永远不会为 null 。 |
java.io.InputStream, java.io.Reader | 用于访问由 Servlet API 公开的原始请求正文。 |
java.io.OutputStream, java.io.Writer | 用于访问由 Servlet API 公开的原始响应正文。 |
@PathVariable | 接收路径参数注解 |
@RequestParam | 用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。 |
@RequestHeader | 用于访问请求标头。标头值将转换为声明的方法参数类型。 |
@CookieValue | 用于访问Cookie。Cookie 值将转换为声明的方法参数类型。 |
@RequestBody | 用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。 |
java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap | 共享域对象,并在视图呈现过程中向模板公开。 |
Errors, BindingResult | 验证和数据绑定中的错误信息获取对象! |
示例:
/**
* 如果想要获取请求或者响应对象,或者会话等,可以直接在形参列表传入,并且不分先后顺序!
* 注意: 接收原生对象,并不影响参数接收!
*/
@GetMapping("api")
@ResponseBody
public String api(HttpSession session , HttpServletRequest request,
HttpServletResponse response){
response.addCookie(new Cookie("session",new Object().toString()));
return "api";
}四大共享域
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:ServletContext、HttpSession、HttpServletRequest、PageContext。
ServletContext应用域:ServletContext对象可以在整个 Web 应用程序中共享数据,是最大的共享域。一般可以用于保存整个 Web 应用程序的全局配置信息,以及所有用户都共享的数据。在ServletContext中保存的数据是线程安全的。HttpSession会话域:HttpSession对象可以在同一用户发出的多个请求之间共享数据,但只能在同一个会话中使用。比如,可以将用户登录状态保存在HttpSession中,让用户在多个页面间保持登录状态。HttpServletRequest请求域:HttpServletRequest对象可以在同一个请求的多个处理器方法之间共享数据。比如,可以将请求的参数和属性存储在HttpServletRequest中,让处理器方法之间可以访问这些数据。PageContext共享域:PageContext对象是在 JSP 页面Servlet 创建时自动创建的。它可以在 JSP 的各个作用域中共享数据,包括pageScope、requestScope、sessionScope、applicationScope等作用域。

请求域
SpringMVC 对请求域进行了拓展,提供了如下的方法参数,使用这些方法参数来存储数据,生命周期为一次请求,即请求域:
java.util.Map:普通的map,存储模型数据@RequestMapping("/attr/request/map") public String testAttrRequestMap( // 在形参位置声明Map类型变量,用于存储模型数据 Map<String, Object> map) { // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域 // 存入请求域这个动作也被称为暴露到请求域 map.put("requestScopeMessageMap", "i am very happy[map]"); return "target"; }org.springframework.ui.Model:存储模型数据@RequestMapping("/attr/request/model") public String testAttrRequestModel( // 在形参位置声明Model类型变量,用于存储模型数据 Model model) { model.addAttribute("requestScopeMessageModel","i am very happy[model]"); return "target"; }org.springframework.ui.ModelMap:存储模型数据@RequestMapping("/attr/request/mav") // handler 返回 ModelAndView 对象 public ModelAndView testAttrByModelAndView() { // 1.创建ModelAndView对象 ModelAndView modelAndView = new ModelAndView(); // 2.存入模型数据 modelAndView.addObject("requestScopeMessageMAV", "i am very happy[mav]"); // 3.设置视图名称,交给视图解析器查找视图 modelAndView.setViewName("target"); return modelAndView; }jakarta.servlet.ServletRequest:原生API操作请求域@RequestMapping("/attr/request/original") public String testAttrOriginalRequest( // 拿到原生对象,就可以调用原生方法执行各种操作 HttpServletRequest request) { request.setAttribute("requestScopeMessageOriginal", "i am very happy[original]"); return "target"; }
会话域 Session
通过在方法参数中接收Session对象,完成对会话域的操作。
@RequestMapping("/attr/session")
@ResponseBody
public String testAttrSession(HttpSession session) {
//直接对session对象操作,即对会话范围操作!
return "target";
}应用域 ServletContext
应用域在整个Web应用的生命周期中只有一个,故SpringMVC会自动将其装入IoC容器,在需要的Controller中可以声明私有属性,使用 @Autowired注入。
@Autowired
private ServletContext servletContext;
@RequestMapping("/attr/application")
@ResponseBody
public String attrApplication() {
servletContext.setAttribute("appScopeMsg", "i am hungry...");
return "target";
}