教材:梁永先等. Java Web程序设计(慕课版 第2版),人民邮电出版社,2021.
供本人复习使用。
5.0 准备
打开Eclipse,工具栏中Window—>Perspective—>Open Perspective—>Web
更改JSP Files编码为UTF-8。
5.1 JSP概述
5.1.1 什么是JSP
JSP(Java Server Pages)是由Sun公司倡导、许多公司参与而建立的动态网页技术标准。它在HTML代码中嵌入Java代码片段(Scriptlet)和JSP标签,构成了JSP网页。在接收到用户请求时,服务器会处理Java代码片段,然后生成处理结果的HTML页面返回给客户端,客户端的浏览器将呈现最终页面效果。
工作原理如下:
5.1.2 如何学好JSP
- 了解Web设计流程与工作原理。
- 了解MVC设计模式。
- 多实践,多思考,多请教。
- 不要急躁。
- 遇到问题首先自己尝试解决。
- 多查阅资料。
- 多阅读别人的源码。
- 熟练掌握HTML、CSS、JavaScript技术。
- 掌握主流的框架技术,如Struts、MyBaines和Spring等。
- 掌握SQL和JDBC对关系型数据库的操作。
- 熟悉常用的Web服务器的管理,如Tomcat。
5.1.3 JSP技术特征
JSP技术所开发的Web应用是基于Java的,它拥有Java语言的一些特性。
- 跨平台
- 业务代码分离
- 组件重用
- 继承Java Servlet功能
- 预编译
5.2 了解JSP的基本构成
【例5-1】了解JSP页面的基本构成。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>一个简单的JSP页面</title>
</head>
<body>
<!-- HTML注释信息 -->
<%
Date now = new Date();
String dateStr;
dateStr = String.format("%tY年%tm月%td日", now, now, now);
%>
当前日期是:<%=dateStr%>
<br>
</body>
</html>
5.3 指令标签
5.3.1 page指令
page指令,用于定义整个JSP页面的相关属性,这些属性在JSP被服务器解析成Servlet时会转换为相应的Java程序代码。
语法格式:
<%@page attr1="value1" attr2="value2" ... %>
- language属性
该属性用于设置JSP页面使用的语言,目前只支持Java语言,以后可能会支持其他语言,如C++、C#等。该属性的默认值是Java。
<%@ page language="java"%>
- extends属性
该属性用于设置JSP页面继承的Java类,所有JSP页面在执行之前都会被服务器解析成Servlet,而Servlet是由Java类定义的,所以JSP和Servlet都可以继承指定的父类。该属性并不常用,而且有可能影响服务器的性能优化。 - import属性
该属性用于设置JSP导入的类包。JSP页面可以嵌入Java代码片段,这些Java代码在调用API时需要导入相应的类包。
<%@ page import="java.util.*"%>
- pageEncoding属性
该属性用于定义JSP页面的编码格式,也就是指定文件编码。JSP页面中的所有代码都使用该属性指定的字符集,如果该属性值设置为iso-8859-1,那么这个JSP页面就不支持中文字符。通常我们设置编码格式为GBK或UTF-8。
<%@ page pageEncoding="UTF-8"%>
- contentType属性
该属性用于设置JSP页面的MIME类型和字符编码,浏览器会据此显示网页内容。
<%@ page contentType="text/html; charset="UTF-8""%>
5.3.2 include指令
include指令用于文件包含。该指令可以在JSP页面中包含另一个文件的内容,但是它仅支持静态包含,也就是说被包含文件中的所有内容都被原样包含到该JSP页面中;如果被包含文件中有代码,将不被执行。被包含的文件可以是一段Java代码、HTML代码或者是另一个JSP页面。
【例5-2】在当前页面中包含一个JSP文件来显示当前日期。
(1)date.jsp文件:
<%@page pageEncoding="UTF-8" %>
<%@page import="java.util.Date"%>
<%
Date now = new Date();
String dateStr;
dateStr = String.format("%tY年%tm月%td日", now, now, now);
%>
<%=dateStr%>
(2)index.jsp文件,它是本实例的首页文件,其中使用了include指令包含date.jsp文件到当前页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include指令演示</title>
</head>
<body>
<!-- HTML注释信息 -->
当前日期是:
<%@include file="date.jsp" %>
<br>
</body>
</html>
5.3.3 taglib指令
该指令用于加载用户自定义标签,自定义标签将在后面章节进行讲解。使用该指令加载后的标签可以直接在JSP页面中使用。其语法格式如下:
<%@taglib prefix="fix" uri="tagUriorDir" %>
prefix属性:用于设置加载自定义标签的前缀。
uri属性:用于指定自定义标签的描述符文件位置。
例如:
<%@taglib prefix="view" uri="/WEB-INF/tags/view.tld" %>
5.4 嵌入Java代码
5.4.1 代码片段
代码片段就是在JSP页面中嵌入的Java代码,也可称为脚本段或脚本代码。
Java代码片段被包含在“<%”和“%>”标记之间。可以编写单行或多行的Java代码,语句以“;”结尾,其编写格式与Java类代码格式相同。
【例5-3】在代码片段中编写循环输出九九乘法表。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP的代码片段</title>
</head>
<body>
<%
long startTime = System.nanoTime(); // 记录开始时间,单位纳秒
%>
输出九九乘法表
<br>
<%
for (int i = 1; i <= 9; i++) { // 第一层循环
for (int j = 1; j <= i; j++) { // 第二次循环
String str = j + "*" + i + "=" + j * i;
out.print(str + "    "); // 使用空格格式化输出
}
out.println("<br>"); // HTML换行
}
long time = System.nanoTime() - startTime;
%>
生成九九乘法表用时
<%
out.println(time / 1000); // 输出用时多少毫秒
%>
毫秒。
</body>
</html>
5.4.2 声明
(1)定义全局变量
<%! long startTime = System.nanoTime();%>
(2)定义全局方法
<%!
int getMax(int a, int b) {
int max = a > b ? a : b;
return max;
}
%>
5.4.3 JSP表达式
JSP表达式可以直接把Java的表达式结果输出到JSP页面中。表达式的最终运算结果将被转换为字符串类型,因为在网页中显示的文字都是字符串。JSP表达式的语法格式如下:
<%= 表达式%>
其中,表达式可以是任何Java语言的完整表达式。
例如,圆周率:
<%=Math.PI%>
5.5 注释
5.5.1 HTML注释
HTML注释的语法格式:
<!-- 注释文本 -->
示例:
<!-- 显示数据报表的表格 -->
<table>
……
</table>
5.5.2 JSP注释
JSP注释的语法格式:
<%-- 注释文本 --%>
示例:
<%-- 显示数据报表的表格 --%>
<table>
……
</table>
5.5.3 代码注释
JSP页面支持嵌入Java代码,这些Java代码的语法和注释方法都和Java类的代码相同,因此也就可以使用Java的代码注释格式。
例如:
<%
//单行注释
/*
多行注释
*/
/**JavaDoc注释,用于成员注释*/
%>
5.6-5.9 JSP常用对象※
5.6 request对象
5.6.1 获取请求参数值
在一个请求中,可以通过使用“?”的方式来传递参数,然后通过request对象的getParameter()方法来获取参数的值。
例如:String id = request.getParameter("id");
上面的代码使用getParameter()方法从request对象中获取参数id的值,如果request对象中不存在此参数,那么该方法将返回null。
【例5-4】使用request对象获取请求参数值。
(1)index.jsp页面:
<%@ page language="java" contentType="text/html" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>获取请求参数的值</title>
</head>
<body>
<a href="show.jsp?id=001">获取请求参数的值</a>
</body>
</html>
(2)show.jsp页面:
<%@ page language="java" contentType="text/html" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>'show.jsp'</title>
</head>
<body>
id参数的值为:<%=request.getParameter("id") %><br>
name参数的值为:<%=request.getParameter("name") %>
</body>
</html>
5.6.2 获取Form表单的信息
除了获取请求参数中传递的值之外,我们还可以使用request对象获取从表单中提交过来的信息。
对于文本元素、单选按钮、单选下拉列表框而言,都可以使用getParameter()
方法来获取其具体的值。
但对于复选框以及多选列表框被选定的内容而言,就要使用getParameterValues()
方法来获取,该方法会返回一个字符串数组,通过循环遍历这个数组就可以得到用户选定的所有内容。
语法:String[] request. getParameterValues(String parameter)
【例5-5】获取Form表单信息。
(1)index.jsp文件:
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>'index.jsp'</title>
</head>
<body>
<form action="show.jsp" method="post">
<ul style="list-style: none; line-height: 30px">
<li>输入用户姓名: <input type="text" name="name" /> <br />
</li>
<li>选择性别: <input name="sex" type="radio" value="男" /> 男 <input
name="sex" type="radio" value="女" /> 女
</li>
<li>选择密码提示问题: <select name="question">
<option value="母亲生日">母亲生日</option>
<option value="宠物名称">宠物名称</option>
<option value="电脑配置">电脑配置</option>
</select>
</li>
<li>请输入问题答案: <input type="text" name="key" />
</li>
<li>请选择个人爱好:
<div style="width: 400px">
<input name="like" type="checkbox" value="唱歌跳舞" /> 唱歌跳舞 <input
name="like" type="checkbox" value="上网冲浪" /> 上网冲浪 <input
name="like" type="checkbox" value="户外登山" /> 户外登山 <br /> <input
name="like" type="checkbox" value="体育运动" /> 体育运动 <input
name="like" type="checkbox" value="读书看报" /> 读书看报 <input
name="like" type="checkbox" value="欣赏电影" /> 欣赏电影
</div>
</li>
<li><input type="submit" value="提交" /></li>
</ul>
</form>
</body>
</html>
(2)show.jsp文件:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>'show.jsp'</title>
</head>
<body>
<ul style="list-style: none; line-height: 30px">
<li>输入用户姓名:<%=new String(request.getParameter("name").getBytes("ISO8859_1"), "UTF-8")%></li>
<li>选择性别:<%=new String(request.getParameter("sex").getBytes("ISO8859_1"), "UTF-8")%></li>
<li>选择密码提示问题:<%=new String(request.getParameter("question").getBytes("ISO8859_1"), "UTF-8")%></li>
<li>请输入问题答案:<%=new String(request.getParameter("key").getBytes("ISO8859_1"), "UTF-8")%>
</li>
<li>请选择个人爱好: <%
String[] like = request.getParameterValues("like");
for (int i = 0; i < like.length; i++) {
%> <%=new String(like[i].getBytes("ISO8859_1"), "UTF-8") + " "%>
<%
}
%>
</li>
</ul>
</body>
</html>
说明:如果想获得所有的参数名称,可以使用
getParameterNames()
方法,则该方法返回一个Enumeration类性值。
5.6.3 获取请求客户端信息
【例5-6】获取请求信息。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'index.jsp'</title>
</head>
<body>
<div style="width: 600px">
<ul style="line-height: 24px">
<li>客户使用的协议:<%=request.getProtocol()%>
<li>客户端发送请求的方法:<%=request.getMethod()%>
<li>客户端请求路径:<%=request.getContextPath()%>
<li>客户机IP地址:<%=request.getRemoteAddr()%>
<li>客户机名称:<%=request.getRemoteHost()%>
<li>客户机请求端口号:<%=request.getRemotePort()%>
<li>接收客户信息的页面:<%=request.getServletPath()%>
<li>获取报头中User-Agent值:<%=request.getHeader("user-agent")%>
<li>获取报头中accept值:<%=request.getHeader("accept")%>
<li>获取报头中Host值:<%=request.getHeader("host")%>
<li>获取报头中accept-encoding值:<%=request.getHeader("accept-encoding")%>
<li>获取URI:<%=request.getRequestURI()%>
<li>获取URL:<%=request.getRequestURL()%>
</ul>
</div>
</body>
</html>
说明:默认情况下,当使用localhost进行访问时,应用
request.getRemoteAddr()
获取客户端IP地址将是0:0:0:0:0:0:0:1,这是以IPv6的形式显示的IP地址,要显示为127.0.0.1,需要在C:\Windows\System32\drivers\etc\hosts文件中添加“127.0.0.1 localhost”,并保存此文件。
5.6.4 在作用域中管理属性
通过使用setAttribute()
方法可以在request对象的属性列表中添加一个属性,然后在request对象的作用域范围内通过getAttribute()
方法将其属性取出;此外,还可以使用removeAttribute()
方法将一个属性删除掉。
语法:Object request.setAttribute(String name ,Object value)
【例5-7】管理request对象属性。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'index.jsp'</title>
</head>
<body>
<%
request.setAttribute("date", new Date()); //添加一个属性
%>
<ul style="line-height: 24px;">
<li>获取date属性:<%=request.getAttribute("date")%></li>
<!-- 将属性删除 -->
<%
request.removeAttribute("date");
%>
<li>删除后再获取date属性:<%=request.getAttribute("date")%></li>
</ul>
</body>
</html>
5.6.5 cookie管理
cookie是小段的文本信息,通过使用cookie可以标识用户身份、记录用户名及密码、跟踪重复用户。cookie在服务器端生成并发送给浏览器,浏览器将cookie的key/value保存到某个指定的目录中,服务器的名称与值可以由服务器端定义。
通过cookie的getCookies()
方法可以获取到所有的cookie对象集合,然后通过cookie对象的getName()
方法获取到指定名称的cookie,再通过getValue()
方法即可获取到cookie对象的值。另外,将一个cookie对象发送到客户端使用了response对象的addCookie()
方法。
5.7 response对象
response代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response只在JSP页面内有效。
response常用对象如下:
5.7.1 重定向网页
重定向是通过使用sendRedirect()
方法,将响应发送到另一个指定的位置进行处理。
示例:response.sendRedirect("www.mingribook.com");
在JSP页面中使用该方法的时候前面不要有HTML代码,并且在重定向操作之后紧跟一个return,因为重定向之后下面的代码已经没有意义了,并且还可能产生错误。
5.7.2 处理HTTP文件头
setHeader()
方法通过两个参数——头名称与参数值的方式来设置HTTP文件头。
设置网页每5秒自动刷新一次。
response.setHeader("refresh","5");
设置2秒钟后自动跳转至指定的页面。
response.setHeader("refresh","2;URL=welcome.jsp");
5.8 session对象
session对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。
session对象常用方法:
方法 | 返回值 | 说明 |
---|---|---|
getAttribute(String name) | Object | 获得指定名字的属性 |
getAttributeNames() | Enumeration | 获得session中所有属性对象 |
getCreationTime() | long | 获得session对象创建时间 |
getId() | String | 获得session对象唯一编号 |
5.8.1 创建及获取session信息
session是与请求有关的会话对象,是java.servlet.http.HttpSession对象,用于保存和存储页面的请求信息。
session对象的setAttribute()方法可实现将信息保存在session范围内,而通过getAttribute()方法可以获取保存在session范围内的信息。
setAttribute()
方法的语法格式:
setAttribute(String key, Object obj)
①key:保存在session范围内的关键字。
②obj:保存在session范围内的对象。getAttribute()
方法的语法格式:
getAttribute(String key)
key:指定保存在session范围内的关键字。
5.8.2 从会话中移除指定的绑定对象
removeAttribute(String key)
key:保存在session范围内的关键字。
例:session.removeAttribute("message");
将保存在session会话中的对象移除。
5.8.3 销毁session
销毁session后就不能再使用session对象了。
语法格式:session.invalidate();
5.9 application对象
application对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象的生命周期更长,类似于系统的“全局变量”。
常用方法:
5.9.1 访问应用程序初始化参数
application对象访问应用程序初始化参数的方法分别介绍如下:
getInitParameter(String name)
:返回一个已命名的参数值。
getAttributeNames()
:返回所有已定义的应用程序初始化名称的枚举。
5.9.2 管理应用程序环境属性
与session对象相同,也可以在application对象中设置属性。与session对象不同的是,session只是在当前客户的会话范围内有效,当超过保存时间,session对象就被收回;而application对象在整个应用区域中都有效。application对象管理应用程序环境属性的方法分别介绍如下。
getAttributeNames()
:获得所有application对象使用的属性名。getAttribute(String name)
:从application对象中获取指定对象名。setAttribute(String key,Object obj)
:使用指定名称和指定对象在application对象中进行关联。removeAttribute(String name)
:从application对象中去掉指定名称的属性。