1. 四大作用域
- application: 应用
作用域是整个项目
项目关闭、重启数据会丢失
如果项目不关闭,所有用户访问该项目的所有页面都可以获取application
- session: 会话
作用域是一次会话
关闭浏览器数据会丢失
如果会话不中断,本次会话访问的所有页面都可以获取session中的数据
- request: 请求
作用域是一次请求
发送另一次请求时数据无法传递
- pageContext: 页面上下文
作用域是一个页面
不同页面无法共享域中的数据。
2. 作用域存放数据的方式是key-value形式,key是String,value是Object
- 基本使用
//我们在page1.jsp中存值。
application.setAttribute("name","123");
session.setAttribute("name","123");
request.setAttribute("name","123");
pageContext.setAttribute("name","123");
//我们在page1.jsp中取值
application域:<%=application.getAttribute("name") %><br>
session域:<%=session.getAttribute("name") %><br>
request域:<%=request.getAttribute("name") %><br>
pageContext域:<%=pageContext.getAttribute("name") %><br>
这时,四个值都是可以取到的
//此时,定义一个page2.jsp,按照相同的方法取值
application域:<%=application.getAttribute("name") %><br>
session域:<%=session.getAttribute("name") %><br>
request域:<%=request.getAttribute("name") %><br>
pageContext域:<%=pageContext.getAttribute("name") %><br>
这时,request和pageContext的数据会丢失
//当我们浏览器重启之后,session的数据会丢失
- request域的转发
request.setAttribute("name","123");
request.getRequestDispatcher("page06.jsp").forward(request, response);
//此时在page06.jsp也可以获得request域的值。
//转发只可在项目内的页面跳转不可转发到其他项目中去
request.getRequestDispatcher("http://www.baidu.com").forward(request, response);
- response的重定向
request.setAttribute("name","123");
response.sendRedirect("page06.jsp");
//此时在page06.jsp中访问不到request的值
//重定向可以访问到百度,但是值发不过去
response.sendRedirect("http://www.baidu.com")
3. session的实际使用:
- 保存在线用户的信息
- 判断用户是否登录:
//利用表单制作用户的登录界面
//在表单提交时做session的存储
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
UserService userService = new UserService();
User user = userService.login(username, password);
//如果用户存在则放在session中,不存在显示登录失败!
if (user != null) {
//out.write(user.getNickname() + "登陆成功!");
// 把当前用户保存到session
session.setAttribute("onlineUser", user);
response.sendRedirect("");
} else {
//out.write("登陆失败!");
request.setAttribute("message", "用户名密码错误!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
// 在其他页面中加入头部
Object onlineUserSession = session.getAttribute("onlineUser");
//如果session的值不是null则表示登录成功
if (onlineUserSession == null) {
// response.sendRedirect("login.jsp");
request.setAttribute("message", "请先登录再访问其他页面!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
User onlineUser = (User)onlineUserSession;
- 实现权限:
- 视图权限:例如权限不够看不见操作的按钮
- 接口权限:权限不够不能请求相应的路径
//这里使用枚举去做了一个简单的管理员校验
Object onlineUserSession1 = session.getAttribute("onlineUser");
if (onlineUserSession1 == null) {
request.setAttribute("message", "请先登录再访问其他页面!");
request.getRequestDispatcher("login.jsp").forward(request, response);
} else if (((User)onlineUserSession1).getRole() != RoleEnum.ADMIN.ordinal()) {
response.sendRedirect("403.jsp");
}
//枚举类
public enum RoleEnum {
ADMIN("管理员"),
USER("普通用户");
private String desc;
private RoleEnum(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
4. application域的实例
网站访问量的统计
1. 使用数据库记录访问量:
优点:可以实现持久化
缺点:效率低、浪费资源
2. application记录访问量
优点:效率高,节省系统资源
缺点:项目重启,数据会丢失
// 记录访问量
Object count = application.getAttribute("web_access_count");
if (count == null) {
application.setAttribute("web_access_count", 1L);
} else {
application.setAttribute("web_access_count", (Long)count + 1);
}