上文提到JSP的基本技术,包括:JSP的基本概念、JSP的执行流程、JSP的文件元素、JSP的生命周期以及JSP的语法标识,重点了解了JSP的语法标识里的:脚本标识、注释标识、指令标识以及动作标识。接下来这篇Blog来重点了解下JSP的内置对象。
JSP内置对象概述
JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。
JSP所支持的九大内置对象,也叫隐式对象,从本质上讲,JSP的这些内置对象其实都是由特定的Java类所产生的,在服务器运行时根据情况自动生成。基于它们的主要作用可以分为四类:输入输出对象、作用域对象、Servlet对象以及异常错误对象。
输入输出对象
输入输出对象共有两个,一个是我们最常用的用作向客户端输出各种数据的out对象,一个是主要用作页面重定向的response对象。
out对象
out 对象主要用于向客户端输出各种数据类型的内容,默认缓冲区8K,可以通过page指令设置,out 对象被封装为 javax.servlet.jsp.JspWriter 类,在实际应用中 out 对象会通过 JSP 容器变换为 java.io.PrintWriter 类,常用方法如下:
out对象有点类似我们之前的表达式脚本<%="我是一个跳转后的表达式语句"%>
,用于像客户端输出信息,和System.out.println()
语句服务端本地打印不同,out是向客户端浏览器打印数据,利用out对象还可以输出html代码,比如<br />
让浏览器解析
response对象
response 对象用于响应客户请求,封装了 JSP 产生的响应,并发送到客户端以响应客户端的请求,response对象常用功能如下:处理 HTTP 文件头和页面重定向,但我们一般不会设置返回的文件头,我们一般使用respnse做页面重定向:
- response 对象提供的 sendRedirect() 方法将网页重定向到另一个页面
这里简单解释下请求转发和重定向:
- 请求转发:客户端发起的请求被转发到了另一个地址进行处理,但这依然发生在一个request作用域里,地址栏显示的也是原来的地址。
- 重定向:重定向操作支持将地址重定向到另一个地址进行处理,这是由目标服务器返回的客户端再次发起的一个请求,不在一个request作用域里,在客户端浏览器上将会得到跳转的地址,并重新发送请求链接,且地址栏显示新地址
好简单了解后我们来看一个重定向的写法:
// 如果用户没有输入用户名,则重定向到 redirect.jsp if (username == null || "".equals(username.trim())) { response.sendRedirect("redirect.jsp");//如果用户名不存在,则转向第一个界面 }
四大作用域对象
共有四种级别的通信域,每一种通信域作用的范围不同,也都有些各自的作用对象,列举如下:
通信域 | 对象 | 作用范围 | 失效情况 |
Page | pageContext | 当前jsp页面 | 请求转发即失效 |
Request | request | 一次请求 | 请求转发公用request,重定向即失效 |
Session | session | 一次会话 | 浏览器关闭即失效 |
Application | application | 项目启动期间 | 项目关闭即失效 |
在正式聊四大作用域对象前我们先了解下表单提交,通过表单提交来看作用域的作用范围
表单提交
网页中表单是用户填写信息并提交的组件,JSP 引擎会将客户端的请求信息封装在request 对象中,调用request 对象相应的方法就可以获取对应的封装信息,first.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/15 Time: 8:02 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="second.jsp" method="get"> <table> <tr> <td> 用户名:</td> <td><input type="text" name="username"></td> <td> 密码:</td> <td><input type="text" name="password"></td> </tr> <tr> <td colspan="2"> <input type="submit" value=" 注册 "> </td> </tr> </table> </form> </body> </html>
这样当我们提交时,表单就会传递到second.jsp页面:
提交后就可以在second.jsp页面获取到填写的信息:
second.jsp的代码清单如下,我会在代码清单里加一些判断逻辑,来完成一些作用域的探索second.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/15 Time: 8:02 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% String username = request.getParameter("username"); String password = request.getParameter("password"); pageContext.setAttribute("password",password); session.setAttribute("password",password); application.setAttribute("password",password); pageContext.setAttribute("username",username); session.setAttribute("username",username); application.setAttribute("username",username); // 如果用户没有输入用户名,则重定向到 redirect.jsp if (username == null || "".equals(username.trim())) { response.sendRedirect("redirect.jsp");//如果用户名不存在,则转向第一个界面 } // 如果用户没有输入密码,则请求转发到forward.jsp if (password == null || "".equals(password.trim())) { request.getRequestDispatcher("forward.jsp").forward(request,response); } %> <% out.println("输出注册信息"); %> <%="您的用户名为:" + username + " 密码为: " + password%> </body> </html>
pageContext对象
pageContext页面上下文对象可以获取其他作用域对象,并提供方法用于访问内建对象在页面上定义的所有属性,从而保持同一页面组件之间的数据共享,pageContext常用方法如下:
请求转发【pageContext失效】
在上文的代码清单里我预置了一些条件,当用户没有输入密码的时候我们执行请求转发,请求转发的代码清单如下forward.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/15 Time: 8:38 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> [pageContext]未填写密码信息,只填写了用户名:<%=pageContext.getAttribute("username")%></br> [request]未填写密码信息,只填写了用户名:<%=request.getParameter("username")%></br> [session]未填写密码信息,只填写了用户名:<%=session.getAttribute("username")%></br> [application]未填写密码信息,只填写了用户名:<%=application.getAttribute("username")%> </body> </html>
此时我们在页面只输入用户名观察浏览器:
request对象
request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等,最重要的作用就是:封装用户提交的表单信息,通过如下方法可以获取对应数据
request也可以帮助我们执行请求转发:
request.getRequestDispatcher("forward.jsp").forward(request,response);
重定向【request失效】
同样在上文的代码清单里我预置了一些条件,当用户没有输入用户名的时候我们执行重定向,重定向的代码清单如下redirect.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/15 Time: 8:20 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> [pageContext]未填写用户名信息,只填写了密码:<%=pageContext.getAttribute("password")%></br> [request]未填写用户名信息,只填写了密码:<%=request.getParameter("password")%></br> [session]未填写用户名信息,只填写了密码:<%=session.getAttribute("password")%></br> [application]未填写用户名信息,只填写了密码:<%=application.getAttribute("password")%> </body> </html>
那么我们打开页面可以观察到:
session对象
session在JSP中被称为会话,目的是保存不同用户在web程序多个页面之间跳转时的数据信息,直到浏览器关闭,每个客户端会对应同一个session对象:
- session对象存储数据方法:
session.setAttribute(“字符串名称”,要存入的数据);
向session中存入数据,并且起名,要存入的数据可以是任意类型,名称必须是字符串类型,例如:在这里插入代码片
- session对象取出数据方法:
session.getAttribute(“存入时的名称”);
,取出数据时是Object类型,如需要可以转为需要类型 - session对象移除数据方法如下:
session.removeAttribute(“存入时的名称”);
示例如下:
session.setAttribute("password",password);
需要注意的是:服务器不知道客户端何时关闭浏览器,为了节省内存开销,默认超时时间为30分钟,即30分钟用户没有再次发出请求,则session自动销毁,超时时间可以在Tomcat配置文件中修改
浏览器关闭【session失效】
我们把请求地址粘贴到另一个新用户浏览器上来观察session的存活状态,发现session在切换了会话后失效了。
application对象
application 对象用于保存应用中的公有数据,服务器启动自动创建 application 对象,只要没有关闭服务器,application 对象将一直存在,所有用户可以共享,application 对象常用于记录缓存项目中的全局数据,常用方法如下:
示例如下:
application.setAttribute("password",password);
关闭服务器【application失效】
我们关闭tomcat服务,可以观察到application的作用域也失效了,当然不光是失效了,服务器都没了。
我们这里要说的就是再重启服务器后application里也是不会有值的。
异常错误对象
exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应,通常和page指令里的errorPage和isErrorPage一起使用。一般常用方法如下:
我们来看下我们的异常页面为test.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/14 Time: 12:30 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" errorPage="error.jsp" %> <html> <head> <title>Title</title> </head> <body> <%! int day = 3; %> if语句输出练习: <br/> <% if (day == 1 || day == 7) { %> <p>今天是周末</p> <% } else { %> <p>今天不是周末</p> <% } ; %> <br/> for语句输出练习; <br/> <%for (int fontSize = 1; fontSize <= 3; fontSize++) { %> <span style="color: green; "> 循环第 <%=fontSize%> 遍<br/> </span><br/> <%}%> <% int b=0; if(b==0){ int a=5/b; throw new Exception("不能做除0运算"); } %> </body> </html>
在这个页面我们通过指令指定如果出现异常要处理异常的页面是哪个:errorPage="error.jsp"
,然后我们来编写下错误的处理页面error.jsp:
<%-- Created by IntelliJ IDEA. User: tianmaolin Date: 2021/7/15 Time: 8:44 下午 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%> <html> <head> <title>Title</title> </head> <body> <% out.print(" 异常信息: "+ exception.getMessage()); //从exception对象中获取异常信息 %> </body> </html>
这样当我们访问问题页面时就会自动展示错误信息:
Servlet对象
还有几个我们不常用到的对象这里也一并了解下,包括config对象和page对象
config对象
config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。以下是config对象的使用方法,不是很重要,所以不常用:
config.getServletName();
它返回包含在<servlet-name>
元素中的servlet名字,注意,<servlet-name>
元素在 WEB-INF\web.xml
文件中定义。
page对象
这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。page 对象就是this对象的同义词
总结一下
好了以上就是JSP的内置对象相关内容,我觉得其中最重要的包含以下三个内容:
- pageContext、request、Session以及application这四个作用域作用的范围,这对以后学习框架也有帮助
- 理解表单提交的基本方式
- 理解请求转发和重定向的含义
好了这期学习和练习就到这里,下一期我们详细学习下JavaBean以及深入理解下动作标识。