JSP
与PHP
、ASP
、ASP.NET
等语言类似,运行在服务端的语言,文件以.jsp
为后缀名。
生命周期
jsp
生命周期共分为5个阶段:
- 翻译阶段(第一次访问时,
.jsp
文件被翻译成.java
文件); - 编译阶段(第一次访问时,
.java
文件被编译成.class
文件); - 初始化阶段(第一次访问时,加载相关
servlet
类,创建实例,执行构造方法、_jspInit()
方法); - 执行阶段(执行
_jspService()
方法); - 销毁阶段(执行
_jspDestroy()
方法);
如果jsp
文件修改过,那么在之后的第一次访问时会重新翻译与编译。
还有一个很无聊的小测试,测试.java
、.class
文件被删除之后会发生什么。
翻译阶段
servlet
容器将.jsp
文件翻译为.java
文件,保存在%Tomcat_Home%/work
文件夹相应工程目录下:
<%--
Created by IntelliJ IDEA.
User: Ving_SuiXin
Date: 2018/4/27
Time: 10:59
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>
<p>测试JSP页面</p>
</body>
</html>
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/9.0.5
* Generated at: 2018-04-27 03:09:00 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
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 {
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET, POST or HEAD. Jasper also permits OPTIONS");
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,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write(" <p>测试JSP页面</p>\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
编译阶段
servlet
容器将.jsp
文件翻译为.java
文件之后,就和正常的流程一样,将.java
文件编译为.class
字节码文件,然后就可以在jvm
中运行了。
一个很无聊的小测试
.jsp
文件在这个页面第一次被访问(所有用户中的第一次访问)时,会执行翻译和编译的阶段。
那么假如我在第1
次访问之后,第N
次访问之前,手痒把翻译之后的.java
文件和编译之后的.class
删了,那会发生什么,这是一个很无聊的测试,测试前我已经想到了结果,但是就想亲眼看看。
下面的测试都是建立在JSP
页面已经被第一次访问的情况下:
- 删除
.java
文件和.class
文件:第N
次访问的时候重新经历了一遍翻译和编译阶段; - 删除
.class
文件:第N次访问的时候重新经历了一次编译阶段; - 删除
.java
文件:什么都没发生,页面照常显示,而.java
文件并没有再次生成,也就是并没有再次经历翻译阶段。
这个结果在预料之内,毕竟有能拿来直接执行的,没必要再翻译一遍。
解决中文乱码
页面中文乱码
在页面第一行加入以下语句:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
例如:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<!-- meta标签可以不必再次设置内容类型以及编码类型,依照个人习惯 -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
</head>
<body>
</body>
</html>
参数中文乱码
获取参数时进行转码:
<%
String parameter
= new String((request.getParameter("parameterName")).getBytes("ISO-8859-1"),"UTF-8");
%>
基本语法
jsp
中除了部分格式需要注意之外,其他语法结构与Java
并无二致(因其本身就是Java
的一种运用);
jsp
支持所有Java逻辑和算术运算符。
脚本
jsp
页面中的脚本代码的格式为:
<% 脚本代码;(';'必须加) %>
或者:
<jsp:scriptlet>
脚本代码;(';'必须加)
</jsp:scriptlet>
声明
jsp
页面中的变量、方法声明的格式为:
<%! 变量、方法声明;(';'必须加) %>
或者:
<jsp:declaration>
变量、方法声明;(';'必须加)
</jsp:declaration>
表达式
jsp
页面中的表达式的格式为:
<%= 表达式(不能加';') %>
或者:
<jsp:expression>
表达式(不能加';')
</jsp:expression>
注释
jsp
页面中的注释方式有两类,分为显式注释和隐式注释。
显式注释会在用户查看页面源代码的时候显示,而隐式注释则不会显示。
显式注释:
<!-- 我是显式注释(HTML注释方式) -->
隐式注释:
<%
//隐式注释一行代码(Java注释方式)
/*
隐式注释多行代码(Java注释方式)
*/
%>
<%-- jsp独特注释方式,也是隐式的 --%>
控制流语句
在jsp
页面中,控制流语句可以全部写在脚本块中,输出部分使用out.println("输出内容");
;也可以用%>输出内容<%
的形式。
下面用if……else……
来举例:
<% if (day == 1 | day == 7) { %>
<p>今天是周末</p>
<% } else { %>
<p>今天不是周末</p>
<% } %>
等价于:
<%
if (day == 1 | day == 7) {
out.println("<p>今天是周末</p>");
} else {
out.println("<p>今天不是周末</p>");
}
%>
编译指令
jsp
共有三大指令用来设置整个JSP页面相关的属性,并且它们都是在编译阶段执行的:
- page指令:定义网页依赖属性,比如脚本语言、error页面、缓存需求等等;
- include指令:包含其他文件;
- taglib指令:引入标签库的定义。
它们的通用语法格式为:
<%@ directive attribute="value" %>
page指令
page
指令为容器提供当前页面的使用说明。
<%@ page attribute="value" %>
等价于:
<jsp:directive.page attribute="value" />
可以把多条page
指令合并为一条:
<%@ page attribute_1="value_1" attribute_2="value_2" ··· attribute_N="value_N" %>
<jsp:directive.page attribute_1="value_1" attribute_2="value_2" ··· attribute_N="value_N" />
等价于:
<%@ page attribute_1="value_1" %>
<%@ page attribute_2="value_2" %>
···
<%@ page attribute_N="value_N" %>
<jsp:directive.page attribute_1="value_1" />
<jsp:directive.page attribute_2="value_2" />
···
<jsp:directive.page attribute_N="value_N" />
属性表:
属性 | 描述 |
---|---|
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 | 确定脚本元素能否被使用 |
include指令
jsp
可以通过include
指令来包含其他文件。被包含的文件可以是jsp
文件、HTML
文件或文本文件。
包含的文件会随jsp
页面一同被编译为一份完整的页面文件,而不是在访问该jsp
页面时才加载。
<%@ include file="文件的相对路径" %>
等价于:
<jsp:directive.include file="文件相对 url 地址" />
taglib指令
taglib
指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
<%@ taglib uri="标签库位置" prefix="调用标签库时所使用的前缀" %>
等价于
<jsp:directive.taglib uri="标签库位置" prefix="调用标签库时所使用的前缀" />
动作元素
jsp
的动作元素在用户对页面进行访问请求时动态执行,共七种:
- include动作;
- useBean动作;
- setProperty动作;
- getProperty动作;
- param动作;
- forward动作;
- plugin动作;
include动作
jsp:include
动作用来包含静态和动态的文件。
与include
指令所不同的是,jsp:include
动作是在页面被访问时才会动态引入包含文件。
<jsp:include page="文件的相对路径" flush="包含资源前是否刷新缓存区" />
属性 | 描述 |
---|---|
page | 包含在页面中的文件的相对路径 |
flush | 布尔属性,定义在包含资源前是否刷新缓存区 |
useBean动作
jsp:useBean
动作用来加载一个将在jsp
页面中使用的JavaBean
。
jsp:useBean
动作最简单的语法为:
<jsp:useBean id="name" class="package.class" />
属性 | 描述 |
---|---|
id | 唯一标识符 |
class | 指定JavaBean对象类型的完全限定名 |
scope | 指定该JavaBean的作用域:page(默认),request,session,application |
type | 指定将引用该对象变量的类型 |
beanName | 该名字被提供给java.beans.Beans类的instantiate()方法,以此来实例化一个JavaBean |
scope属性有四个可选值:
- application:表示在服务器重启之前都有效,可以通过
application.getAttribute()
方法取得JavaBean
对象。 - session:表示在当前会话周期内有效,可以通过
HttpSession.getAttribute(id)
方法取得JavaBean
对象。 - request:表示在当前请求中才有效,可以通过
HttpRequest.getAttribute(id)
方法取得JavaBean
对象; - page:默认选项,表示只有在当前页面有效。
setProperty动作
jsp:setProperty
动作用来设置已经实例化的JavaBean
对象的属性,有两种用法:
<jsp:useBean id="myName" ... />
...
<jsp:setProperty name="myName" property="someProperty" .../>
此时,不管jsp:useBean
是找到了一个现有的Bean
,还是新创建了一个Bean
实例,jsp:setProperty
都会执行。
<jsp:useBean id="myName" ... >
...
<jsp:setProperty name="myName" property="someProperty" .../>
</jsp:useBean>
此时,jsp:setProperty
只有在新建Bean
实例时才会执行,如果是使用现有实例则不执行jsp:setProperty
。
属性 | 描述 |
---|---|
name | name属性是必需的,它表示要设置属性的是哪个Bean |
property | property属性是必需的,它表示要设置哪个属性。有一个特殊用法:如果property的值是*,表示请求中所有名字和Bean属性名字匹配的参数都将被传递给相应的属性set方法 |
value | value属性是可选的,该属性用来指定Bean属性的,value属性和param属性不能同时使用,但可以使用其中任意一个 |
param | param属性是可选的,它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值 |
getProperty动作
jsp:getProperty
动作提取指定Bean
属性的值,转换成字符串,然后输出。
<jsp:getProperty name="beanName" property="targetProperty" />
属性 | 描述 |
---|---|
name | 要检索的Bean属性名称,Bean必须已定义 |
property | 表示要提取Bean属性的值 |
param动作
jsp:param
动作被用来以"key-value"
对的形式为其他标签提供附加信息。
jsp:param
动作通常和jsp:include
动作、jsp:forward
动作、jsp:plugin
动作一起使用。
<jsp:param name="paramName" value="paramValue"/>
属性 | 描述 |
---|---|
name | 属性的名字 |
property | 属性的值 |
forward动作
jsp:forward
动作把请求转到另外的页面。
<jsp:forward page="页面的相对路径" />
属性 | 描述 |
---|---|
page | 页面的相对路径,既可以直接给出,也可以在请求的时候动态计算;可以是一个jsp页面,或者一个Servlet |
plugin动作
jsp:plugin
动作用来根据浏览器的类型,插入通过Java
插件运行Java Applet
所必需的OBJECT
或EMBED
元素。
如果需要的插件不存在,它会下载插件,然后执行Java
组件。
Java
组件可以是一个Java Applet
或是一个JavaBean
。
jsp:plugin
动作有多个对应HTML
元素的属性用于格式化Java
组件,通常使用jsp: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>
Applet error.
</jsp:fallback>
</jsp:plugin>
<jsp:fallback>
元素是一个新元素,在组件出现故障的错误时发送给用户错误信息。
隐式对象
jsp
内置的九大对象可以直接使用而不用显式声明:
- request:
HttpServletRequest
接口的实例 - response:
HttpServletResponse
接口的实例 - out:
JspWriter
类的实例,用于把结果输出至网页上 - session:
HttpSession
类的实例,在某个用户和服务器的访问会话期间一直存在 - application:
ServletContext
类的实例,服务器启动时产生,直到因服务器关闭而销毁,多用户共享。 - config:
ServletConfig
类的实例 - pageContext:
PageContext
类的实例,提供对jsp
页面所有对象以及命名空间的访问 - page:类似于
Java
类中的this
关键字 - exception:
Throwable
子类的实例对象,代表发生错误的jsp
页面中对应的异常对象
还有,Cookie
不属于九大内置对象。
request对象
每当客户端请求一个jsp
页面时,jsp
引擎就会制造一个新的request
对象来代表这个请求。
request
对象常用方法(原文链接):
方法 | 描述 |
---|---|
Cookie[] getCookies() | 返回客户端所有的Cookie的数组 |
Enumeration getAttributeNames() | 返回request对象的所有属性名称的集合 |
Enumeration getHeaderNames() | 返回所有HTTP头的名称集合 |
Enumeration getParameterNames() | 返回请求中所有参数的集合 |
HttpSession getSession() | 返回request对应的session对象,如果没有,则创建一个 |
HttpSession getSession(boolean create) | 返回request对应的session对象,如果没有并且参数create为true,则返回一个新的session对象 |
Locale getLocale() | 返回当前页的Locale对象,可以在response中设置 |
Object getAttribute(String name) | 返回名称为name的属性值,如果不存在则返回null |
ServletInputStream getInputStream() | 返回请求的输入流 |
String getAuthType() | 返回认证方案的名称,用来保护servlet,比如 “BASIC” 或者 “SSL” 或 null(如果 JSP没设置保护措施) |
String getCharacterEncoding() | 返回request的字符编码集名称 |
String getContentType() | 返回request主体的MIME类型,若未知则返回null |
String getContextPath() | 返回request URI中指明的上下文路径 |
String getHeader(String name) | 返回name指定的信息头 |
String getMethod() | 返回此request中的HTTP方法,比如 GET,,POST,或PUT |
String getParameter(String name) | 返回此request中name指定的参数,若不存在则返回null |
String getPathInfo() | 返回任何额外的与此request URL相关的路径 |
String getProtocol() | 返回此request所使用的协议名和版本 |
String getQueryString() | 返回此 request URL包含的查询字符串 |
String getRemoteAddr() | 返回客户端的IP地址 |
String getRemoteHost() | 返回客户端的完整名称 |
String getRemoteUser() | 返回客户端通过登录认证的用户,若用户未认证则返回null |
String getRequestURI() | 返回request的URI |
String getRequestedSessionId() | 返回request指定的session ID |
String getServletPath() | 返回所请求的servlet路径 |
String[] getParameterValues(String name) | 返回指定名称的参数的所有值,若不存在则返回null |
boolean isSecure() | 返回request是否使用了加密通道,比如HTTPS |
int getContentLength() | 返回request主体所包含的字节数,若未知的返回-1 |
int getIntHeader(String name) | 返回指定名称的request信息头的值 |
int getServerPort() | 返回服务器端口号 |
response对象
当服务器创建request对象时会同时创建用于响应这个客户端的response对象。
response
对象常用方法(原文链接):
方法 | 描述 |
---|---|
String encodeRedirectURL(String url) | 对sendRedirect()方法使用的URL进行编码 |
String encodeURL(String url) | 将URL编码,回传包含Session ID的URL |
boolean containsHeader(String name) | 返回指定的响应头是否存在 |
boolean isCommitted() | 返回响应是否已经提交到客户端 |
void addCookie(Cookie cookie) | 添加指定的cookie至响应中 |
void addDateHeader(String name, long date) | 添加指定名称的响应头和日期值 |
void addHeader(String name, String value) | 添加指定名称的响应头和值 |
void addIntHeader(String name, int value) | 添加指定名称的响应头和int值 |
void flushBuffer() | 将任何缓存中的内容写入客户端 |
void reset() | 清除任何缓存中的任何数据,包括状态码和各种响应头 |
void resetBuffer() | 清除基本的缓存数据,不包括响应头和状态码 |
void sendError(int sc) | 使用指定的状态码向客户端发送一个出错响应,然后清除缓存 |
void sendError(int sc, String msg) | 使用指定的状态码和消息向客户端发送一个出错响应 |
void sendRedirect(String location) | 使用指定的URL向客户端发送一个临时的间接响应 |
void setBufferSize(int size) | 设置响应体的缓存区大小 |
void setCharacterEncoding(String charset) | 指定响应的编码集(MIME字符集),例如UTF-8 |
void setContentLength(int len) | 指定HTTP servlets中响应的内容的长度,此方法用来设置 HTTP Content-Length 信息头 |
void setContentType(String type) | 设置响应的内容的类型,如果响应还未被提交的话 |
void setDateHeader(String name, long date) | 使用指定名称和值设置响应头的名称和内容 |
void setHeader(String name, String value) | 使用指定名称和值设置响应头的名称和内容 |
void setIntHeader(String name, int value) | 指定 int 类型的值到 name 标头 |
void setLocale(Locale loc) | 设置响应的语言环境,如果响应尚未被提交的话 |
void setStatus(int sc) | 设置响应的状态码 |
out对象
out
对象是 javax.servlet.jsp.JspWriter
类的实例,用来在response
对象中写入内容。
JspWriter
类包含了大部分java.io.PrintWriter
类中的方法,并且JspWriter
还新增了一些专为处理缓存而设计的方法,同时JspWriter
类会抛出IOExceptions
异常,而PrintWriter
不会。
下面是常用的out
对象的常用方法:
方法 | 描述 |
---|---|
out.print(dataType dt) | 输出Type类型的值 |
out.println(dataType dt) | 输出Type类型的值然后换行 |
out.flush() | 刷新输出流 |
session对象
session
对象用来跟踪在各个客户端请求间的会话。
当用户链接服务器的任一页面时产生一个session
对象,同时分配一个session
对象的id
号,直到因用户关闭浏览器而停止会话或者超过服务器设置的session
有效时间后消失,在此期间不论用户切换到哪一个页面,所对应的session
均为同一个。
我们通常在比较小的项目中选择将用户验证信息保存在session
对象中。
session
对象的常用方法有:
方法 | 描述 |
---|---|
public String getId() | 获取Session对象编号 |
public void setAttribute(String key,Object obj) | 将参数Object指定的对象obj添加到Session对象中,并为添加的对象指定一个索引关键字 |
public Object getAttribute(String key) | 获取Session对象中含有关键字的对象 |
public Boolean isNew() | 判断是否是一个新的客户 |
application对象
application对象
在服务器启动时产生,直到因服务器关闭而销毁,期间不管有多少用户链接服务器,每个用户又是访问了多少页面,application
对象都是同一个。
application
对象的常用方法有:
方法 | 描述 |
---|---|
setAttribute(String key,Object obj) | 将参数Object指定的对象obj添加到application对象中,并且指定一个索引关键字 |
getAttribute(String key) | 获取application对象中含有关键字的对象 |
config对象
config
对象允许开发者访问Servlet
或者jsp
引擎的初始化参数,比如文件路径等。
这个对象不常用。
pageContext对象
这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。
这个对象存储了request
对象和response
对象的引用,同时application
对象,config
对象,session
对象,out
对象也可以通过访问这个对象的属性来导出。
pageContext
对象也包含了传给jsp
页面的指令信息,包括缓存信息,ErrorPage URL
,页面scope
等。
PageContext
类中定义了一些字段,包括PAGE_SCOPE
,REQUEST_SCOPE
,SESSION_SCOPE
, APPLICATION_SCOPE
,它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext
类。
其中一个重要的方法就是removeAttribute()
,它可接受一个或两个参数。
page对象
page
对象就是页面实例的引用,它可以被看做是当前整个jsp
页面的代表,就和this
代表当前类的实例本身一样。
exception对象
exception
对象很独特,jsp
页面的默认设置导致它不能再默认条件下被使用,如果要使用,着需要使用page
指令将isErrorPage
属性的值设置为true
,声明这是一个异常处理页面(error.jsp
),同时需要在调用error.jsp
的页面中使用page
指令设置errorPage
属性的值为error.jsp
的相对路径。
error.jsp:
<%@ page isErrorPage="true" %>
调用error.jsp的页面:
<%@ page errorPage="error.jsp" %>
exception
对象的常用方法有:
方法 | 描述 |
---|---|
public String getMessage() | 返回异常的信息,这个信息在Throwable构造函数中被初始化 |
public ThrowablegetCause() | 返回引起异常的原因,类型为Throwable对象 |
public String toString() | 返回关于异常错误的简单信息描述 |
public void printStackTrace() | 以标准形式输出一个异常和异常的堆栈 |
public StackTraceElement [] getStackTrace() | 以栈轨迹元素数组的形式返回异常栈轨迹 |
public ThrowablefillInStackTrace() | 使用当前栈轨迹填充Throwable对象 |
Cookie
Cookie
是储存在用户本地的一些信息,如果没有设置过期时间,那么默认是在浏览器关闭时销毁。
jsp
及Servlet
中的Cookie
类的主要方法(原文地址):
方法 | 描述 |
---|---|
public void setDomain(String pattern) | 设置cookie的域名,比如 runoob.com |
public String getDomain() | 获取cookie的域名,比如 runoob.com |
public void setMaxAge(int expiry) | 设置cookie有效期,以秒为单位,默认有效期为当前session的存活时间 |
public int getMaxAge() | 获取cookie有效期,以秒为单位,默认为-1 ,表明cookie会活到浏览器关闭为止 |
public String getName() | 返回 cookie的名称,名称创建后将不能被修改 |
public void setValue(String newValue) | 设置 cookie的值 |
public String getValue() | 获取cookie的值 |
public void setPath(String uri) | 设置cookie 的路径,默认为当前页面目录下的所有URL,还有此目录下的所有子目录 |
public String getPath() | 获取cookie 的路径 |
public void setSecure(boolean flag) | 指明cookie是否要加密传输 |
public void setComment(String purpose) | 设置注释描述 cookie的目的,当浏览器将cookie展现给用户时,注释将会变得非常有用 |
public String getComment() | 返回描述cookie目的的注释,若没有则返回null |
另外,我们通过调用response.addCookie()
函数来向HTTP
响应头中添加需要保存到用户Cookie
中的键值对信息:
response.addCookie(cookie);
此外,我将在之后的HTTP
协议的学习中深入Cookie
。
JavaBean
JavaBean是一种特殊的Java类,需要遵守一定的规则:
- 需要被序列化并且实现了
Serializable
接口; - 提供一个默认的无参构造函数;
- 可能有一系列可读写属性;
- 可能有一系列的
getter
或setter
方法; - 为了使
null
更好地起到作用,建议更多地基本数据类型的包装类。
然后我们就可以通过useBean
动作、setProperty
动作、getProperty
动作轻松地使用JavaBean
了!