SpringMVC和Servlet域对象
1.Servlet域对象介绍
1.1 三大域对象
Servlet有三个域对象分别是请求域(request)、会话域(seesion)和应用域(application)。
域对象与数据的共享密不可分。通过方法可以向域对象中存储key:value
键值对形式的数据。三个域对象都有以下通用方法,通过这些方法来达到存储数据的目的。
//向与中存储数据
void setAttribute(String name,Obeject obj);
//从域中获取数据
void getAttribute(String name);
//删除域中的数据
void removeAttribute(String name);
1.2 三大域对象的使用范围
request:
接口名:HttpServletRequest
请求域的数据只在一个请求的范围中奏效。一次请求一个请求域。在资源A跳到资源B的过程中是一次请求。如果想让资源A和资源B共享一个数据,可以将数据放到请求域中。
session
接口名:Httpsession
session对象代表一次完整的会话。什么是一次完整的会话。比如你打开B站看搞笑视频,只要浏览器没有关闭,那么就是一次会话。可以借鉴无痕浏览B站并且登录。你会发现你使用无痕浏览登录B站以后,只要网页不关闭,在一定时间类,你的登录信息是有的,一旦关闭,就需要重新登录。背后的原理其实就是每个会话都对应一个JSESSIONID
,它生成以后会以cookie的存储方式存储在浏览器客户端。
如果你使用重定向(注意请求转发和重定向不一样),重定向是一次请求,但是请求转发是两次请求。所以请求转发的过程是两次request,如果想要数据共享就需要将数据放到session域中。
application
接口名:ServeletContext
application对象代表整个web应用,这是最大的一个域,没有比这个更大的域了。当服务器启动时创建,服务器关闭时销毁。如果你需要记录网站在线人数这种全局信息你可以使用application域。
2.Servlet域对象在SpringMVC中的使用
接下来我们将对如何在域对象中进行数据存储进行介绍,主要包括Servlet原生方法和SpringMVC框架中的拓展方法。
2.1 request
测试建议:向服务器请求数据,DispatcherServlet收到请求后,分发给对应映射路径的Controller,可以通过在Controller中储存数据,然后Controller返回逻辑视图,结合thymeleaf,返回物理视图资源。可以在物理视图中取用该数据展现在页面上达到测试效果。
Map、ModelMap、Model关系: Map、Model、ModelMap底层实例化的对象都是:BindingAwareModelMap。
重要:对于处理器方法来说,不管你使用的参数是Model接口,还是Map接口,还是ModelMap类,还是ModelAndView类,最终处理器方法执行结束之后,返回的都是ModelAndView对象。这个返回的ModelAndView对象给DispatcherServlet类了。
当请求路径不是JSP的时候,都会走前端控制器DispatcherServlet。DispatcherServlet中有一个核心方法 doDispatch(),这个方法用来通过请求路径找到对应的 处理器方法然后调用 处理器方法,处理器方法返回一个逻辑视图名称(可能也会直接返回一个ModelAndView对象)。
原生ServletAPI:
@Controller
public class RequestScopeTestController {
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
// 向request域中存储数据
request.setAttribute("testRequestScope", "在SpringMVC中使用原生Servlet API实现request域数据共享");
return "view";
}
}
Model接口:
@RequestMapping("/testModel")
public String testModel(Model model){
// 向request域中存储数据
model.addAttribute("testRequestScope", "在SpringMVC中使用Model接口实现request域数据共享");
return "view";
}
Map接口:
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
// 向request域中存储数据
map.put("testRequestScope", "在SpringMVC中使用Map接口实现request域数据共享");
return "view";
}
ModelMap类:
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
// 向request域中存储数据
modelMap.addAttribute("testRequestScope", "在SpringMVC中使用ModelMap实现request域数据共享");
return "view";
}
ModelAndView类:
在SpringMVC框架中为了更好的体现MVC架构模式,提供了一个类:ModelAndView。这个类的实例封装了Model和View。也就是说这个类既封装业务处理之后的数据,也体现了跳转到哪个视图。使用它也可以完成request域数据共享。
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
// 创建“模型与视图对象”
ModelAndView modelAndView = new ModelAndView();
// 绑定数据
modelAndView.addObject("testRequestScope", "在SpringMVC中使用ModelAndView实现request域数据共享");
// 绑定视图
modelAndView.setViewName("view");
// 返回
return modelAndView;
}
注意:
- 方法的返回值类型不是String,而是ModelAndView对象。
- ModelAndView不是出现在方法的参数位置,而是在方法体中new的。
- 需要调用addObject向域中存储数据。
- 需要调用setViewName设置视图的名字。
2.2 session
测试建议:可以采用在Controller中放入session域数据,随后Controller返回index页面的逻辑,在index页面中写入一个超链接链接其他页面,在其他页面读出放入session的数据,如果显示成功,即测试成功。因为index页面的reponse和其他页面的response属于不同的request域,但是是同一个session
原生ServletAPI
@Controller
public class SessionScopeTestController {
@RequestMapping("/testSessionScope1")
public String testServletAPI(HttpSession session) {
// 向会话域中存储数据
session.setAttribute("testSessionScope1", "使用原生Servlet API实现session域共享数据");
return "view";
}
}
使用SessionAttributes注解:
@Controller
@SessionAttributes(value = {"x", "y"})
public class SessionScopeTestController {
@RequestMapping("/testSessionScope2")
public String testSessionAttributes(ModelMap modelMap){
// 向session域中存储数据
modelMap.addAttribute("x", "我是埃克斯");
modelMap.addAttribute("y", "我是歪");
return "view";
}
}
注意:SessionAttributes注解使用在Controller类上。标注了当key是 x 或者 y 时,数据将被存储到会话session中。如果没有 SessionAttributes注解,默认存储到request域中。
2.3 application
测试建议,可以按照session的测试方法,两个不同页面,但是读数据需要用themeleaf的application的方式读出
原生ServletAPI:
在SpringMVC实现application域数据共享,最常见的方案就是直接使用Servlet API了:
@Controller
public class ApplicationScopeTestController {
@RequestMapping("/testApplicationScope")
public String testApplicationScope(HttpServletRequest request){
// 获取ServletContext对象
ServletContext application = request.getServletContext();
// 向应用域中存储数据
application.setAttribute("applicationScope", "我是应用域当中的一条数据");
return "view";
}
}
测试语句:
视图:
<div th:text="${application.applicationScope}"></div>
超链接:
<a th:href="@{/testApplicationScope}">在SpringMVC中使用ServletAPI实现application域共享数据</a><br>
标签:SpringMVC,数据,request,对象,session,ModelAndView,Servlet,public
From: https://www.cnblogs.com/bobospace/p/18280641