- JSP页面元素的构成:
静态内容
,注释
,声明
,小脚本
,表达式
,指令
。
- JSP指令
page
指令:通常位于jsp页面的顶端,同一个页面可以有多个page指令。
JSP的三大指令元素
<%@ page 属性1="属性值1" 属性2="属性值2" ...%>
<%-- 例如:--%>
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"%>
属性 |
描述 |
默认值 |
language |
指定JSP页面使用的脚本语言 |
java |
import |
通过该属性来引用脚本语言中使用到的类文件 |
无 |
contentType |
用来指定JSP页面所采用的编码方式 |
text/html,ISO-8859-1(纯英文,不支持中文),charset的值一般为utf-8。pageEncoding 是jsp文件本身的编码。contentType的charset是指服务器发给客户端时的内容编码 |
JSP注释
<!--html注释, 客户端可见-->
<%-- jsp注释,客户端不可见 --%>
<%
// JSP脚本注释:单行注释
/*
多行注释
服务器端的注释,客户端看不到
*/
out.println("我是jsp页面中的java代码,我向浏览器输出一条信息!");
%>
JSP脚本
<%
// Java代码
%>
JSP声明
<%! Java代码 %>
<%-- 例如:--%>
<%!
//在JSP页面中定义变量或者方法
String str = "张三";
int add(int a, int b) {
return a + b;
}
%>
JSP表达式
<%=表达式 %>
<%-- 注意:表达式不以分号结束,即不要在表达式后面添加分号 --%>
<%-- 例如使用上面JSP声明的变量和方法 --%>
你好,<%=str %>
<hr/>
x+y=<%=add(10, 3) %>
<hr/>
JSP页面的生命周期
- jspService()方法被调用来
处理客户端的请求
。对每一个请求,JSP引擎创建一个新的线程来处理该请求(为基于多线程的处理方式)。若有多个客户端同时请求该JSP文件,则JSP引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可以大大降低对系统的资源需求,提高系统的并发量及响应时间
,但也要注意多线程编程带来的同步问题。由于该Servlet始终驻于内存
,所以响应是非常快的。
- 当用户第一次请求一个jsp页面时,首先被执行的是
构造方法
。
<%!
String printMultiTable1() {
String str = "";
for(int i = 1; i <= 9; ++i) {
for(int j = 1; j <= i; ++j) {
str += i + "*" + j + "=" + (i * j) + " ";
}
str += "<br/>";
}
return str;
}
//JSP内置out对象,使用脚本方式调用,打印九九乘法表
void printMultiTable2(JspWriter out) throws IOException {
for(int i = 1; i <= 9; ++i) {
for(int j = 1; j <= i; ++j) {
out.println(i + "*" + j + "=" + (i * j) + " ");
}
out.println("<br/>");
}
}
%>
<hr/>
<h1>九九乘法表</h1>
<%=printMultiTable1() %>
<hr/>
<!-- 通过脚本方式调用定义的方法,遵循java代码要求 -->
<% printMultiTable2(out); %>
include
指令:将一个外部文件嵌入到当前JSP文件中,同时解析这个页面中的JSP语句。语法:<%@ include file="URL" %>
<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ page import="java.text.SimpleDateFormat"%>
<%@ page import="java.util.Date"%>
<%
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String s = sdf.format(d);
out.print(s);
%>
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<h1>Include指令和动作</h1>
<hr>
<!-- include指令 -->
<%@ include file="date.jsp" %>
<hr>
<!-- include动作 -->
<jsp:include page="date.jsp" flush="false"/>
</body>
</html>
- 启动tomcat服务器,访问
http://localhost:8080/MyJavaWebApp/include.jsp
,结果显示如下:
-
include动作
,语法:<jsp:include page="URL" flush="true|false" />
。其中,page
指要包含的页面
;flush
指被包含的页面是否从缓冲区读取
,若为true,则表示使用缓冲数据,否则表示不使用缓冲数据。
-
forward动作
,语法:<jsp:forward page="URL" />
等同于服务器内部跳转指令:request.getRequestDispatcher("/url").forward(request, response);
taglib
指令:使用标签库定义新的自定义标签,在JSP页面中启用定制行为。
JSP内置对象
- JSP内置对象是Web容器创建的一组对象,
不使用new关键字
就可以直接使用的内置对象。比如:out
对象。
- JSP九大内置对象:
out
、request
、response
、session
、application
、Page、PageContext、exception、config
- Web程序的请求响应模式:用户发送请求(
request
),服务器给用户响应(response
)。
- 缓冲区:Buffer,即内存的一块区域用来保存
临时数据
。
- out对象:JspWriter类的实例,是向客户端(浏览器)输出内容常用的对象。
- 常用方法如下:
- void println(); 向客户端(浏览器)打印字符串。
- void clear(); 清除缓冲区的内容,
若其在flush()方法后被调用则会抛出异常
。
- void clearBuffer(); 清除缓冲区的内容,
若其在flush()方法之后被调用则不会抛出异常
。
- void flush(); 将缓冲区内容输出到客户端(浏览器)。
- int getBufferSize(); 返回
JSP页面缓冲区总字节数的大小
。
- int getRemaining(); 返回缓冲区还剩余多少可用。
- boolean isAutoFlush(); 返回缓冲区满时,是自动清空还是抛出异常。
- void close(); 关闭输出流。
<%
out.flush();
//clear()方法不能在flush()方法后使用,会抛出异常
//out.clear();
out.clearBuffer();//而使用clearBuffer()方法则不会抛出异常
%>
缓冲区的大小:<%=out.getBufferSize() %>byte<br/>
缓冲区剩余大小:<%=out.getRemaining() %>byte<br/>
是否自动清空缓冲区:<%=out.isAutoFlush() %><br/>
- 表单提交的两种方式:
-
get
:以明文
的方式通过URL提交数据,数据在URL中可以看到。提交的数据不超过2KB
。安全性较低但效率比post方式高。适合提交数据量不大
,安全性不高
的数据。比如:搜索
、查询
等功能。
-
post
:将用户提交的信息封装在HTML HEADER
内。适合提交数据量大
,安全性高
的用户信息。比如:注册、修改、上传等功能。
<h1>用户登录表单</h1>
<%--不推荐使用get方式提交表单,因为url中包含要提交的数据,建议使用post方式提交表单--%>
<form action="doLogin.jsp" name="loginForm" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<%--colspan 属性规定单元格可横跨的列数--%>
<td colspan="2"><input type="submit" value="登录" /></td>
</tr>
</table>
</form>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>响应登录结果</title>
</head>
<body>
<h1>欢迎您,登录成功!</h1>
</body>
</html>
-
request对象
:客户端的请求信息被封装在request对象
中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例
。request对象具有请求域
,即完成客户端的请求之前,该对象一直有效
。常用方法如下:
- String getParameter(String name) : 返回name 指定参数的参数值
- String[] getParameterValues(String name): 返回包含参数name的所有值的数组
- void setAttribute(String, Object): 存储此请求中的属性
- object getAttribute(String name): 返回指定属性的属性值(键值对)
- String getContentType(): 得到请求体的MIME类型
- String getProtocol(): 返回请求用的协议类型及版本号
- String getServerName(): 返回接收请求的服务器主机名
- int getServerPort(): 返回服务器接收此请求所用的端口号
- String getCharacterEncoding(): 返回字符编码方式
- void setCharacterEncoding(): 设置请求的字符编码方式
- int getContentLength(): 返回请求体的长度(以字节数)
- String getRemoteAddr(): 返回发送此请求的客户端IP地址
- String getRealPath(String path): 返回某个文件的真实路径
- String request.getContextPath(): 返回上下文路径
<h1>用户注册</h1>
<form action="request.jsp" name="regForm" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>爱好:</td>
<td>
<input type="checkbox" name="favorite" value="read">读书
<input type="checkbox" name="favorite" value="music">音乐
<input type="checkbox" name="favorite" value="movie">电影
<input type="checkbox" name="favorite" value="internet">上网
</td>
</tr>
<tr>
<%--colspan 属性规定单元格可横跨的列数--%>
<td colspan="2"><input type="submit" value="登录" /></td>
</tr>
</table>
</form>
<%--URL传递中文需要更改tomcat配置文件server.xml:即添加URIEncoding="utf-8"
若不更改配置文件,则使用post/get请求就可以避免中文乱码
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="utf-8"/>
--%>
<a href="request.jsp?username=李四">测试URL传递参数</a>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<html>
<head>
<title>注册信息测试页面</title>
</head>
<body>
<h1>request内置对象</h1>
<%
//在接收数据的页面中解决中文乱码问题:设置当前页面与提交表单页面的字符集一致,但是其无法解决URL参数传递中文出现的乱码问题
request.setCharacterEncoding("utf-8");
//设置属性值
request.setAttribute("password", "123456");
%>
用户名:<%=request.getParameter("username") %> <br/>
爱好:<%
String[] favorites = request.getParameterValues("favorite");
if(favorites != null) {
for (int i = 0; i < favorites.length; ++i) {
out.println(favorites[i] + " ");
}
}
%>
<br/>
密码:<%=request.getAttribute("password") %><br/>
请求体的MIME类型:<%=request.getContentType() %><br/>
协议类型及版本号:<%=request.getProtocol() %><br/>
服务器主机名:<%=request.getServerName() %><br/>
服务器端口号:<%=request.getServerPort() %><br/>
请求文件的长度:<%=request.getContentLength() %><br/>
请求客户端的IP地址:<%=request.getRemoteAddr() %><br/>
请求的真实路径:<%=request.getRealPath("request.jsp") %><br/>
请求的上下文路径(虚拟访问路径):<%=request.getContextPath() %><br/>
</body>
</html>
-
response对象
包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例
。response对象具有页面作用域
,即访问一个页面时,该页面内的response对象只能对这次访问有效
,其他页面的response对象对当前页面无效。常用的方法如下:
- String getCharacterEncoding(): 返回响应用的是何种字符编码
- void setContentType(String type): 设置响应的MIME类型
- PrintWriter getWriter(): 返回可以向客户端输出字符的一个对象(注意比较:PrintWriter与内置对象out的区别)
- sendRedirect(java.lang.String location): 重新定向客户端的请求
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.io.PrintWriter" %>
<%
//设置响应的MIME类型
response.setContentType("text/html;charset=utf-8");
out.println("<h1>response内置对象</h1>");
out.println("<hr/>");
//PrintWriter对象的执行要比内置对象out提前,若要实现out先输出,则需要强制清空缓冲区,将缓冲区的内容刷新到浏览器页面中
//out.flush();
//获得输出流对象
PrintWriter outer = response.getWriter();
outer.println("大家好,我是response对象生成的输出流outer对象");
//请求重定向,注意使用之前要把前面的out.flush();代码注释掉,否则会抛出异常
//response.sendRedirect("request.jsp");
request.getRequestDispatcher("request.jsp").forward(request, response);
%>
请求转发与请求重定向
-
请求重定向
:客户端行为
;response.sendRedirect()
,从本质上讲等同于两次请求
,前一次的请求对象不会保存
,地址栏的URL地址会改变
。
-
请求转发
:服务器行为
,request.getRequestDispatcher().forward(req, resp)
; 是一次请求
,转发后请求对象会保存
,地址栏的URL地址不会改变
。
-
session
:表示客户端与服务器的一次会话,实际上是一个特定的时间概念
。
- Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。
- 在服务器的内存中保存着
不同用户的session
。
-
session对象
是一个JSP内置对象
。session对象在第一个JSP页面被装载时自动创建
,完成会话期管理。从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话
。当一个客户访问一个服务器时,可能会在服务器的几个页面之间切换,服务器应当通过某种办法知道这是一个客户,就需要session对象
。session对象是HttpSession
类的实例。常用方法如下:
- long getCreationTime(): 返回SESSION对象的创建时间,单位是
毫秒
- public String getId(): 返回SESSION创建时JSP引擎为它设置的唯一ID号
- public Object setAttribute(String name, Object value): 使用指定名称将对象绑定到此会话
- public Object getAttribute(String name): 返回与此会话中的指定名称绑定在一起的对象,若没有对象绑定在该名称下,则返回null
- String[] getValueNames(): 返回一个包含此SESSION中所有可用属性的数组
- int getMaxInactiveInterval(): 返回两次请求间隔多长时间此SESSION被取消(单位:秒)
- void setMaxInactiveInterval(): 设置当前session的最大生存期限(单位:秒)
<h1>session内置对象</h1>
<%
SimpleDateFormat sdft = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date d = new Date(session.getCreationTime());
session.setAttribute("pwd", "admin");
session.setAttribute("user", "张三");
session.setAttribute("age", 20);
//设置当前session的最大生存期限,单位:秒
session.setMaxInactiveInterval(10); //10秒钟
%>
Session对象的创建时间:<%=sdft.format(d) %><br/>
Session的ID编号:<%=session.getId() %><br/>
从Session对象中获取密码:<%=session.getAttribute("pwd") %><br/>
<a href="doLogin.jsp" target="_blank">跳转到新的页面来测试是否为同一个session</a>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>响应登录结果</title>
</head>
<body>
<h1>欢迎您,登录成功!</h1>
<h1>Session内置对象</h1>
Session的ID编号:<%=session.getId() %><br/>
从Session对象中获取密码:<%=session.getAttribute("pwd") %><br/>
Session对象中保存的属性有:<%
String[] names = session.getValueNames();
for (String name : names) {
out.println(name + " ");
}
%><br/>
</body>
</html>
Session的生命周期
-
创建阶段
:当客户端第一次访问某个jsp或者servlet时,服务器会为当前会话创建一个SessionId,每次客户端向服务端发送请求时,都会将此SessionId携带进去,服务端会对此SessionId进行校验。
-
活动阶段
:某次会话当中通过超链接打开的新页面属于同一次会话
。只要当前会话页面没有全部关闭,重新打开新的浏览器窗口访问同一项目资源时属于同一次会话。除非本次会话的所有页面都关闭后(或者超时
)再重新访问某个jsp或者servlet将会创建新的会话。
- 注意:原有会话还存在,旧的SessionId仍然存在于服务端中,只不过客户端发送的请求中再也不会携带它交予服务端检验!
-
销毁阶段
:Session的销毁只有三种方式:1、调用了session.invalidate()
方法;2、Session过期
(超时);3、服务器重新启动
。
- Tomcat服务器默认的session超时时间为
30分钟
。
- 设置
Session会话过期
的方式有2种:
- 1、在web.xml文件中添加以下代码:
<!--设置会话一分钟后过期,单位:分钟-->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
- 2、在jsp页面中使用
session.setMaxInactiveInterval(秒数)
。
-
application对象
:application对象实现了用户之间数据的共享
,可存放于全局变量
。
- application开始于服务器的启动,终止于服务器的关闭。即服务器的启动和关闭决定了application对象的生命周期。application对象是
ServletContext
类的实例。
- 在用户的前后连接或不同用户之间的连接中,可以对application对象的同一属性进行操作。在任何地方对application对象属性的操作,都将影响到其他用户对服务端的访问(相当于
访问java类名.公有的静态变量或方法
)。常用方法如下:
- public void setAttribute(String name, Object value): 使用指定名称将对象绑定到此会话。
- public Object getAttribute(String name): 返回与此会话中的指定名称绑定在一起的对象,若没有对象绑定在该名称下,则返回null。
- Enumeration getAttributeNames(): 返回所有可用属性名的枚举。
- String getServerInfo(): 返回JSP(SERVLET)引擎名及版本号。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.Enumeration" %>
<html>
<head>
<title>application内置对象</title>
</head>
<body>
<%
application.setAttribute("city", "北京");
application.setAttribute("postcode", "10000");
application.setAttribute("email", "lisi@qq.com");
%>
所在的城市是:<%=application.getAttribute("city") %><br/>
application对象中的属性有:<%
Enumeration attributes = application.getAttributeNames();
while(attributes.hasMoreElements()) {
out.print(attributes.nextElement() + "<br/>");
}
%><br/>
JSP(SERVLET)引擎名及版本号:<%=application.getServerInfo() %><br/>
</body>
</html>
-
page对象
:就是指向当前JSP页面本身,有点像类中的this指针,它是java.lang.Object类的实例。常用方法如下:
- class getClass():返回此Object的类
- int hasCode():返回此Object的hash码
- boolean equals(Object obj):判断此Object是否与指定的Object对象相等
- void copy(Object obj):把此Object拷贝到指定的Object对象中
- Object clone():克隆此Object对象
- String toString():把此Object对象转换成String类的对象
- void notify():唤醒一个等待的进程
- void notifyAll():唤醒所有等待的进程
- void wait(int timeout):使一个线程处于等待直到timeout结束或被唤醒
- void wait():使一个线程处于等待直到被唤醒
-
pageContext对象
:其提供了对JSP页面内所有的对象
及名字空间
的访问;其可以访问到本页所在的session,也可以取本页所在的application的某一属性值;其相当于页面中所有功能的集大成者
。其本类名也叫pageContext
。常用方法如下:
- JspWriter getOut():返回当前客户端响应被使用的JspWriter流(out)
- HttpSession getSession():返回当前页中的HttpSession对象(session)
- Object getPage():返回当前页面的Object对象(page)
- ServletRequest getRequest():返回当前页面的ServletRequest对象(request)
- ServletResponse getResponse():返回当前页面的ServletResponse对象(response)
- void setAttribute(String name, Object attribute):设置属性及属性值
- Object getAttribute(String name, int scope):在指定范围内取属性的值
- int getAttributeScope(String name):返回某属性的作用范围
- void forward(String relativeUrlPath):使当前页面重导到另一页面
- void include(String relativeUrlPath):在当前位置包含另一文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String s = sdf.format(date);
out.println(s + "<br/>");
%>
<html>
<head>
<title>测试包含jsp文件的页面</title>
</head>
<body>
我是include.jsp文件,我被包含了!
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>pageContext内置对象</title>
</head>
<body>
<h1>测试pageContext内置对象</h1>
密码是:<%=pageContext.getSession().getAttribute("pwd") %>
<hr/>
日期为:
<%
// 跳转到注册界面
// pageContext.forward("request.jsp");
// 包含include.jsp文件
pageContext.include("include.jsp");
%>
</body>
</html>
- 重新启动tomcat服务器,访问主页
http://localhost:8080/tomcatdemo/
,然后访问http://localhost:8080/tomcatdemo/pageContext.jsp
,结果显示如下:
-
Config对象
:在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值即键值对构成)以及服务器的有关信息(通过传递一个ServletContext对象),常用方法如下:
- ServletContext getServletContext():返回含有服务器相关信息的ServletContext对象
- String getInitParameter(String name):返回初始化参数的值
- Enumeration getInitParameterNames():返回Servlet初始化所需所有参数的枚举
-
Exception对象
:一个异常对象,当一个页面在运行过程中发生异常,就产生了这个对象。如果一个JSP页面要应用此对象,就必须在其页面中将isErrorPage
设为true,否则无法编译。它实际上是java.lang.Throwable的对象,常用方法如下:
- String getMessage():返回描述异常的信息
- String toString():返回关于异常的简短描述信息
- void printStackTrace():显示异常及其栈轨迹
- Throwable FillInStackTrace():重写异常的执行栈轨迹
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="exception2.jsp" %>
<%-- 指定抛出的异常让exception2.jsp文件去处理 --%>
<html>
<head>
<title>测试异常</title>
</head>
<body>
<h1>测试异常exception</h1>
<%
// 抛出运行时算数异常
System.out.println(100/0);
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<%--当前页面要处理异常,则必须将isErrorPage属性设置为true--%>
<html>
<head>
<title>测试exception内置对象</title>
</head>
<body>
<h1>exception内置对象</h1>
异常消息是:<%=exception.getMessage() %><br/>
异常的字符串描述:<%=exception.toString() %>
</body>
</html>
- 重启tomcat服务器,访问
http://localhost:8080/tomcatdemo/exception1.jsp
,结果显示如下: