---
title: 一文搞懂jSP
date: 2020-12-12 13:51:56
tags:
- JavaWeb
- jsp
- EL表达式
- JSTL标签库
categories:
- JavaWeb
---

## JSP简介

JSP（全称Java Server Pages）是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求，而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准，在传统的网页HTML文件中插入Java程序段(Scriptlet)和JSP标记(tag)，从而形成JSP文件。

<!--more-->

JSP 技术是以 Java 语言作为脚本语言的，JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。

**语法**

```jsp
声明标签: <%!变量或者方法声明%>
表达式标签: <%= 表达式%> 在页面上显示的效果
程序代码标签: <%java代码%> 页面上动态展示内容
<!-- html注释内容,查看源码时能看到 -->
<%-- jsp注释,查看页面源码时看不到 --%>
```

**原理**

<font color=red>JSP本质上也是servlet</font>

将jsp文件翻译成java文件并编译成class文件，其中包含的HTML代码以流的方式被响应回浏览器显示

>   **JSP中出现的状态码（服务器状态码）**		
>
>   状态码是指由服务器根据HTTP协议所提交的信息，返回的HTTP头信息代码。
>
>   | 状态码 | 消息                       | 描述                                                         |
>   | ------ | -------------------------- | ------------------------------------------------------------ |
>   | 100    | Continue                   | 只有一部分请求被服务器接收，但只要没被服务器拒绝，客户端就会延续这个请求 |
>   | 101    | Switching Protocols        | 服务器交换机协议                                             |
>   | 200    | OK                         | 请求被确认                                                   |
>   | 201    | Created                    | 请求时完整的，新的资源被创建                                 |
>   | 202    | Accepted                   | 请求被接受，但未处理完                                       |
>   | 300    | Multiple Choices           | 一个超链接表，用户可以选择一个超链接并访问，最大支持5个超链接 |
>   | 301    | Moved Permanently          | 被请求的页面已经移动到了新的URL下                            |
>   | 302    | Found                      | 被请求的页面暂时性地移动到了新的URL下                        |
>   | 303    | See Other                  | 被请求的页面可以在一个不同的URL下找到                        |
>   | 400    | Bad Request                | 服务器无法识别请求                                           |
>   | 403    | Forbidden                  | 禁止访问所请求的页面                                         |
>   | 404    | Not Found                  | 服务器无法找到所请求的页面                                   |
>   | 405    | Method Not Allowed         | 请求中所指定的方法不被允许                                   |
>   | 500    | Internal Server Error      | 请求不完整，服务器遇见了出乎意料的状况                       |
>   | 501    | Not Implemented            | 请求不完整，服务器不提供所需要的功能                         |
>   | 502    | Bad Gateway                | 请求不完整，服务器从上游服务器接受了一个无效的响应           |
>   | 503    | Service Unavailable        | 请求不完整，服务器暂时重启或关闭                             |
>   | 504    | Gateway Timeout            | 网关超时                                                     |
>   | 505    | HTTP Version Not Supported | 服务器不支持所指定的HTTP版本                                 |

## JSP的内置对象

JSP中一共预先定义了9个对象，分别为：request、response、session、application、out、
pagecontext、config、page、exception

1.  **request对象**

    该对象代表了客户端的请求信息，主要用于接受通过HTTP协议传送到服务器的数据。（包括头信息、系统信息、请求方式以及请求参数等）**request对象的作用域为一次请求。**所属类型:HttpServletRequest。

2.  **response对象**

    response 代表的是对客户端的响应，主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域，**它只在JSP页面内有效**。所属类型:HttpServletResponse

3.  **session对象**

    session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象，用于保存该用户的信息，跟踪用户的操作状态。session对象内部使用Map类来保存数据，因此保存数据的格式为`"Key/value"`。 所属类型:HttpSession

4.  **application对象**

    application 对象可将信息保存在服务器中，直到服务器关闭，application对象中保存的信息会在整个应用中都有效。与session对象相比，application对象生命周期更长，类似于系统的「全局变量」。所属类型:ServletContext

5.  **out 对象**

    out 对象用于在Web浏览器内输出信息，并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时，可以对数据缓冲区进行操作，及时清除缓冲区中的残余数据，为其他的输出让出缓冲空间。待数据输出完毕后，要及时关闭输出流。例如：

    ```jsp
    out.print("<script type='text/javascript'>alert('用户名不存在');location.href='index.jsp'</script>");
    ```

6.  **pageContext 对象**

    pageContext 对象的作用是取得任何范围的参数，通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的，在JSP页面中可以直接使用pageContext对象。

7.  **config 对象**

    config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时，容器把某些信息通过config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。

8.  **page 对象**

    page 对象代表JSP本身，只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量，类似于Java编程中的 this 指针。

9.  **exception 对象**

    exception 对象的作用是显示异常信息，只有在包含 isErrorPage="true" 的页面中才可以被使用，在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样，都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中，可以使用try/catch关键字来处理异常情况； 如果在JSP页面中出现没有捕获到的异常，就会生成 exception 对象，并把 exception 对象传送到在page指令中设定的错误页面中，然后在错误页面中处理相应的 exception 对象。

    ```jsp
    <%--先在可能发生错误的页面中添加errorPage属性:--%>
    <%@ page pageEncoding="utf-8" errorPage="error.jsp" contentType="text/html;charset=UTF-8" language="java" %>
    
    <%--在error.jsp页面中设置isErrorPage="true" 的属性--%>
    <%@ page language="java" isErrorPage="true" import="java.util.*" pageEncoding="UTF-8"%>
    ```

    >   **jsp对象的作用域:**
    >
    >   pageContext < request  < session < application
    >
    >   pageContext :当前页面
    >
    >   request:单次请求
    >   session:浏览器访问期间(会话期间)
    >   application:服务器启动期间,所存的数据可以跨浏览器

## JSP的指令

JSP指令用来设置整个JSP页面相关的属性，如网页的编码方式和脚本语言。

语法格式如下：

```jsp
<%@ directive attribute="value" %>
directive：指令名称 attribute 属性名 value:属性值
```

| 指令名称 | 描述                                                    |
| -------- | ------------------------------------------------------- |
| page     | 定义网页依赖属性，比如脚本语言、error页面、缓存需求等等 |
| include  | 包含其他文件                                            |
| taglib   | 引入标签库的定义                                        |

1.  **page指令**

    Page指令为容器提供当前页面的使用说明，一个JSP页面可以包含多个page指令

    ```jsp
    <%@ page attribute="value" %>
    ```

    page指令的属性

    | 常用属性     | 属性值                    | 属性描述                                                     |
    | ------------ | ------------------------- | ------------------------------------------------------------ |
    | language     | java                      | 解释该JSP文件时采用的语言，一般为java语言，默认为java        |
    | extends      | 任何类的全名              | 编译该JSP文件时继承哪个类，JSP为Servlet，因此当指明继承普通类时需要实现Servlet的init、destroy等方法 |
    | import       | 引入该JSP中用到的类、包等 | import是唯一可以声明多次的page指令属性，中间用英文逗号隔开<%@page import=包名.类名，包名.类名%> |
    | session      | true/false                | 该JSP内是否内置Session对象，如果为true，则内置Session对象，可直接使用，否则反之，默认为true |
    | autoFlush    | true/false                | 是否运行缓存，如果为true，则使用out.println()等方法输出的字符串并不是立刻到达客户端服务器的，而是暂时存到缓存里，缓存满了或者程序行完毕或者执行out.flush()操作时才到客户端，默认为true。 |
    | buffer       | none或者数字KB            | 指定缓存大小，当autoFlush设为true时有效，例如<%@ page buffer=10kb%> |
    | isThreadSafe | true/false                | 是否线程安全，如果为true，则运行多个线程同时运行该jsp程序，否则只运行一个线程，其余线程等待，默认为false |
    | isErrorPage  | true/false                | 指定该页面是否为错误显示页面，如果为true，则该JSP内置有一个Exception对象 exception，可直接使用，否则没有，默认为false |
    | errorPage    | 某个JSP页面的相对路径     | 指明一个错误页面，如果该JSP程序抛出一个未捕捉的异常，则转到 errorPage指定的页面，errorPage指定的页面通常isErrorPage属性为true，且内置的exception对象为未捕捉的异常 |
    | contentType  | 有效的文档类型            | 客户端浏览器根据该属性判断文档类型，例如 HTML格式为text/html、纯文本格式为text/plain、JPG图像为image/jpeg、GIF图像为image/gif、WORD文档为application/msword，该属性常跟着charset设置编码一起，作用是通知服务器和浏览器都使用同一个码表 |
    | pageEncoding | 字符集编码如：UTF-8       | 设置页面字符集编码                                           |

