JSP
简介
什么是Java Server Pages?
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。
Hello World
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Test</title>
</head>
<body>
Hello World
<br>
<%
out.println("Hello World!");
%>
</body>
</html>
生命周期
-
编译阶段:
servlet容器编译servlet源文件,生成servlet类
-
初始化阶段:
加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法
-
执行阶段:
调用与JSP对应的servlet实例的服务方法
-
销毁阶段:
调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例
JSP编译
编译的过程包括三个步骤:
- 解析JSP文件。
- 将JSP文件转为servlet。
- 编译servlet。
首次访问慢的原因:当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。
JSP初始化
容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()
方法。如果您需要执行自定义的JSP初始化任务,复写jspInit()
方法就行了,就像下面这样:
public void jspInit(){
// 初始化代码
}
一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()
方法中初始化数据库连接、打开文件和创建查询表。
JSP执行
这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。
当JSP网页完成初始化后,JSP引擎将会调用_jspService()
方法。
_jspService()
方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样:
void _jspService(HttpServletRequest request,
HttpServletResponse response)
{
// 服务端处理代码
}
_jspService()
方法在每个request中被调用一次并且负责产生与之相对应的response,并且它还负责产生所有7个HTTP方法的回应,比如GET、POST、DELETE等等
JSP清理
JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。
jspDestroy()
方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()
方法,比如释放数据库连接或者关闭文件夹等等。
jspDestroy()
方法的格式如下:
public void jspDestroy()
{
// 清理代码
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>life.jsp</title>
</head>
<body>
<%!
private int initVar=0;
private int serviceVar=0;
private int destroyVar=0;
%>
<%!
public void jspInit(){
initVar++;
System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
}
public void jspDestroy(){
destroyVar++;
System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次");
}
%>
<%
serviceVar++;
System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求");
String content1="初始化次数 : "+initVar;
String content2="响应客户请求次数 : "+serviceVar;
String content3="销毁次数 : "+destroyVar;
%>
<h1>菜鸟教程 JSP 测试实例</h1>
<p><%=content1 %></p>
<p><%=content2 %></p>
<p><%=content3 %></p>
</body>
</html>
语法
脚本程序
脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的
任何文本、HTML标签、JSP元素必须写在脚本程序的外面
<% 代码片段 %>
也可以编写与其等价的XML语句
<jsp:scriptlet>
代码片段
</jsp:scriptlet>
中文编码问题
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
Hello World!<br/>
<%
out.println("你的 IP 地址 " + request.getRemoteAddr());
%>
</body>
</html>
脚本变量从page,request,session,application这四个作⽤域⾃动寻找,如果没有定义,不报错。
pageContext.setAttribute(“var”, new Integer(5));
request.setAttribute(“var”, new Integer(6));
session.setAttribute(“var”, new Integer(7));
application.setAttribute(“var”, new Integer(8));
JSP声明
一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们
<%! declaration; [ declaration; ]+ ... %>
也可以编写与其等价的XML语句
<jsp:declaration>
代码片段
</jsp:declaration>
<%! int i = 0; %>
<%! int a, b, c; %>
<%! Circle a = new Circle(2.0); %>
JSP表达式
一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方。
由于表达式的值会被转化成String,所以可以在一个文本行中使用表达式而不用去管它是否是HTML标签。
表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。
<%= 表达式 %>
也可以编写与之等价的XML语句
<jsp:expression>
表达式
</jsp:expression>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>
今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body>
</html>
JSP注释
语法 | 描述 |
---|---|
<%-- 注释 --%> |
JSP注释,注释内容不会被发送至浏览器甚至不会被编译 |
<!-- 注释 --> |
HTML注释,通过浏览器查看网页源代码时可以看见注释内容 |
<\% |
代表静态 <%常量 |
%\> |
代表静态 %> 常量 |
\' |
在属性中使用的单引号 |
\" |
在属性中使用的双引号 |
<%-- 该部分注释在网页中不会被显示--%>
JSP指令
JSP指令用来设置与整个JSP页面相关的属性
<%@ directive attribute="value" %>
指令 | 描述 |
---|---|
<%@ page … %> | 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等 |
<%@ include … %> | 包含其他文件 |
<%@ taglib … %> | 引入标签库的定义,可以是自定义标签 |
Page指令
Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。
Page指令的语法格式:
<%@ page attribute="value" %>
等价的XML格式:
<jsp:directive.page attribute="value" />
下表列出与Page指令相关的属性:
属性 | 描述 |
---|---|
buffer | 指定out对象使用缓冲区的大小 |
autoFlush | 控制out对象的 缓存区 |
contentType | 指定当前JSP页面的MIME类型和字符编码 |
errorPage | 指定当JSP页面发生异常时需要转向的错误处理页面 |
isErrorPage | 指定当前页面是否可以作为另一个JSP页面的错误处理页面 |
extends | 指定servlet从哪一个类继承 |
import | 导入要使用的Java类 |
info | 定义JSP页面的描述信息 |
isThreadSafe | 指定对JSP页面的访问是否为线程安全 |
language | 定义JSP页面所用的脚本语言,默认是Java |
session | 指定JSP页面是否使用session |
isELIgnored | 指定是否执行EL表达式 |
isScriptingEnabled | 确定脚本元素能否被使用 |
<%@ page import=“java.util.*, java.net.*, java.io.*". session=“true” isErrorPage=“false”
errorPage=“/error.jsp” %>
<%@ page import = "Bean.NumberGuessBean" %>
Include指令
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
Include指令的语法格式如下:
<%@ include file="文件相对 url 地址" %>
include 指令中的文件名实际上是一个相对的 URL 地址。
如果您没有给文件关联一个路径,JSP编译器默认在当前路径下寻找。
等价的XML语法:
<jsp:directive.include file="文件相对 url 地址" />
Taglib指令
JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。
Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
Taglib指令的语法:
<%@ taglib uri="uri" prefix="prefixOfTag" %>
uri属性确定标签库的位置,prefix属性指定标签库的前缀。
等价的XML语法:
<jsp:directive.taglib uri="uri" prefix="prefixOfTag" />
JSP行为
JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等
<jsp:action_name attribute="value" />
语法 | 描述 |
---|---|
jsp:include | 用于在当前页面中包含静态或动态资源 |
jsp:useBean | 寻找和初始化一个JavaBean组件 |
jsp:setProperty | 设置 JavaBean组件的值 |
jsp:getProperty | 将 JavaBean组件的值插入到 output中 |
jsp:forward | 从一个JSP文件向另一个文件传递一个包含用户请求的request对象 |
jsp:plugin | 用于在生成的HTML页面中包含Applet和JavaBean对象 |
jsp:element | 动态创建一个XML元素 |
jsp:attribute | 定义动态创建的XML元素的属性 |
jsp:body | 定义动态创建的XML元素的主体 |
jsp:text | 用于封装模板数据 |
所有的动作要素都有两个属性:id属性和scope属性。
-
id属性:
id属性是动作元素的唯一标识,可以在JSP页面中引用。动作元素创建的id值可以通过PageContext来调用。
-
scope属性:
该属性用于识别动作元素的生命周期。 id属性和scope属性有直接关系,scope属性定义了相关联id对象的寿命。 scope属性有四个可能的值: (a) page, (b)request, ©session, 和 (d) application。
<jsp:useBean id=“a” class=“SomeClazz” scope=“page|request|session|application”/>
jsp:include
<jsp:include>
动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下:
<jsp:include page="相对 URL 地址" flush="true" />
前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。
以下是include动作相关的属性列表。
属性 | 描述 |
---|---|
page | 包含在页面中的相对URL地址。 |
flush | 布尔属性,定义在包含资源前是否刷新缓存区。 |
jsp:useBean
<jsp:useBean id="name" class="package.class" />
在类载入后,我们既可以通过 jsp:setProperty 和 jsp:getProperty 动作来修改和检索bean的属性
属性 | 描述 |
---|---|
class | 指定Bean的完整包名。 |
type | 指定将引用该对象变量的类型。 |
beanName | 通过 java.beans.Beans 的 instantiate() 方法指定Bean的名字。 |
jsp:setProperty
jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty,如下所示:
<jsp:useBean id="myName" ... />
...
<jsp:setProperty name="myName" property="someProperty" .../>
此时,不管jsp:useBean是找到了一个现有的Bean,还是新创建了一个Bean实例,jsp:setProperty都会执行。第二种用法是把jsp:setProperty放入jsp:useBean元素的内部,如下所示:
<jsp:useBean id="myName" ... >
...
<jsp:setProperty name="myName" property="someProperty" .../>
</jsp:useBean>
此时,jsp:setProperty只有在新建Bean实例时才会执行,如果是使用现有实例则不执行jsp:setProperty。
jsp:setProperty动作有下面四个属性,如下表:
属性 | 描述 |
---|---|
name | name属性是必需的。它表示要设置属性的是哪个Bean。 |
property | property属性是必需的。它表示要设置哪个属性。有一个特殊用法:如果property的值是"*",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法。 |
value | value 属性是可选的。该属性用来指定Bean属性的值。字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、 byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如"true")通过 Boolean.valueOf转换,int和Integer类型的属性值(比如"42")通过Integer.valueOf转换。 value和param不能同时使用,但可以使用其中任意一个。 |
param | param 是可选的。它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值。 |
jsp:getProperty
属性 | 描述 |
---|---|
name | 要检索的Bean属性名称。Bean必须已定义。 |
property | 表示要提取Bean属性的值 |
<jsp:useBean id="test" class="com.runoob.main.TestBean" />
<jsp:setProperty name="test"
property="message"
value="菜鸟教程..." />
<p>输出信息....</p>
<jsp:getProperty name="test" property="message" />
jsp:forward
jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。语法格式如下所示
<jsp:forward page="相对 URL 地址" />
属性 | 描述 |
---|---|
page | page属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算,可以是一个JSP页面或者一个 Java Servlet. |
<%-- main.jsp --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h2>forward 动作实例</h2>
<jsp:forward page="date.jsp" />
</body>
</html>
<%-- date.jsp --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<p>
今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
jsp:plugin
jsp:plugin动作用来根据浏览器的类型,插入通过Java插件 运行Java Applet所必需的OBJECT或EMBED元素。如果需要的插件不存在,它会下载插件,然后执行Java组件。 Java组件可以是一个applet或一个JavaBean。plugin动作有多个对应HTML元素的属性用于格式化Java 组件。param元素可用于向Applet 或 Bean 传递参数
<jsp:plugin type="applet" codebase="dirname" code="MyApplet.class"
width="60" height="80">
<jsp:param name="fontcolor" value="red" />
<jsp:param name="background" value="black" />
<jsp:fallback>
Unable to initialize Java Plugin
</jsp:fallback>
</jsp:plugin>
jsp:element jsp:attribute jsp:body
<jsp:element> 、 <jsp:attribute>、 <jsp:body>
动作元素动态定义XML元素。动态是非常重要的,这就意味着XML元素在编译时是动态生成的而非静态
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<jsp:element name="xmlElement">
<jsp:attribute name="xmlElementAttr">
属性值
</jsp:attribute>
<jsp:body>
XML 元素的主体
</jsp:body>
</jsp:element>
</body>
</html>
jsp:text
<jsp:text>
动作元素允许在JSP页面和文档中使用写入文本的模板 不能包含重复元素,只能包含文本和EL表达式
<jsp:text>模板数据</jsp:text>
在XML文件中,不能使用表达式如 ${whatever > 0},因为>符号是非法的。 可以使用 ${whatever gt 0}表达式或者嵌入在一个CDATA部分的值。
<jsp:text><![CDATA[<br>]]></jsp:text>
如果你需要在 XHTML 中声明 DOCTYPE,必须使用到<jsp:text>
动作元素,实例如下:
<jsp:text><![CDATA[<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">]]>
</jsp:text>
<head><title>jsp:text action</title></head>
<body>
<books><book><jsp:text>
Welcome to JSP Programming
</jsp:text></book></books>
</body>
</html>
JSP隐含对象
JSP支持九个自动定义的变量
对象 | 描述 |
---|---|
request | HttpServletRequest类的实例 |
response | HttpServletResponse类的实例 |
out | PrintWriter类的实例,用于把结果输出至网页上 |
session | HttpSession类的实例 |
application | ServletContext类的实例,与应用上下文有关 |
config | ServletConfig类的实例 |
pageContext | PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问 |
page | 类似于Java类中的this关键字 |
exception | exception 类的对象,代表发生错误的 JSP 页面中对应的异常对象 |
方法 | 描述 |
---|---|
out.print(dataType dt) | 输出Type类型的值 |
out.println(dataType dt) | 输出Type类型的值然后换行 |
out.flush() | 刷新输出流 |
控制流语句示例
JSP提供对Java语言的全面支持。您可以在JSP程序中使用Java API甚至建立Java代码块,包括判断语句和循环语句等等
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! int day = 3; %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h3>IF...ELSE 实例</h3>
<% if (day == 1 || day == 7) { %>
<p>今天是周末</p>
<% } else { %>
<p>今天不是周末</p>
<% } %>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! int day = 3; %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h3>SWITCH...CASE 实例</h3>
<%
switch(day) {
case 0:
out.println("星期天");
break;
case 1:
out.println("星期一");
break;
case 2:
out.println("星期二");
break;
case 3:
out.println("星期三");
break;
case 4:
out.println("星期四");
break;
case 5:
out.println("星期五");
break;
default:
out.println("星期六");
}
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! int fontSize; %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h3>For 循环实例</h3>
<%for ( fontSize = 1; fontSize <= 3; fontSize++){ %>
<font color="green" size="<%= fontSize %>">
菜鸟教程
</font><br />
<%}%>
</body>
</html>
设置响应 状态码
S.N. | 方法 & 描述 |
---|---|
1 | **String encodeRedirectURL(String url)**对sendRedirect()方法使用的URL进行编码 |
2 | **String encodeURL(String url)**将URL编码,回传包含Session ID的URL |
3 | **boolean containsHeader(String name)**返回指定的响应头是否存在 |
4 | **boolean isCommitted()**返回响应是否已经提交到客户端 |
5 | **void addCookie(Cookie cookie)**添加指定的cookie至响应中 |
6 | **void addDateHeader(String name, long date)**添加指定名称的响应头和日期值 |
7 | **void addHeader(String name, String value)**添加指定名称的响应头和值 |
8 | **void addIntHeader(String name, int value)**添加指定名称的响应头和int值 |
9 | **void flushBuffer()**将任何缓存中的内容写入客户端 |
10 | **void reset()**清除任何缓存中的任何数据,包括状态码和各种响应头 |
11 | **void resetBuffer()**清除基本的缓存数据,不包括响应头和状态码 |
12 | **void sendError(int sc)**使用指定的状态码向客户端发送一个出错响应,然后清除缓存 |
13 | **void sendError(int sc, String msg)**使用指定的状态码和消息向客户端发送一个出错响应 |
14 | **void sendRedirect(String location)**使用指定的URL向客户端发送一个临时的间接响应 |
15 | **void setBufferSize(int size)**设置响应体的缓存区大小 |
16 | **void setCharacterEncoding(String charset)**指定响应的编码集(MIME字符集),例如UTF-8 |
17 | **void setContentLength(int len)**指定HTTP servlets中响应的内容的长度,此方法用来设置 HTTP Content-Length 信息头 |
18 | **void setContentType(String type)**设置响应的内容的类型,如果响应还未被提交的话 |
19 | **void setDateHeader(String name, long date)**使用指定名称和日期设置响应头的名称和日期 |
20 | **void setHeader(String name, String value)**使用指定名称和值设置响应头的名称和内容 |
21 | **void setIntHeader(String name, int value)**指定 int 类型的值到 name 标头 |
22 | **void setLocale(Locale loc)**设置响应的语言环境,如果响应尚未被提交的话 |
23 | **void setStatus(int sc)**设置响应的状态码 |
使用setIntHeader()方法和setRefreshHeader()方法来模拟一个数字时钟
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h2>自动刷新实例</h2>
<%
// 设置每隔5秒自动刷新
response.setIntHeader("Refresh", 5);
// 获取当前时间
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;
out.println("当前时间: " + CT + "\n");
%>
</body>
</html>
S.N. | 方法 & 描述 |
---|---|
1 | **public void setStatus ( int statusCode )**此方法可以设置任意的状态码。如果您的响应包含一个特殊的状态码和一个文档,请确保在用PrintWriter返回任何内容前调用setStatus方法 |
2 | **public void sendRedirect(String url)**此方法产生302响应,同时产生一个 Location 头告诉URL 一个新的文档 |
3 | **public void sendError(int code, String message)**此方法将一个状态码(通常为 404)和一个短消息,自动插入HTML文档中并发回给客户端 |
发送407错误码给浏览器
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<title>Setting HTTP Status Code</title>
</head>
<body>
<%
response.sendError(407, "Need authentication!!!" );
%>
</body>
</html>
应用
表单处理
JSP 读取表单数据
- getParameter(): 使用 request.getParameter() 方法来获取表单参数的值。
- getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkbox类型
- **getParameterNames()😗*该方法可以取得所有变量的名称,该方法返回一个 Enumeration。
- **getInputStream()😗*调用此方法来读取来自客户端的二进制数据流
<-- http://localhost:8080/testjsp/main.jsp?name=菜鸟教程&url=http://ww.runoob.com --></-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>使用 GET 方法读取数据</h1>
<ul>
<li><p><b>站点名:</b>
<%= request.getParameter("name")%>
</p></li>
<li><p><b>网址:</b>
<%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<form action="main.jsp" method="GET">
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>使用 POST 方法读取数据</h1>
<ul>
<li><p><b>站点名:</b>
<%
// 解决中文乱码的问题
String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8");
%>
<%=name%>
</p></li>
<li><p><b>网址:</b>
<%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
Cookie
方法
序号 | 方法 & 描述 |
---|---|
1 | **public void setDomain(String pattern)**设置 cookie 的域名,比如 runoob.com |
2 | **public String getDomain()**获取 cookie 的域名,比如 runoob.com |
3 | **public void setMaxAge(int expiry)**设置 cookie 有效期,以秒为单位,默认有效期为当前session的存活时间 |
4 | **public int getMaxAge()**获取 cookie 有效期,以秒为单位,默认为-1 ,表明cookie会活到浏览器关闭为止 |
5 | **public String getName()**返回 cookie 的名称,名称创建后将不能被修改 |
6 | **public void setValue(String newValue)**设置 cookie 的值 |
7 | **public String getValue()**获取cookie的值 |
8 | **public void setPath(String uri)**设置 cookie 的路径,默认为当前页面目录下的所有 URL,还有此目录下的所有子目录 |
9 | **public String getPath()**获取 cookie 的路径 |
10 | **public void setSecure(boolean flag)**指明 cookie 是否要加密传输 |
11 | **public void setComment(String purpose)**设置注释描述 cookie 的目的。当浏览器将 cookie 展现给用户时,注释将会变得非常有用 |
12 | **public String getComment()**返回描述 cookie 目的的注释,若没有则返回 null |
JSP设置Cookie
(1)创建一个 cookie 对象: 调用 cookie 的构造函数,使用一个 cookie 名称和值做参数,它们都是字符串。
Cookie cookie = new Cookie("key","value");
请务必牢记,名称和值中都不能包含空格或者如下的字符:
[ ] ( ) = , " / ? @ : ;
**(2) 设置有效期:**调用 setMaxAge() 函数表明 cookie 在多长时间(以秒为单位)内有效。下面的操作将有效期设为了 24 小时。
cookie.setMaxAge(60*60*24);
**(3) 将 cookie 发送至 HTTP 响应头中:**调用 response.addCookie() 函数来向 HTTP 响应头中添加 cookie。
response.addCookie(cookie);
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<%
// 编码,解决中文乱码
String str = URLEncoder.encode(request.getParameter("name"),"utf-8");
// 设置 name 和 url cookie
Cookie name = new Cookie("name",
str);
Cookie url = new Cookie("url",
request.getParameter("url"));
// 设置cookie过期时间为24小时。
name.setMaxAge(60*60*24);
url.setMaxAge(60*60*24);
// 在响应头部添加cookie
response.addCookie( name );
response.addCookie( url );
%>
<html>
<head>
<title>设置 Cookie</title>
</head>
<body>
<h1>设置 Cookie</h1>
<ul>
<li><p><b>网站名:</b>
<%= request.getParameter("name")%>
</p></li>
<li><p><b>网址:</b>
<%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<form action="main.jsp" method=GET>
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
JSP 读取 Cookie
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>获取 Cookie</title>
</head>
<body>
<%
Cookie cookie = null;
Cookie[] cookies = null;
// 获取 cookies 的数据,是一个数组
cookies = request.getCookies();
if( cookies != null ){
out.println("<h2> 查找 Cookie 名与值</h2>");
for (int i = 0; i < cookies.length; i++){
cookie = cookies[i];
out.print("参数名 : " + cookie.getName());
out.print("<br>");
out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>");
out.print("------------------------------------<br>");
}
}else{
out.println("<h2>没有发现 Cookie</h2>");
}
%>
</body>
</html>
JSP 删除 cookie
- 获取一个已经存在的 cookie 然后存储在 Cookie 对象中。
- 将 cookie 的有效期设置为 0。
- 将这个 cookie 重新添加进响应头中。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>获取 Cookie</title>
</head>
<body>
<%
Cookie cookie = null;
Cookie[] cookies = null;
// 获取当前域名下的cookies,是一个数组
cookies = request.getCookies();
if( cookies != null ){
out.println("<h2> 查找 Cookie 名与值</h2>");
for (int i = 0; i < cookies.length; i++){
cookie = cookies[i];
if((cookie.getName( )).compareTo("name") == 0 ){
cookie.setMaxAge(0);
response.addCookie(cookie);
out.print("删除 Cookie: " +
cookie.getName( ) + "<br/>");
}
out.print("参数名 : " + cookie.getName());
out.print("<br>");
out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>");
out.print("------------------------------------<br>");
}
}else{
out.println("<h2>没有发现 Cookie</h2>");
}
%>
</body>
</html>
Session
默认情况下,JSP允许会话跟踪,一个新的HttpSession对象将会自动地为新的客户端实例化。禁止会话跟踪需要显式地关掉
<%@ page session="false" %>
S.N. | 方法 & 描述 |
---|---|
1 | **public Object getAttribute(String name)**返回session对象中与指定名称绑定的对象,如果不存在则返回null |
2 | **public Enumeration getAttributeNames()**返回session对象中所有的对象名称 |
3 | **public long getCreationTime()**返回session对象被创建的时间, 以毫秒为单位,从1970年1月1号凌晨开始算起 |
4 | **public String getId()**返回session对象的ID |
5 | **public long getLastAccessedTime()**返回客户端最后访问的时间,以毫秒为单位,从1970年1月1号凌晨开始算起 |
6 | **public int getMaxInactiveInterval()**返回最大时间间隔,以秒为单位,servlet 容器将会在这段时间内保持会话打开 |
7 | **public void invalidate()**将session无效化,解绑任何与该session绑定的对象 |
8 | **public boolean isNew()**返回是否为一个新的客户端,或者客户端是否拒绝加入session |
9 | **public void removeAttribute(String name)**移除session中指定名称的对象 |
10 | public void setAttribute(String name, Object value) 使用指定的名称和值来产生一个对象并绑定到session中 |
11 | **public void setMaxInactiveInterval(int interval)**用来指定时间,以秒为单位,servlet容器将会在这段时间内保持会话有效 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<%
// 获取session创建时间
Date createTime = new Date(session.getCreationTime());
// 获取最后访问页面的时间
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "再次访问菜鸟教程实例";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
// 检测网页是否有新的访问用户
if (session.isNew()){
title = "访问菜鸟教程实例";
session.setAttribute(userIDKey, userID);
session.setAttribute(visitCountKey, visitCount);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount += 1;
userID = (String)session.getAttribute(userIDKey);
session.setAttribute(visitCountKey, visitCount);
}
%>
<html>
<head>
<title>Session 跟踪</title>
</head>
<body>
<h1>Session 跟踪</h1>
<table border="1" align="center">
<tr bgcolor="#949494">
<th>Session 信息</th>
<th>值</th>
</tr>
<tr>
<td>id</td>
<td><% out.print( session.getId()); %></td>
</tr>
<tr>
<td>创建时间</td>
<td><% out.print(createTime); %></td>
</tr>
<tr>
<td>最后访问时间</td>
<td><% out.print(lastAccessTime); %></td>
</tr>
<tr>
<td>用户 ID</td>
<td><% out.print(userID); %></td>
</tr>
<tr>
<td>访问次数</td>
<td><% out.print(visitCount); %></td>
</tr>
</table>
</body>
</html>
删除Session数据
-
移除一个特定的属性:
调用public void removeAttribute(String name) 方法来移除指定的属性。
-
删除整个会话:
调用public void invalidate() 方法来使整个session无效。
-
设置会话有效期:
调用 public void setMaxInactiveInterval(int interval) 方法来设置session超时。
-
登出用户:
支持servlet2.4版本的服务器,可以调用 logout()方法来登出用户,并且使所有相关的session无效。
-
配置web.xml文件:
如果使用的是Tomcat,可以向下面这样配置web.xml文件:
文件上传
commons-fileupload-1.3.2.jar、commons-io-2.5.jar
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传实例 - 菜鸟教程</title>
</head>
<body>
<h1>文件上传实例 - 菜鸟教程</h1>
<form method="post" action="/TomcatTest/UploadServlet" enctype="multipart/form-data">
选择一个文件:
<input type="file" name="uploadFile" />
<br/><br/>
<input type="submit" value="上传" />
</form>
</body>
</html>
package com.runoob.test;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* Servlet implementation class UploadServlet
*/
// 如果不配置 web.xml ,可以使用下面的代码
// @WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 上传文件存储目录
private static final String UPLOAD_DIRECTORY = "upload";
// 上传配置
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
/**
* 上传数据及保存文件
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 检测是否为多媒体上传
if (!ServletFileUpload.isMultipartContent(request)) {
// 如果不是则停止
PrintWriter writer = response.getWriter();
writer.println("Error: 表单必须包含 enctype=multipart/form-data");
writer.flush();
return;
}
// 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);
// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);
// 中文处理
upload.setHeaderEncoding("UTF-8");
// 构造临时路径来存储上传的文件
// 这个路径相对当前应用的目录
String uploadPath = getServletContext().getRealPath("/") + File.separator + UPLOAD_DIRECTORY;
// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
// 解析请求的内容提取文件数据
@SuppressWarnings("unchecked")
List<FileItem> formItems = upload.parseRequest(request);
if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (FileItem item : formItems) {
// 处理不在表单中的字段
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
// 在控制台输出文件的上传路径
System.out.println(filePath);
// 保存文件到硬盘
item.write(storeFile);
request.setAttribute("message",
"文件上传成功!");
}
}
}
} catch (Exception ex) {
request.setAttribute("message",
"错误信息: " + ex.getMessage());
}
// 跳转到 message.jsp
getServletContext().getRequestDispatcher("/message.jsp").forward(
request, response);
}
}
页面重定向
<%
// 重定向到新地址
String site = new String("http://www.runoob.com");
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site);
%>
页面刷新
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<html>
<head>
<title>自动刷新实例</title>
</head>
<body>
<h2>自动刷新实</h2>
<%
// 设置每隔5秒刷新一次
response.setIntHeader("Refresh", 5);
// 获取当前时间
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;
out.println("当前时间为: " + CT + "\n");
%>
</body>
</html>
JavaBean
访问JavaBean
<jsp:useBean id="bean 的名字" scope="bean 的作用域" typeSpec/>
访问 JavaBean 对象的属性
<jsp:useBean id="id" class="bean 编译的类" scope="bean 作用域">
<jsp:setProperty name="bean 的 id" property="属性名"
value="value"/>
<jsp:getProperty name="bean 的 id" property="属性名"/>
...........
</jsp:useBean>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>get 和 set 属性实例</title>
</head>
<body>
<jsp:useBean id="students"
class="com.runoob.StudentsBean">
<jsp:setProperty name="students" property="firstName"
value="小强"/>
<jsp:setProperty name="students" property="lastName"
value="王"/>
<jsp:setProperty name="students" property="age"
value="10"/>
</jsp:useBean>
<p>学生名字:
<jsp:getProperty name="students" property="firstName"/>
</p>
<p>学生姓氏:
<jsp:getProperty name="students" property="lastName"/>
</p>
<p>学生年龄:
<jsp:getProperty name="students" property="age"/>
</p>
</body>
</html>
JSP 自定义标签
自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时将被转化为servlet,标签转化为对被 称为tag handler的对象的操作,即当servlet执行时Web container调用那些操作
可以继承SimpleTagSupport类并重写的doTag()方法来开发一个最简单的自定义标签
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("Hello Custom Tag!");
}
}
创建如下标签库 webapps\ROOT\WEB-INF\custom.tld
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello/>
</body>
</html>
可以像标准标签库一样在标签中包含消息内容
<ex:Hello>
This is message body
</ex:Hello>
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException
{
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello>
This is message body
</ex:Hello>
</body>
</html>
自定义标签属性
可以在自定义标准中设置各种属性,要接收属性,值自定义标签类必须实现setter方法, JavaBean 中的setter方法如下所示
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
private String message;
public void setMessage(String msg) {
this.message = msg;
}
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException
{
if (message != null) {
/* 从属性中使用消息 */
JspWriter out = getJspContext().getOut();
out.println( message );
}
else {
/* 从内容体中使用消息 */
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
}
属性的名称是"message",所以setter方法是的setMessage()。在TLD文件中使用的<attribute>
元素添加此属性
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>message</name>
</attribute>
</tag>
</taglib>
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello message="This is custom tag" />
</body>
</html>
属性 | 描述 |
---|---|
name | 定义属性的名称。每个标签的是属性名称必须是唯一的。 |
required | 指定属性是否是必须的或者可选的,如果设置为false为可选。 |
rtexprvalue | 声明在运行表达式时,标签属性是否有效。 |
type | 定义该属性的Java类类型 。默认指定为 String |
description | 描述信息 |
fragment | 如果声明了该属性,属性值将被视为一个 JspFragment。 |
<attribute>
<name>attribute_name1</name>
<required>false</required>
<type>java.util.Boolean</type>
<fragment>false</fragment>
</attribute>
<attribute>
<name>attribute_name2</name>
<required>true</required>
<type>java.util.Date</type>
</attribute>
El表达式
<jsp:setProperty name="box" property="perimeter" value="100"/>
<jsp:setProperty name="box" property="perimeter" value="${2*box.width+2*box.height}"/>
<jsp:text>
Box Perimeter is: ${2*box.width + 2*box.height}
</jsp:text>
想要停用对EL表达式的评估的话,需要使用page指令将isELIgnored属性值设为true,EL表达式就会被忽略。若设为false,则容器将会计算EL表达式
<%@ page isELIgnored ="true|false" %>
操作符 | 描述 |
---|---|
. | 访问一个Bean属性或者一个映射条目 |
[] | 访问一个数组或者链表的元素 |
( ) | 组织一个子表达式以改变优先级 |
+ | 加 |
- | 减或负 |
* | 乘 |
/ or div | 除 |
% or mod | 取模 |
== or eq | 测试是否相等 |
!= or ne | 测试是否不等 |
< or lt | 测试是否小于 |
> or gt | 测试是否大于 |
<= or le | 测试是否小于等于 |
>= or ge | 测试是否大于等于 |
&& or and | 测试逻辑与 |
|| or or | 测试逻辑或 |
! or not | 测试取反 |
empty | 测试是否空值 |
JSP EL中的函数
JSP EL允许您在表达式中使用函数。这些函数必须被定义在自定义标签库中。函数的使用语法如下:
${ns:func(param1, param2, ...)}
ns指的是命名空间(namespace),func指的是函数的名称,param1指的是第一个参数,param2指的是第二个参数,以此类推。比如,有函数fn:length,在JSTL库中定义,可以像下面这样来获取一个字符串的长度:
${fn:length("Get my length")}
要使用任何标签库中的函数,您需要将这些库安装在服务器中,然后使用<taglib>
标签在JSP文件中包含这些库。
EL隐含对象
除了pageContext对象是PageContext类型,其余都是 Map类型
隐含对象 | 描述 |
---|---|
pageScope | page 作用域 |
requestScope | request 作用域 |
sessionScope | session 作用域 |
applicationScope | application 作用域 |
param | Request 对象的参数,字符串 |
paramValues | Request对象的参数,字符串集合 |
header | HTTP 信息头,字符串 |
headerValues | HTTP 信息头,字符串集合 |
initParam | 上下文初始化参数 |
cookie | Cookie值 |
pageContext | 当前页面的pageContext |
pageContext对象是JSP中pageContext对象的引用。通过pageContext对象,您可以访问request对象。比如,访问request对象传入的查询字符串,就像这样:
${pageContext.request.queryString}
pageScope,requestScope,sessionScope,applicationScope变量用来访问存储在各个作用域层次的变量。举例来说,如果需要显式访问在applicationScope层的box变量,可以这样来访问:applicationScope.box。
param和paramValues对象用来访问参数值,通过使用request.getParameter方法和request.getParameterValues方法。举例来说,访问一个名为order的参数,可以这样使用表达式:{param[“order”]}。
<%@ page import="java.io.*,java.util.*" %>
<%
String title = "Accessing Request Param";
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align="center">
<p>${param["username"]}</p>
</div>
</body>
</html>
param对象返回单一的字符串,而paramValues对象则返回一个字符串数组。
header和headerValues对象用来访问信息头,通过使用 request.getHeader方法和request.getHeaders方法。
举例来说,要访问一个名为user-agent的信息头,可以这样使用表达式:{header[“user-agent”]}。
访问user-agent信息头:
<%@ page import="java.io.*,java.util.*" %>
<%
String title = "User Agent Example";
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align="center">
<p>${header["user-agent"]}</p>
</div>
</body>
</html>
异常处理
序号 | 方法&描述 |
---|---|
1 | **public String getMessage()**返回异常的信息。这个信息在Throwable构造函数中被初始化 |
2 | **public ThrowablegetCause()**返回引起异常的原因,类型为Throwable对象 |
3 | **public String toString()**返回类名 |
4 | **public void printStackTrace()**将异常栈轨迹输出至System.err |
5 | **public StackTraceElement [] getStackTrace()**以栈轨迹元素数组的形式返回异常栈轨迹 |
6 | **public ThrowablefillInStackTrace()**使用当前栈轨迹填充Throwable对象 |
<%@ page errorPage="ShowError.jsp" %>
<html>
<head>
<title>Error Handling Example</title>
</head>
<body>
<%
// Throw an exception to invoke the error page
int x = 1;
if (x == 1)
{
throw new RuntimeException("Error condition!!!");
}
%>
</body>
</html>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>Show Error Page</title>
</head>
<body>
<h1>Opps...</h1>
<p>Sorry, an error occurred.</p>
<p>Here is the exception stack trace: </p>
<pre>
<% exception.printStackTrace(response.getWriter()); %>
Q.E.D.