JSP/Servlet及相关技术详解
文章目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UyehziGy-1583235818226)(第二章:JSPServlet及相关技术详解.assets/jsp servlet 及相关技术详解.jpg)]
一、JSP
web应用和web.xml文件
构建web应用
- classes 和 lib,这两个文件夹的作用完全相同: 都是用于保存 Web 应用所需要的 Java 类文件,区别是 classes 保存单个*.class 文件;而 lib 保存打包后 的 JAR 文件。
- 对于Java Web应用而言,WEB-INF是一个特殊的文件夹,Web容器会包含该文件夹下的内容,客户端浏览器无法访问WEB-INF路径下的任何内容。
- WEB-INF 路径下的 web.xml 文件被称为配置描述符。
web.xml文件
<?xml version="1.0" encoding="GBK"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
matadata-complete = "false" >
<welcome-file-list>
<welcome-file>a.jsp</welcome-file>
</welcome-file-list>
</web-app>
- web.xml文件的根元素是**<web-app…/>**元素,在Servlet3规范中,该元素新增了如下属性。
- metadata-complete:该属性接受true 或false两个属性值。当该属性值为true时,该Web应用将不会加载注解配置的Web组件(如Servlet、Filter、Listener等)。
- 在web.xml文件中配置首页使用welcome-file-list 元素,该元素能包含多个welcome-file子元素,其中每个welcome-file子元素配置一个首页。
- 每个 Web 容器都会提供一个系统的 web.xml 文件,用于描述所有 Web 应用共同的配置属性。
JSP的基本原理
- Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
- Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
- servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法 init()和destroy(),还有一个处理请求的service(),也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要回答这三个问题:
- 你初始化时要做什么
- 你销毁时要做什么
- 你接受到请求时要做什么
- JSP的本质是Servlet(一个特殊的Java类),当用户向指定Servlet 发送请求时,Servlet利用输出流动态生成HTML页面,包括每一个静态的HTML标签和所有在HTML页面中出现的内容。
- JSP通过在标准的HTML页面中嵌入Java代码,其静态的部分无须Java程序控制,只有那些需要从数据库读取或需要动态生成的页面内容,才使用Java脚本控制。
- 从上面的介绍可以看出,JSP页面的内容由如下两部分组成。
- 静态部分:标准的HTML标签、静态的页面内容,这些内容与静态HTML页面相同。
- 动态部分:受Java程序控制的内容,这些内容由Java脚本动态生成。
- JSP 页面必须放在 Web 应用 中才有效,所以编写该 JSP 页面之前应该先构建一个 Web 应用 。
- 事实上,**JSP的本质依然是Servlet,每个JSP页面就是一个Servlet 实例JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。**也就是说,JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。
- Servlet类的源代码,该 Java 类主要 包含如下三个方法(去除方法名中的_jsp 前缀,再将首字母小写):
- init():初始化JSP/Servlet的方法。
- destroy():销毁JSP/Servlet之前的方法。
- service() :对用户请求生成响应的方法。
- 根据上面的JSP页面工作原理图,可以得到如下4个结论。
- JSP文件必须在JSP服务器内运行。
- JSP文件必须生成Servlet才能执行。
- 每个JSP页面的第一个访问者速度会有点慢,因为必须等待JSP编译成Servlet。
- JSP页面的访问者无须安装任何客户端,甚至不需要可以运行Java的运行环境,因为JSP页面输送到客户端的是标准HTML页面。
JSP的四种基本语法
- 编写JSP页面非常简单:在静态HTML页面中“镶嵌”动态Java脚本即可。
- JSP 页面的 4 种基本语法——也就是 JSP 允许在静态 HTML 页面中“镶嵌”的成 分。
JSP注释
- JSP注释用于标注在程序开发过程中的开发提示,它不会输出到客户端。
- JSP注释的格式如下:
<%--注释内容--%>
- JSP 注释在 JSP 编译成 Servlet 的阶段己经 被“丢弃”了。
JSP声明
- JSP声明用于声明变量和方法。
- 实际上,JSP声明将会转换成对应Servlet的成员变量或成员方法,因此JSP声明依然符合Java语法。
- JSP声明的语法格式如下:
<%!声明部分%>
-
由于JSP声明语法定义的变量和方法对应于Servlet类的成员变量和方法,所以JSP声明部分定义的变量和方法可以使用private、public等访问控制符修饰,也可使用static修饰,将其变成类属性和类方法。
但不能使用abstract修饰声明部分的方法,因为抽象方法将导致JSP对应Servlet变成抽象类,从而导致无法实例化。
JSP输出表达式
- JSP提供了一种输出表达式值的简单方法,输出表达式值的语法格式如下:
<%=表达式%>
- 输出表达式将转换成 Serviet 里的输出语句。
JSP小脚本
- 通常来 说, 所有可执行性 Java 代码都可通过 JSP 小脚本嵌入 HTML 页面
<table bgcolor="#9999dd" border="1" width="300px">
<!-- JSP小脚本,这些脚本会对HTML的标签产生作用 -->
<%
for(int i = 0 ; i < 10 ; i++)
{
%>
<!-- 上面的循环将控制<tr>标签循环 -->
<tr>
<td>循环值:</td>
<td><%=i%></td>
</tr>
<%
}
%>
<table>
- JSP小脚本将转换成Servlet里_jspService()方法的可执行性代码。这意味着在JSP小脚本部分也可以声明变量,但在JSP小脚本部分声明的变量是局部变量,但不能使用private、public等访问控制符修饰,也不可使用static修饰。
- 实际上不仅JSP小脚本部分会转换成_jspService()方法里的可执行性代码,JSP页面里的所有静态内容都将由_jspService()方法里输出语句来输出,这就是JSP小脚本可以控制JSP页面中静态内容的原因。由于JSP小脚本将转换成_jspService()方法里的可执行性代码,而Java语法不允许在方法里定义方法,所以的在JSP小脚本里不能定义方法。在JSP小脚本中定义的变量是局部变量。
JSP的三个编译指令
- JSP的编译指令是通知JSP引擎的消息,它不直接生成输出。编译指令都有默认值,因此开发人员无须为每个指令设置值。
常见的编译指令有如下三个。- page:该指令是针对当前页面的指令。
- include:用于指定包含另一个页面。
- taglib:用于定义和访问自定义标签。
编译指令格式:
<%@ 编译指令名 属性名="属性值"…%>
page指令
<%@page
[lanquage="Java"]
[extends="package.class"]
[import="package.class | package.*…"]
[session="true |false"]
[buffer="none | 8KB|size Kb"]
[autoFlush="true |false"]
[isThreadSafe="true|false"]
[info="text"]
[errorPage="relativeURL"]
[contentType="mimeType[;charset=characterSet]"|"text/html;charSet=ISO-8859-1"]
[pageEncoding="ISO-8859-1"]
[isErrorPage="true |false"]
%>
-
各属性的含义:
- language:声明当前JSP页面使用的脚本语言的种类,因为页面是JSP页面,该属性的值通常都是java,该属性的默认值也是java,所以通常无须设置。
- extends:指定JSP页面编译所产生的Java类所继承的父类,或所实现的接口。
- import:**用来导入包。**下面几个包是默认自动导入的,不需要显式导入。默认导入的包有:
java.lang.*、javax.servlet.*、javax.servlet.jsp.*、javax.servlet.http.* - session:设定这个JSP页面是否需要HTTP Session。
- buffer:指定输出缓冲区的大小。输出缓冲区的JSP内部对象:out用于缓存JSP页面对客户浏览器的输出,默认值为8KB,可以设置为none,也可以设置为其他的值,单位为KB。
- autoFlush:当输出缓冲区即将溢出时,是否需要强制输出缓冲区的内容。设置为true时为正常输出;如果设置为false,则会在buffer 溢出时产生一个异常。
- info:设置该JSP程序的信息,也可以看做其说明,可以通过Servlet.getServletlnfo()方法获取该值。如果在JSP页面中,可直接调用getServletlnfo()方法获取该值,因为JSP页面的实质就是Servlet。
- errorPage:**指定错误处理页面。**如果本页面产生了异常或者错误,而该JSP页面没有对应的处理代码,则会自动调用该属性所指定的JSP页面。
- isErrorPage:**设置本JSP页面是否为错误处理程序。**如果该页面本身已是错误处理页面,则通常无须指定errorPage属性。
- contentType: 用于设定生成网页的文件格式和编码字符集,即MIME类型和页面字符集类型,默认的MIME类型是text/html;默认的字符集类型为ISO-8859-1。
- pageEncoding:指定生成网页的编码字符集。
-
errorPage 属性的实质是JSP的异常处理机制,JSP脚本不要求强制处理异常,即使该异常是checked异常。
如果 JSP 页面在 运行中抛出未处理的异常,系统将自动跳转到 errorPage 属性指定的页面;
如果 errorPage 没有指定错误 页面,系统则直接把异常信息呈现给客户端浏览器一一这是所有的开发者都不愿意见到的场景。
<%@page contentType="text/html; charset=gbk" language="java" errorPage="" %>
<!--指定info信息-->
<%@ page info = "this is a jsp"%>
<!DOCTYPE html PUBLIC "-//w3c//DTD/ XHTML 1.0 Transitional//EN""xhtml11-transitional.dtd">
<html xmlns= "http://www.w3.org/1999/xhtml">
<head>
<title>测试page指令的info属性</title>
</head>
<body>
<!--输出info信息-->
<%= getServletInfo()%>
</body>
</html>
<%@ page contentType="text/html; charset=GBK" language="java" errorPage= "error.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> new document </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<%
// 下面代码将出现运行时异常
int a = 6;
int b = 0;
int c = a / b;
%>
</body>
</html>
<%@ page contentType="text/html; charset=GBK" language="java" isErrorPage="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 错误提示页面 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 提醒客户端系统出现异常 -->
系统出现异常<br/>
</body>
</html>
include指令
-
使用include指令,可以将一个外部文件嵌入到当前JSP文件中,同时解析这个页面中的JSP语句(如果有的话)。
这是个静态的include语句,它会把目标页面的其他编译指令也包含进来,但动态include则不会。
include既可以包含静态的文本,也可以包含动态的JSP页面。静态的include编译指令会将被包含的页面加入本页面,融合成一个页面,因此被包含页面甚至不需要是一个完整的页面。
-
如果被嵌入的文件经常需要改变,建议使用<jsp:include>操作指令,因为它是动态的include语句。
include编译指令的语法如下:
<%@include file="relativeURLSpec"%>
- 静态包含的意义: 包含页面在编译时将完全包含了被包含页面的代码。 静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突, 那么页面就会出错。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 静态include测试 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 使用include编译指定导入页面 -->
<%@include file="scriptlet.jsp"%>
</body>
</html>
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 小脚本测试 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<table bgcolor="#9999dd" border="1" width="300px">
<!-- JSP小脚本,这些脚本会对HTML的标签产生作用 -->
<%
for(int i = 0 ; i < 10 ; i++)
{
%>
<!-- 上面的循环将控制<tr>标签循环 -->
<tr>
<td>循环值:</td>
<td><%=i%></td>
</tr>
<%
}
%>
<table>
</body>
</html>
JSP的七个动作指令
-
动作指令与编译指令不同,编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的动作。编译指令在将JSP编译成Servlet时起作用;而处理指令通常可替换成JSP小脚本,它只是JSP小脚本的标准化写法。
-
JSP动作指令主要有如下7个:
- jsp:forward:执行页面转向,将请求的处理转发到下一个页面。
- jsp:param:用于传递参数,必须与其他支持参数的标签一起使用。
- jsp:include;用于动态包含一个JSP页面。
- jsp:plugin:用于下载JavaBean或Applet到客户端执行。
- jsp:useBean:创建一个JavaBean的实例。
- jsp:setProperty:设置JavaBean实例的属性值。
- jsp:getProperty:输出JavaBean实例的属性值。
forward指令
- forward指令用于将页面响应转发到另外的页面。既可转发到静态的HTML页面,也可转发到动态的JSP页面,或者转发到容器中的Servlet。
jsp:forward page="{relativeURL|<%=expression>">
{<jsp:param..…/>}
</jsp:forward>
- 在转发时增加额外的请求参数。增加的请求参数的值可以通过HttpServletRequest类的getParameter()方法获取。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> forward的原始页 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h3>forward的原始页</h3>
<%--将客户端请求转发到 forward-result.jsp 页面, 转发请求时增加了一个请求参数: 参数名为 age, 参数值为 29 --%>
<jsp:forward page="forward-result.jsp">
<jsp:param name="age" value="29"/>
</jsp:forward>
</body>
</html>
<%--filenName = forward-result.jsp --%>
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>forward结果页</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 使用request内置对象获取age参数的值 -->
<%=request.getParameter("age")%>
<!-- 输出username请求参数的值 -->
<%=request.getParameter("username")%>
</body>
</html>
- 从表面上看,<jsp:forward.>指令给人一种感觉:它是将用户请求“转发”到了另一个新页面,但实际上,<jsp:forward./>并没有重新向新页面发送请求,它只是完全采用了新页面来对用户生成响应—请求依然是一次请求,所以请求参数、请求属性都不会丢失。
include指令
- include 指令是一个动态include指令,也用于包含某个页面,它不会导入被include页面的编译指令,仅仅将被导入页面的body内容插入本页面。
<jsp:include page="{relativeURL|<s=expressiong>}"flush="true">
<jsp:param name="parameterName"value="patameterValue"/>
</jsp:include>
- flush属性用于指定输出缓存是否转移到被导入文件中。如果指定为true,则包含在被导入文件中;如果指定为false,则包含在原文件中。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> jsp-include测试 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 使用动态include指令导入页面 -->
<jsp:include page="scriptlet.jsp" />
</body>
</html>
<%--filenName = scriptlet.jsp --%>
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 小脚本测试 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<table bgcolor="#9999dd" border="1" width="300px">
<!-- JSP小脚本,这些脚本会对HTML的标签产生作用 -->
<%
for(int i = 0 ; i < 10 ; i++)
{
%>
<!-- 上面的循环将控制<tr>标签循环 -->
<tr>
<td>循环值:</td>
<td><%=i%></td>
</tr>
<%
}
%>
<table>
</body>
</html>
- 动态导入只是使用一个include方法来插入目标页面的内容,而不是将目标页面完全融入本页面中。
- 归纳起来,静态导入和动态导入有如下三点区别:
- 静态导入是将被导入页面的代码完全融入,两个页面融合成一个整体Servlet;而动态导入则在Servlet中使用include方法来引入被导入页面的内容。
- 静态导入时被导入页面的编译指令会起作用;而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。
- 动态包含还可以增加额外的参数。
- 实际上,forward动作指令和include动作指令十分相似(它们的语法就很相似),它们都采用方法来引入目标页面,通过查看JSP页面所生成Servlet代码可以得出:**forward指令使用_jspx_page_context的forward() 方法来引入目标页面,而include指令则使用通过JspRuntimeLibrary的include() 方法来引入目标页面。**区别在于:**执行forward时,被forward的页面将完全代替原有页面;而执行include时,被include的页面只是插入原有页面。**简而言之,forward拿目标页面代替原有页面,而include则拿目标页面插入原有页面。
useBean、setProperty、getProperty 指令
- 这三个指令都是与JavaBean相关的指令,其中
- useBean 指令用于在JSP页面中初始化一个Java实例;
- setProperty指令用于为JavaBean实例的属性设置值;
- getProperty指令用于输出JavaBean实例的属性。
- 如果多个JSP页面中需要重复使用某段代码,则可以把这段代码定义成Java类的方法,然后让多个JSP页面调用该方法即可,这样可以达到较好的代码复用。
useBean的语法格式如下:
<jsp:useBean id="name" class="classname" scope="page | request |session | application"/>
- 其中,id属性是JavaBean的实例名,class 属性确定JavaBean的实现类。scope 属性用于指定JavaBean实例的作用范围,该范围有以下4个值:
- page:该JavaBean实例仅在该页面有效。
- request:该JavaBean实例在本次请求有效。
- session:该JavaBean实例在本次session内有效。
- application:该JavaBean实例在本应用内一直有效。
setProperty指令的语法格式如下:
<jsp:setProperty name="BeanName" property="propertyName" value="value"/>
-
name属性确定需要设定JavaBean的实例名;
property属性确定需要设置的属性名;
value属性则确定需要设置的属性值。
getProperty 的语法格式如下:
<jsp:getProperty name="BeanName"property="propertyName"/>
-
name属性确定需要输出的JavaBean的实例名;
property属性确定需要输出的属性名。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> Java Bean测试 </title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 创建lee.Person的实例,该实例的实例名为p1 -->
<jsp:useBean id="p1" class="lee.Person" scope="page"/>
<!-- 设置p1的name属性值 -->
<jsp:setProperty name="p1" property="name" value="crazyit.org"/>
<!-- 设置p1的age属性值 -->
<jsp:setProperty name="p1" property="age" value="23"/>
<!-- 输出p1的name属性值 -->
<jsp:getProperty name="p1" property="name"/><br/>
<!-- 输出p1的age属性值 -->
<jsp:getProperty name="p1" property="age"/>
</body>
</html>
package lee;
public class Person
{
private String name;
private int age;
// 无参数的构造器
public Person()
{
}
// 初始化全部成员变量的构造器
public Person(String name , int age)
{
this.name = name;
this.age = age;
}
// name的setter和getter方法
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}
}
- 上面的Person.java只是源文件,此处将该文件放在Web 应用的WEB-INF/src路径下,实际上Java源文件对Web应用不起作用,所以此处会使用Ant来编译它,并将编译得到的二进制文件放入WEB-INF/classes路径下。而且,为Web应用提供了新的class文件后,必须重启该Web应用,让它可以重新加载这些新的class文件。
plugin 指令
- plugin 指令主要用于下载服务器端的JavaBean或Applet到客户端执行。由于程序在客户端执行,因此客户端必须安装虚拟机。
- 实际由于现在很少使用Applet,而且就算要使用Applet,也完全可以使用支持Applet 的HTML标签,所以jsp:plugin标签的使用场景并不多。
param指令
-
param指令用于设置参数值,这个指令本身不能单独使用,因为单独的param 指令没有实际意义。
-
param指令可以与以下三个指令结合使用。
- jsp:include
- jsp:forward
- jsp:plugin
-
当与include指令结合使用时,param 指令用于将参数值传入被导入的页面;
-
当与forward指令结合使用时,param指令用于将参数值传入被转向的页面;
-
当与plugin 指令结合使用时,则用于将参数传入页面中的JavaBean实例或Applet实例。
param指令的语法格式如下:
<jsp:param name="paramName"value="paramValue"/>
JSP脚本中的9个内置对象
- Jsp 脚本中包含9个内置对象,这9个内置对象都是ServletAPl接口的实例,只是JSP规范对它们 进行了默认初始化(由JSP页面对应Servlet的_jspService()方法来创建这些实例)。也就是说,它们已 经是对象,可以直接使用。
- 9个内置对象依次如下:
- application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于 JSP页面,或者在Servlet之间交换信息。常用的方法有getAttribute(String attName)、 setAttribute(String attName,String att Value)和getInitParameter(String paramName)等。
- config:javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息。常用的方法有getInitParameter(String paramName)和getInitParameternames()等方法。事实上JSP页面通常无需配置,也就不存在配置信息。
- exception:java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当页面是错 误处理页面,即编译指令page的isErrorPage属性为true时,该对象才可以使用。常用的方法有 getMessage()和printStackTrace()等。
- out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容,形成HTML 页面。
- page:代表该页面本身,通常没有太大用处。也就是Servlet中的this,其类型就是生成的Servlet 类,能用page的地方就可用this。
- pageContext:javax.servlet.jsp.PageContext的实例,该对象代表该JSP页面上下文,使用该对象 可以访问页面中的共享数据。常用的方法有getServletContext()和getServletConfig()等。
- request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参 数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。常用的 方法有getParameter(String paramName)、getParameter Values(String paramName)、setAttribute(String attrName,Object attrValue)、getAttribute(String attrName)和 setCharacterEncoding(String env)等。
- response:javax.servlet.http.HtpServletResponse的实例,代表服务器对客户端的响应。通常很少 使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。而response对象常用于 重定向,常用的方法有getOutputStream()、sendRedirect(java.lang.String location)等。
- session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端浏览器与站点建立连接时,会话开始;当客户端关闭浏览器时,会话结束。常用的方法有:getAttribute(String attrName)、setAttribute(String attrName,Object atrValue)等。
几乎所有的JSP页面编译后Servlet类都有如下所示的结构,下面Servlet 类的粗体字代码表明: request、response 两个对象是_jspService()方法的形参,当Tomcat 调用该方法时会初始化这两个对象。 而 page、pageContext、application、config、session、out 都是_jspService()方法的局部变量,由该方法完成初始化。
通过下面的代码不难发现JSP内置对象的实质:它们要么是_jspService()方法的形参,要么是 _jspService() 方法的局部变量,所以可以直接在JSP脚本(脚本将对应于Servlet的_jspService()方法部分) 中调用这些对象,无须创建它们。
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=utf-8");
pageContext = _jspxFactory.getPageContext(this, request, response