2.  **Include指令**

    JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分，会被同时编译执行。

    ```jsp
    <%@ include file="文件相对 url 地址" %>
    ```

3.  **Taglib指令**

    JSP API允许用户自定义标签，一个自定义标签库就是自定义标签的集合。

    Taglib指令引入一个自定义标签集合的定义，包括库路径、自定义标签。

    ```jsp
    <%@ taglib uri="uri" prefix="" %>
    ```

    uri属性确定标签库的位置，prefix属性指定标签库的前缀(可自定义)。

## EL表达式

EL（Expression Language）：简化对象和变量访问的一种语法

```jsp
语法格式：${需要取出数据的键值}
```

当表达式没有指定变量或者对象的范围时，那么容器会依次从pageContext—>request—>session—>application中查找该变量或对象，我们可以通过隐含对象获得指定作用域的值

```jsp
${pageScope.key} 	用于获取当前页面的属性值
${requestScope.key} 用于获取请求范围的属性值
${sessionScope.key} 用于获取会话范围的属性值
${applicationScope.key} 用于获取程序范围的属性值
```

<font color = red>EL表达式不可以直接取出变量，只能通过将变量放入作用域的方式</font>

**EL中基础操作符**

EL表达式支持大部分Java所提供的算术和逻辑操作符：

| **操作符** | **描述**                         |
| :--------- | :------------------------------- |
| .          | 访问一个Bean属性或者一个映射条目 |
| []         | 访问一个数组或者链表的元素       |
| ( )        | 组织一个子表达式以改变优先级     |
| +          | 加                               |
| -          | 减或负                           |
| *          | 乘                               |
| / or div   | 除                               |
| % or mod   | 取模                             |
| == or eq   | 测试是否相等                     |
| != or ne   | 测试是否不等                     |
| < or lt    | 测试是否小于                     |
| > or gt    | 测试是否大于                     |
| <= or le   | 测试是否小于等于                 |
| >= or ge   | 测试是否大于等于                 |
| && or and  | 测试逻辑与                       |
| \|\| or or | 测试逻辑或                       |
| ! or not   | 测试取反                         |
| empty      | 测试是否空值                     |

