## JSP 简介
JSP(全称Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。
JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。
JSP文件后缀名为 ***.jsp** 。
JSP开发的WEB应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。
## JSP 概念
jsp全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。
jsp外表看起来和HTML没有多少区别,只是多了一个头部的标识,和文件后缀名改为了.jsp的形式,但是本质上区别是很大的。jsp是运行在服务端的java,html本质上就是静态页面。
## JSP 语法
上面说过,jsp实际上就是java代码,也就是说可以直接在页面上写java代码。下面就是书写方式。
```html
<% 代码片段 %>
```
下面的案例是通过java代码在页面上输出的结果为你的IP地址
```html
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>
```
**注意:**请确保正确安装了tomcat,然后再检查文件名字是不是hello.jsp,把文件复制到tomcat安装目录的webapps/ROOT文件夹下面,浏览器访问:http://localhost:8080/hello.jsp 得到测试结果。
## JSP 指令
JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。指令可以有很多个属性,它们以键值对的形式存在,并用逗号隔开。
JSP中的三种指令标签:
| 指令 | 描述 |
| ------------ | ------------ |
| <%@ page ... %> | 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 |
| <%@ include ... %> | 包含其他文件 |
| <%@ taglib ... %> | 引入标签库的定义 |
**Page指令**
Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。
Page指令的语法格式:
```html
<%@ page 属性="属性值" %>
```
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 | 确定脚本元素能否被使用 |
**Include指令**
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
Include指令的语法格式如下:
```html
<%@ include file="相对路径" %>
```
Include指令中的文件名实际上是一个相对的URL。如果您没有给文件关联一个路径,JSP编译器默认在当前路径下寻找。
**Taglib指令**
JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。
Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
Taglib指令的语法:
```html
<%@ taglib uri="标签库的位置" prefix="标签库的前缀" %>
```
## JSP 隐式对象
JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。
**JSP九大隐式对象:**
| 对象 | 描述 |
| ------------ | ------------ |
| request | HttpServletRequest类的实例 |
| response | HttpServletResponse类的实例 | |
| out | PrintWriter类的实例,用于把结果输出至网页上 |
| session | HttpSession类的实例 |
| application | ServletContext类的实例,与应用上下文有关 |
| config | ServletConfig类的实例 |
| pageContext | PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问 |
| page | 类似于Java类中的this关键字 |
| Exception | Exception类的对象,代表发生错误的JSP页面中对应的异常对象 |
**request对象**
request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。
**response对象**
response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。
response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。
**out对象**
out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。
最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用buffered='false'属性来轻松关闭缓存。
JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter新增了一些专为处理缓存而设计的方法。还有就是,JspWriter类会抛出IOExceptions异常,而PrintWriter不会。
下表列出了我们将会用来输出boolean,char,int,double,Srtring,object等类型数据的重要方法:
| 方法 | 描述 |
| ------------ | ------------ |
| out.print(dataType dt) | 输出Type类型的值 |
| out.println(dataType dt) | 输出Type类型的值然后换行 |
| out.flush() | 刷新输出流 |
**session对象**
session对象是 javax.servlet.http.HttpSession 类的实例。和Java Servlets中的session对象有一样的行为。
session对象用来跟踪在各个客户端请求间的会话。
**application对象**
application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。
这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。
通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。
**config对象**
config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。
这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。
以下是config对象的使用方法,不是很重要,所以不常用:
```html
config.getServletName();
```
它返回包含在<servlet-name>元素中的servlet名字,注意,<servlet-name>元素在 WEB-INF\web.xml 文件中定义。
**pageContext 对象**
pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。
这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。
这个对象存储了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 类。
其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute("attrName")移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性:
```html
pageContext.removeAttribute("attrName", PAGE_SCOPE);
```
**page 对象**
这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。
page 对象就是this对象的同义词。
**exception 对象**
exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。
## JSTL 标准标签库
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
根据JSTL标签所提供的功能,可以将其分为5个类别。
- 核心标签
- 格式化标签
- SQL 标签
- XML 标签
- JSTL 函数
- JSTL 库安装
## JSTL 使用前提
首先导入jstl-1.2.jar,然后在使用标签的页面头部引用对应的标签库,通常使用<c:forEach>,<c:if>,<c:choose>,<c:when>,都需要在页面头部写一下内容:
```html
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
```
## JSTL 核心标签
核心标签是最常用的JSTL标签。引用核心标签库的语法如下:
```html
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
```
| 标签 | 描述 |
| ------------ | ------------ |
| <c:out> | 用于在JSP中显示数据,就像<%= ... > |
| <c:set> | 用于保存数据 |
| <c:remove> | 用于删除数据 |
| <c:catch> | 用来处理产生错误的异常状况,并且将错误信息储存起来 |
| <c:if> | 与我们在一般程序中用的if一样 |
| <c:choose> | 本身只当做<c:when>和<c:otherwise>的父标签 |
| <c:when> | <c:choose>的子标签,用来判断条件是否成立 |
| <c:otherwise> | <c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行 |
| <c:import> | 检索一个绝对或相对 URL,然后将其内容暴露给页面 |
| <c:forEach> | 基础迭代标签,接受多种集合类型 |
| <c:forTokens> | 根据指定的分隔符来分隔内容并迭代输出 |
| <c:param> | 用来给包含或重定向的页面传递参数 |
| <c:redirect> | 重定向至一个新的URL. |
| <c:url> | 使用可选的查询参数来创造一个URL |
## JSTL 格式化标签
JSTL格式化标签用来格式化并输出文本、日期、时间、数字。引用格式化标签库的语法如下:
```html
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
```
| 标签 | 描述 |
| ------------ | ------------ |
| <fmt:formatNumber> | 使用指定的格式或精度格式化数字 |
| <fmt:parseNumber> | 解析一个代表着数字,货币或百分比的字符串 |
| <fmt:formatDate> | 使用指定的风格或模式格式化日期和时间 |
| <fmt:parseDate> | 解析一个代表着日期或时间的字符串 |
| <fmt:bundle> | 绑定资源 |
| <fmt:setLocale> | 指定地区 |
| <fmt:setBundle> | 绑定资源 |
| <fmt:timeZone> | 指定时区 |
| <fmt:setTimeZone> | 指定时区 |
| <fmt:message> | 显示资源配置文件信息 |
| <fmt:requestEncoding> | 设置request的字符编码 |
## JSTL SQL标签
JSTL SQL标签库提供了与关系型数据库(Oracle,MySQL,SQL Server等等)进行交互的标签。引用SQL标签库的语法如下:
```html
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
```
| 标签 | 描述 |
| ------------ | ------------ |
| <sql:setDataSource> | 指定数据源 |
| <sql:query> | 运行SQL查询语句 |
| <sql:update> | 运行SQL更新语句 |
| <sql:param> | 将SQL语句中的参数设为指定值 |
| <sql:dateParam> | 将SQL语句中的日期参数设为指定的java.util.Date 对象值 |
| <sql:transaction> | 在共享数据库连接中提供嵌套的数据库行为元素,将所有语句以一个事务的形式来运行 |
## JSTL XML 标签
JSTL XML标签库提供了创建和操作XML文档的标签。引用XML标签库的语法如下:
```html
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
```
在使用xml标签前,你必须将XML 和 XPath 的相关包拷贝至你的<Tomcat 安装目录>\lib下:
XercesImpl.jar下载地址: http://www.apache.org/dist/xerces/j/
xalan.jar下载地址: http://xml.apache.org/xalan-j/index.html
| 标签 | 描述 |
| ------------ | ------------ |
| <x:out> | 与<%= ... >,类似,不过只用于XPath表达式 |
| <x:parse> | 解析 XML 数据 |
| <x:set> | 设置XPath表达式 |
| <x:if> | 判断XPath表达式,若为真,则执行本体中的内容,否则跳过本体 |
| <x:forEach> | 迭代XML文档中的节点 |
| <x:choose> | <x:when>和<x:otherwise>的父标签 |
| <x:when> | <x:choose>的子标签,用来进行条件判断 |
| <x:otherwise> | <x:choose>的子标签,当<x:when>判断为false时被执行 |
| <x:transform> | 将XSL转换应用在XML文档中 |
| <x:param> | 与<x:transform>共同使用,用于设置XSL样式表 |
## JSTL 函数
JSTL包含一系列标准函数,大部分是通用的字符串处理函数。引用JSTL函数库的语法如下:
```html
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
```
| 标签 | 描述 |
| ------------ | ------------ |
| fn:contains() | 测试输入的字符串是否包含指定的子串 |
| fn:containsIgnoreCase() | 测试输入的字符串是否包含指定的子串,大小写不敏感 |
| fn:endsWith() | 测试输入的字符串是否以指定的后缀结尾 |
| fn:escapeXml() | 跳过可以作为XML标记的字符 |
| fn:indexOf() | 返回指定字符串在输入字符串中出现的位置 |
| fn:join() | 将数组中的元素合成一个字符串然后输出 |
| fn:length() | 返回字符串长度 |
| fn:replace() | 将输入字符串中指定的位置替换为指定的字符串然后返回 |
| fn:split() | 将字符串用指定的分隔符分隔然后组成一个子字符串数组并返回 |
| fn:startsWith() | 测试输入字符串是否以指定的前缀开始 |
| fn:substring() | 返回字符串的子集 |
| fn:substringAfter() | 返回字符串在指定子串之后的子集 |
| fn:substringBefore() | 返回字符串在指定子串之前的子集 |
| fn:toLowerCase() | 将字符串中的字符转为小写 |
| fn:toUpperCase() | 将字符串中的字符转为大写 |
| fn:trim() | 移除首位的空白符 |
## JSTL 案例 -- 遍历list集合
```java
package com.sponge.servlet;
import java.io.IOException;
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 com.sponge.dao.UserDao;
import com.sponge.entity.User;
@WebServlet("/showServlet")
public class ShowServlet extends HttpServlet { // 显示全部数据
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AdminDao dao = new AdminDao();
List<User> userList = dao.getAll();
// servlet中存放list集合
req.setAttribute("userList", userList);
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
}
```
```java
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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>
<style type="text/css">
table {
border: 1px solid pink;
margin: 0 auto;
}
td{
width: 150px;
border: 1px solid pink;
text-align: center;
}
</style>
</head>
<body>
<table>
<tr>
<td>编号</td>
<td>帐号</td>
<td>密码</td>
<td>操作</td>
</tr>
<c:forEach items="${userList}" var="user">
<tr>
<td>${user.id }</td>
<td>${user.username }</td>
<td>${user.userpwd }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
```