JSP 概述
JSP 主要负责呈现与用户交互的界面
从开发的角度看,JSP 就是一个嵌入了 Java 程序的 HTML 页面
JSP 脚本
JSP 脚本可以将 Java 代码嵌入 JSP 文件中
这些嵌入的 Java 代码最终都会导入 Servlet 中的 serve() 方法中
因此在 JSP 中可以实现在大段落上共享临时变量,也存在预设的变量 request 和 response
JSP 本质上是界面和功能实现的结合,如果只是为了写功能实现,还是建议使用 Servlet
格式
1、JSP 脚本
执行 Java 代码
<% Java 代码 %>
2、方法声明
定义 Java 方法
<%!
Java 方法声明
%>
3、变量表达式
将 Java 表达式输出到 HTML 页面
<%=Java变量>
4、注释
<%-- xxxxx --%>
一个简单实例如下:
<%-- JSP 实例 --%>
<%!
public String test() {
return "XYZ";
}
%>
<%String name = test();%>
<%=name%>
嵌入的 Java 代码的实例:
可迭代数据的循环取出
<%-- JSP 实例 --%>
<%
List<String> idNums = new ArrayList<>();
idNums.add("001");
idNums.add("002");
idNums.add("003");
idNums.add("004")
List<String> names = new ArrayList<>();
names.add("数据结构与算法");
names.add("计算机组成原理");
names.add("操作系统原理");
names.add("计算机网络原理");
%>
<table>
<tr>
<th>序号</th>
<th>名称</th>
</tr>
<%
for (int i = 0; i < idNums.size(); i++) {
%>
<tr>
<td><%=idNums.get(i)%></td>
<td><%=names.get(i)%></td>
</tr>
<%
}
%>
</table>
JSP 内置对象
九个 JSP 内置对象
- request:HttpServletRequest,表示一次请求
- response:HttpServletResponse,表示一次响应
- pageContext:PageContext,页面上下文,获取页面信息
- session:HttpSession,表示一次会话,保存用户信息
- application:ServletContext,表示当前 Web 应用,全局对象,保存所有用户共享信息
- config:ServletConfig,当前 JSP 对应的 Servlet 的 ServletConfig 对象,获取当前 Servlet 信息
- out:JspWriter,向浏览器输出数据
- page:Servlet,当前 JSP 对应的 Servlet 对象
- exception:Exception,JSP 页面发生的异常
request 对象
request 常用方法:
1、获取客户端传来的参数:
String getParameter(String key)
该方法多用于 JSP 从客户端获取参数
当客户端传递了多个同名参数(key 相同)时,可以将这些参数存入一个数组:
String[] getParameterValues()
2、保存和取出数据
通过 (key, value) 键值对来保存和取出数据
void setAttribute(String key, Object value) // 通过键值对保存数据
Object getAttribute(String key) // 通过 key 取出 value
该方法多用于多个 JSP之间传递参数
3、请求转发
返回一个 RequestDispatcher 对象
RequestDispatcher getRequestDispatcher(String path)
常常使用该对象的 forward() 方法用于请求转发
这里只进行介绍,后续将会比较转发和重定向的区别
4、设置请求的编码
void setCharacterEncoding(String charset)
例如:出现中文乱码的问题,则可指定:
request.setCharacterEncoding("UTF-8");
response 对象
响应状态码:
200:正常
404:资源找不到
400:请求类型不匹配
500:Java 程序抛出异常
response 常用方法:
1、重定向,用于页面的跳转
sendRedirect(String path)
转发和重定向的区别
转发:同一个请求在服务器之间传递,地址栏的 url 不变。也叫服务器跳转
重定向:由客户端发送一次新的请求来访问跳转后的目标资源,之前一次请求生命周期的将会结束。也叫客户端跳转
request.getRequestDispatcher("target.jsp").forward(request, response);
response.sendRedirect("target.jsp");
第一行:转发,将同一个请求传给下一个页面
第二行:重定向,创建一个新的请求传给下一个页面
如果两个页面之间需要通过 request 来传值,则必须使用转发,不能使用重定向
转发与重定向的应用实例:登录界面的跳转
用户登录:
若用户名和密码正确,则跳转到首页,并且展示用户名(转发)
否则重新回到登录页面(重定向)
文件1:login.jsp
<form action="check.jsp" method="post">
<label>
用户名:
<input type="text" name="username"/>
</label><br/>
<label>
密码:
<input type="password" name="password"/>
</label><br/>
<input type="submit" value="登录"/>
</form>
文件2:check.jsp
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
if(username.equals("admin") && password.equals("123456")) {
// 登录成功
request.setAttribute("name", username);
request.getRequestDispatcher("welcome.jsp").forward(request, response);
} else {
// 登录失败
response.sendRedirect("login.jsp");
}
%>
文件3:welcome.jsp
<%
String name = (String) request.getAttribute("name");
%>
欢迎!<%=name%>
会话
服务器无法识别每一次 HTTP 请求的出处,而通过会话技术可以得知 HTTP 请求的出处
会话:客户端和服务器之间发生的一系列的连续的请求和响应过程
会话状态:指服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的一系列请求和响应关联起来
实现会话两种方式
- session
- cookie
session 对象
session 对象常用方法:
属于同一次会话的请求都有一个相同的标识符 sessionID
String getId()
:获取 sessionID
void set MaxInactiveInterval(int interval)
:设置 session 的失效时间,单位为 秒
int getMaxInactiveInterval()
:获取当前 session 的失效时间
void invalidate()
:使当前 session 失效
void setAttribute(String key, Object value)
:通过键值对存储数据
Object getAttribute(String key)
:通过键获取数据
void removeAttribute(String keye)
:通过键删除数据
Cookie
Session 是在服务端产生的,而 Cookie 是在客户端(由浏览器)产生的
在 HTTP 响应中附带传给浏览器的一个小型文本文件,一旦浏览器保存了某个 Cookie,在之后的请求和响应过程中,会以此 Cookie 为载体完成客户端和服务端之间的数据交互(来回传递)
- 创建 Cookie
为 response 添加一个 Cookie
Cookie cookie = new Cookie("username", "admin");
response.addCookie(cookie);
- 读取 Cookie
从 request 中读取 Cookie 的值
Cookie[] cookies = request.getCookies();
for(Cookie cookie: cookies) {
out.write(cookie.getName() + ":" + cookie.getValue() + "<br/>");
}
- Cookie 常用方法
void setMaxAge(int age)
:设置 Cookie 的有效时间,单位为 秒
int getMaxAge()
:获取 Cookie 的有效时间,单位为 秒
String getName()
:获取 Cookie 的 name
String getValue()
:获取 Cookie 的 value
Session 和 Cookie 的区别和总结
session | cookie | |
---|---|---|
保存位置 | 保存在服务器 | 保存在本地客户端(用户浏览器) |
数据类型 | Object | String |
服务端生命周期 | 随着会话的结束而销毁(服务器/Web应用的关闭或重启) | 可以长期保存,与会话无关 |
客户端生命周期 | 随浏览器的关闭而销毁 | 默认随浏览器关闭而销毁,可以更改改有效期 |
一般用途 | 保存重要信息 | 保存不重要信息 |
基于 Cookie 的模拟登录案例,部分代码:
String username = req.getParameter(s:"username");
String password = req.getParameter(s:"password");
if(username.equals(defaultUsername) && password.equals(defaultPassword)) {
Cookie cookie = new Cookie(name:"name", username);
cookie.setMaxAge(60*60*24*7); // 浏览器保存账户信息 7 天
resp.addCookie(cookie);
resp.sendRedirect(s:"cookie_welcome.jsp");
} else {
resp.sendRedirect(s:"cookie_login.jsp");
}
JSP 内置对象的作用域
研究对象:page、request、session 和 application
特征:这四个对象都有 setAttribute 和 getAttribute 方法
目的:不同对象的作用域(数据能够传输的范围)
page 作用域:对应内置对象是 pageContext,只在当前页面有效(实际开发中极少使用)
request 作用域:对应内置对象是 request,只在一次请求内有效
session 作用域:对应内置对象是 session,只在一次会话内有效
application 作用域:对应内置对象是 application,在 Web 应用内有效
作用域大小:page < request < session < application
示例:统计网站的访问量
统计网站的访问量,考虑的是会有不同用户从不同的浏览器访问服务端,产生多次会话,因此统计变量 count 必须存储在 application 作用域中
页面代码:count.jsp
<body>
<%
Integer count = (Integer) application.getAttribute(s:"count");
if(count == null) {
count = 1;
} else {
count++;
}
application.setAttribute("count", count);
%>
您是当前的第<%=count%>位访客
</body>
弊端:当服务器关闭时,数据会丢失
因此当实际开发中,服务器进行维护时,需要将数据存入数据库中备份
EL 表达式
Expression Language 表达式语言,可以简化 JSP 页面中数据访问时的代码,仅限 JSP 中使用
表达式结构:${变量名}
作用:取出域对象(pageContext / request / session / application)中保存的数据,前提是域对象中存在该变量
变量名可以存入数据时 setAttribute() 方法中的 key 值,也可以是定义变量时的变量名
若该变量为实例化对象,则可以直接用 " . " 访问类成员(可以直接访问私有成员变量,前提是在实体类中编写了 getter)
示例
假设已经有:request.setAttribute(“name”, “admin”)
<%-- 使用 EL 表达式 --%>
${name}
<%-- 不使用 EL 表达式 --%>
<%
String name = (String) request.getAttribute("name");
%>
<%=name%>
两段代码的作用相同
查找优先级
EL 表达式按规定的遍历顺序查找:pageContext > request > session > application
因此当多个作用域对象都存储了同名对象,则只会取出查找优先级较高的数据
可以指定单个作用域查找:
${pageScope.name}
:只在 page 作用域中查找
${requestScope.name}
:只在 request 作用域中查找
${sessionScope.name}
:只在 session 作用域中查找
${applicationScope.name}
:只在 application 作用域中查找
数据级联
访问类成员的方法:假设类对象 a 中含有成员 b
${a.b}
${a["b"]}
其他功能(不常用)
-
赋值操作:${id=3}
-
布尔判断:${num1 ? num2 : num1 < num2}
&& || ! < > <= >= ==
&& and
|| or
! not
== eq
< lt
> gt
<= le
>= ge
!= ne
empty // 变量为 null, length=0 的字符串, size=0 的集合
JSTL 标准标签库
JSP Standard Tag Library:JSP 标准标签库,是 JSP 为开发者提供的一系列标签
使用这些标签可以完成循环、遍历等逻辑处理,简化代码,防止出现 JSP 脚本穿插的情况
相比于 EL 表达式擅长的数据展示,JSTL 更侧重于逻辑处理
JSTL 使用
1、导入下面两个 jar 包到路径 web\WEB-INF\lib
文件夹下
- jstl.jar
- standard.jar
2、在 JSP 页面头部(HTML 标签上方)导入 JSTL 标签库
<%-- 导入 JSTL 核心标签库并用字符 c 表示 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
注意:第二个参数是 uri 而不是 url
prefix="c"
表明从 uri 所指向的地址中导入了核心标签库 core
JSTL 各种标签库
核心标签库 Core
导入:
<%-- 导入 JSTL 格式化标签库并用字符串 fmt 表示 --%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
核心标签库 Core 不仅包含常用标签如 set、out、remove 和 catch 处理数据的增删改和展示,还能够处理条件分支以及循环
set 标签
用于向域对象中添加数据,或是对对象的某一属性进行赋值
- 添加数据
格式:<c:set var="" value="" scope=""></c:set>
默认存储顺序:pageContext > request > session > application
- 给域对象的属性赋值
格式:<c:set target="" property="" value=""></c:set>
<%
Book book = new Book("《恶意》", "あくい", "作者姓名");
request.setAttribute("akui", book);
%>
<c:set target="${akui}" property="author" value="东野圭吾"></c:set>
out 标签
输出域对象中的数据
格式:<c:out value="" default=""></c:out>
<c:out value="${key}" default="NoneType"></c:out>
default 属性:设置当 EL 表达式取出为空时展示的默认值
remove 标签
删除域对象中的数据
格式:<c:remove var="" scope=""></c:remove>
<c:remove var="key" scope="session"></c:remove>
catch 标签
异常捕获及展示
- 异常捕获
格式:<c:catch var="error_name"></c:catch>
然后可以使用 EL 表达式通过 var 的值打印异常报告
<c:catch var="error">
...
</c:catch>
${error}
if 标签
条件语句
格式:<c:if test="${...}"></c:if>
<c:if test="${a>b}">Succeed</c:if>
<c:if test="${a le b}">Failed</c:if>
choose 标签
分支条件语句
<c:choose>
<c:when test="${a>b}">Succeed</c:when>
<c:otherwise>Failed</c:otherwise>
</c:choose>
forEach 标签
循环语句
var 表示临时变量名
begin 表示开始的下标(默认值为 0),end 表示结束的下标(默认到结尾)
取值的下标范围 index ∈ [begin, end]
step 表示步长,默认值为 1
varStatus 表示当前集合对象,可以通过该属性获取当此循环元素的 index、count、begin、end、step 等信息
<c:forEach items="${Object}" var="str" begin=0 end=5>
${str}<br/>
</c:forEach>
格式化标签库
导入:
<%-- 导入 JSTL 格式化标签库并用字符串 fmt 表示 --%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
formatDate 标签
格式化时间
<%
request.setAttribute("date", new Date());
%>
<fmt:formateDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formateDate>
函数标签库
导入:
<%-- 导入 JSTL 函数标签库并用字符串 fn 表示 --%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
格式:
<%
request.setAttribute("info", "Java, C, Python");
%>
${fn.contains(info, "Python")}
${fn.startsWith(info, "Java")}
${fn.indexOf(info, "a")}
${fn.replace(info, "C", "C/C++")}
${fn.substring(info, 2, 4)}
${fn.split(info, ",")[1]}