>   **关于EL表达式更多内容可以参考：[https://www.runoob.com/jsp/jsp-expression-language.html](https://www.runoob.com/jsp/jsp-expression-language.html)**

## JSTL

JSTL(JSP标准标签库)是一个JSP标签集合，它封装了JSP应用的通用核心功能。

JSTL支持通用的、结构化的任务，比如迭代，条件判断，XML文档操作，国际化标签，SQL标签。 除了这些，它还提供了一个框架来使用集成JSTL的自定义标签。

根据JSTL标签所提供的功能，可以将其分为5个类别。核心标签、格式化标签、sql标签、xml标签、jstl函数

>   要使用JSTL首先需要导入jar包
>
>   下载 jakarta-taglibs-standard-1.1.2.zip 包并解压，将 jakarta-taglibs-standard-1.1.2/lib/ 下的两个 jar 文
>   件：standard.jar 和 jstl.jar 文件拷贝到 /WEB-INF/lib/ 下，并配置。

**语法：**

1.  在JSP页面中引入`<%@ taglib prefix=”页面使用的名称” uri=”功能范围的路径”%>`

    | 功能范围  | 说明       | Uri                                   | 前缀prefix |
    | --------- | ---------- | ------------------------------------- | ---------- |
    | core      | 核心标签   | http://java.sun.com/jsp/jstl/core     | c          |
    | i18n      | 格式化标签 | http://java.sun.com/jsp/jstl/fmt      | fmt        |
    | sql       | sql标签    | http://java.sun.com/jsp/jstl/sql      | sql        |
    | xml       | xml标签    | http://java.sun.com/jsp/jstl/xml      | x          |
    | functions | jstl函数   | http://java.sun.com/jsp/jstl/function | fn         |

2.  通过标签库前缀和标记及属性进行操作`<前缀:标记 属性="值",属性="值">`

**核心标签**

核心标签有以下几种标记

*   表达式操作 out、set、remove、catch
*   流程控制 if、choose、when、otherwise
*   迭代操作 forEach、forTokens
*   URL操作 import、param、url、redirect

常用的标记及其属性：

-   ＜c:set> ：主要用来将变量存储至JSP范围中 或是JavaBean的属性或Map对象中

    | 名称     | 说明                 | 是否必须写 | 默认值 |
    | -------- | -------------------- | ---------- | ------ |
    | value    | 要被存储的值         | 否         | 无     |
    | var      | 存入的变量名称       | 否         | 无     |
    | scope    | var变量的JSP范围     | 否         | Page   |
    | target   | JavaBean或Map对象    | 否         | 无     |
    | property | 指定target对象的属性 | 否         | 无     |

-   ＜c:out>主要用来显示数据的内容

    | 名称      | 说明                                   | 是否必须写 | 默认值 |
    | --------- | -------------------------------------- | ---------- | ------ |
    | value     | 需要显示出来的值                       | 是         | 无     |
    | default   | 如果value的值为null，则显示default的值 | 否         | 无     |
    | escapeXml | 是否转换特殊字符，如：＜转换成 & lt;   | 否         | True   |

-   ＜c:remove> 主要负责移除变量

    | 名称  | 说明             | 是否必须写 | 默认值 |
    | ----- | ---------------- | ---------- | ------ |
    | var   | 欲移除的变量名称 | 是         | 无     |
    | Scope | var变量的jsp范围 | 否         | Page   |

-   ＜c:if> 主要用于进行if判断,如果为true,则输出标签体中的内容

    | 名称  | 说明                                          | 是否必须写 | 默认值 |
    | ----- | --------------------------------------------- | ---------- | ------ |
    | test  | 表达式的结果为true，则执行体内容，false则相反 | 是         | 无     |
    | var   | 如果 用来存储test运算的结果(true或false)      | 否         | 无     |
    | scope | Var变量的JSP范围                              | 否         | page   |

-   ＜c:choose >,＜c:when >,＜c:otherwise > 作用相当于if-else

    | 名称 | 说明                                          | 是否必须写 | 默认值 |
    | ---- | --------------------------------------------- | ---------- | ------ |
    | test | 表达式的结果为true，则执行体内容，false则相反 | 是         | 无     |

-   ＜c:forEach> 循环控制，它可以将数组,集合(Collection)中的成员循序浏览一遍。

    | 名称      | 说明                                 | 必须 | 默认值       |
    | --------- | ------------------------------------ | ---- | ------------ |
    | var       | 用来存放现在指定的成员               | 是   | 无           |
    | items     | 被迭代的集合对象（需要使用EL表达式） | 否   | 无           |
    | varStatus | 用来代指被迭代的集合对象             | 否   | 无           |
    | begin     | 开始的位置                           | 否   | 0            |
    | end       | 结束的位置                           | 否   | 最后一个成员 |
    | step      | 每次迭代的间隔数                     | 否   | 1            |

**格式化标签**

常用的标记及其属性：

*   < fmt:formatDate > 将日期类型格式化为指定模式的字符串

    | 名称    | 说明                                                         | 默认值 |
    | ------- | ------------------------------------------------------------ | ------ |
    | value   | 将要被格式化的数据                                           |        |
    | pattern | 格式化的模式，与SimpleDateFormat的参数设置一样,如yyyy-MM-dd  |        |
    | var     | 格式化后的字符串所要存放的变量，若不指定var，则会将格式化的结果直接显示在页面 |        |
    | scope   | 变量存放的域属性空间                                         | page   |
    | type    | 其取值为date、time、both，表示给出的value是日期、时间、还是两者都包含 | date   |

*   < fmt:parseDate > 用于将指定字符串转化为日期类型

    | 名称    | 说明             |
    | ------- | ---------------- |
    | value   | 服务器获取的时间 |
    | pattern | 转换的格式       |
    | var     | 页面显示的变量   |

*   < fmt:formatNumber > 按照指定格式对数字进行格式化

    | 名称             | 说明                                |
    | ---------------- | ----------------------------------- |
    | maxIntegerDigits | 整数部分最多的位数                  |
    | minIntegerDigits | 整数部分最少的位数                  |
    | maxFrctionDigits | 小数部分最多的位数                  |
    | minFrctionDigits | 小数部分最少的位数                  |
    | var              | 存储格式化结果的变量                |
    | scope            | var属性的作用域                     |
    | integerOnly      | 是否只解析整型数true或者浮点数false |

>   **关于JSTL更多内容可以参考：[https://www.runoob.com/jsp/jsp-jstl.html](https://www.runoob.com/jsp/jsp-jstl.html)**