0%

JSP内置对象&作用域

JSP学习笔记之JSP内置对象&作用域

下边代码示例的环境搭建部分点这里查看

JSP内置对象

  • pageContext 可以存数据
  • request 可以存数据
  • response
  • session 可以存数据
  • application (ServletContext) 可以存数据
  • config (ServletConfig)
  • out
  • page (不用了解)
  • exception

保存数据

内置对象,pageContext、request、session、application可以保存数据的,但是作用域不同。

  • pageContext
    • 保存的数据只在 一个页面 中有效
  • request
    • 保存的数据只在 一次请求 中有效
  • session
    • 保存的数据只在 一次会话 中有效,从打开浏览器到关闭浏览器
  • application
    • 保存的数据只在 服务器 中有效,从打开服务器到关闭服务器(其实就是ServletContext)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%
pageContext.setAttribute("name1","长江1号");//保存的数据只在 一个页面 中有效
request.setAttribute("name2","长江2号");//保存的数据只在 一次请求 中有效
session.setAttribute("name3","长江3号");//保存的数据只在 一次会话 中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","长江4号");//保存的数据只在 服务器 中有效,从打开服务器到关闭服务器(其实就是ServletContext)
%>

<%--脚本片段中的代码,会被原封不动地生成到_jsp.java中
要求:这里的代码,必须保证java语法的正确性
--%>
<%
//从pageContext取出,我们通过寻找的方式来--find(get也可以
//从底层到高层(作用域):page --> request --> session --> application
String name1 = (String)pageContext.findAttribute("name1");
String name2 = (String)pageContext.findAttribute("name2");
String name3 = (String)pageContext.findAttribute("name3");
String name4 = (String)pageContext.findAttribute("name4");
String name5 = (String)pageContext.findAttribute("name5");//不存在
pageContext.setAttribute("name","qsdbl",PageContext.SESSION_SCOPE);//等价于下边
// session.setAttribute("name","qsdbl");

%>

<%--使用EL表达式输出 ${} --%>
<h1>取出的值:</h1>
<h3>1:${name1}</h3>
<h3>2:${name2}</h3>
<h3>3:${name3}</h3>
<h3>4:${name4}</h3>
<h3>5:${name5}</h3>
<h3>5:<%=name5%></h3>
<h3>使用JSP表达式取值,若不存在会返回:<%=name5%>,而使用EL表达式则不会返回东西,见上边</h3>

作用域

上边的示例中,通过pageContext对象可以取到其他内置对象保存的数据。但是要注意不同内置对象保存的数据,其作用范围是不一样的。作用范围小的,例如pageContext,在其他页面就取不到了。作用范围大的,例如application,只要是同一个web应用程序内的JSP页面都可以取到。(在java代码中要实现共享数据,可以使用ServletContext对象session对象,对应这里JSP页面中的application对象和session对象)

1
从底层到高层(作用域):pageContext --> request --> session --> application

我们查看一下源码。按住cmd键,鼠标点击pageContext的方法setAttribute。我们可以看到setAttribute方法除了可以放两个参数,还有一个重载方法可以放三个参数,第三个参数是int类型,形参名为scope(范围,可以理解成前边说的作用域)

查看有三个形参的方法setAttribute的具体实现,点击方法左侧的绿色i字母小图标,我们可以看到该方法的具体实现类是PageContextImpl。该方法的具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void setAttribute(String name, Object attribute, int scope) {
switch(scope) {
case 1:
this.mPage.put(name, attribute);
break;
case 2:
this.mRequest.put(name, attribute);
break;
case 3:
this.mSession.put(name, attribute);
break;
case 4:
this.mApp.put(name, attribute);
break;
default:
throw new IllegalArgumentException("Bad scope " + scope);
}

}

继续查看实现类PageContextImpl的父类PageContext。我们可以看到在类的前边定义了一些常量,对应着不同的作用域。从中可以确定作用域范围:pageContext --> request --> session --> application(低到高)

1
2
3
4
public static final int PAGE_SCOPE = 1;
public static final int REQUEST_SCOPE = 2;
public static final int SESSION_SCOPE = 3;
public static final int APPLICATION_SCOPE = 4;

所以下边两条语句作用是一样的,都是将数据保存到session中,但上边的是通过pageContext对象。

1
2
pageContext.setAttribute("name","qsdbl",PageContext.SESSION_SCOPE);//等价于下边
//session.setAttribute("name","qsdbl");

代码演示

将前边保存数据部分的演示代码稍作修改,再尾部添加一个请求转发语句forward()

上图,未添加请求转发语句。pageContext的值还在,还可以取出来。下图,添加请求转发语句,访问demo02.jsp后请求被转发到demo03.jsp(浏览器地址不变),也就是说跳到了另一个页面,在这里另一个页面通过pageContext对象保存的数据是取不到的,超出了pageContext的作用域范围。(点这里,复习一下各内置对象的作用域范围)

请求转发

使用pageContext对象或request对象都可以实现请求转发,在JSP页面demo02.jsp中添加下边语句:(java代码实现请求转发,点这里。ServletContext对象、request对象都可以,对应这里的两个JSP内置对象)

1
2
3
4
<%
pageContext.forward("/404error.jsp");//请求转发,地址不变
//request.getRequestDispatcher("/404error.jsp").forward(request,response);
%>

总结

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如新闻,用户看完没用了

session:客户端向服务器发送请求,产生的数据,用户用完一会儿还有用,比如购物车

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如聊天数据

若图片不能正常显示,请在浏览器中打开

欢迎关注我的其它发布渠道