一、JSP原理剖析
1.1 什么是JSP?
- Java Servlet Pages:Java服务器端页面,和Servlet一样,用于动态web技术
- 它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
1.2 JSP的特点
- 软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。
- JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。
- JSP开发的WEB应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。
- 写JSP就像再写html,但是html只会提供静态数据
1.3 JSP原理
- 服务器内部工作
tomcat有一个work目录
IDEA中使用Tomcat的会在IDEA的tomcat中生成一个work目录
电脑中的目录地址
C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2\tomcat\d0a5c8e1-d2f7-4e43-b341-e0ad42b78504\work\Catalina\localhost\stu20211011\org\apache\jsp
可以看到页面转变成立Java程序
浏览器向服务器发送请,不管访问什么资源,实际上都在再访问Servlet
JSP最终也会被转换成Java类——JSP本质上就是一个Servlet
<!-- 使用maven添加HttpJspBase所在的依赖-->
<dependency>
<groupId>tomcat</groupId>
<artifactId>jasper-runtime</artifactId>
<version>5.5.23</version>
</dependency>
index_jsp.java
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
1、判断请求
2、内置对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //application
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //this 当前page
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
HttpServletRequest request //请求
HttpServletResponse response //响应
3、输出页面前增加的代码
response.setContentType("text/html"); //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
4、以上的对象,可以在jsp页面中直接使用
jsp被处理过程
jsp处理过程源码分析
index.html
<html>
<body>
<h2>Hello World!</h2>
<%
String str = "learn fro java";
%>
<%--输出str--%>
desc:<%=str%>
</body>
</html>
在启动tomcat服务
idea中tomcat work文件下的的java文件
可以看出在jsp中的Java代码会原封不动地输出,而html的代码会使用out.write
输出
注意:每启动一次tomcat服务,都会程序生成新的Java文件和class文件。
二、JSP语法
2.1 JSP需要用的依赖
<dependencies>
<!--servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- 使用maven添加HttpJspBase所在的依赖-->
<dependency>
<groupId>tomcat</groupId>
<artifactId>jasper-runtime</artifactId>
<version>5.5.23</version>
</dependency>
<!-- JSTL表达式依赖-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
JSP支持JAVA的所有语法。JSP作为Java技术的一种应用,它拥有一些自己扩充的语法
2.2 JSP 表达式
<%%>
<%=%> 也可以用${}代替
<%!%>
<%--注释--%> JSP的注释不会再客户端显示,但是html的注释会显示
EL表达式${...}
&{"Hello"} 等价于 <%="Hello
"%>输出值
输出到客户端
<%= 变量或者表达式%>
<%= new java.util.Date()%>
<%="Hello"%>
2.3 JSP脚本片段
<%
int num = 1024;
for (int i = 0; i < 10; i++) {
num += i;
out.println(num);
}
out.print("<h1>sum=" + num+"</h1>");
%>
2.4 脚本片段的再实现
在jsp代码中可以包裹一些html代码以达到特定效果
下面的代码中相对于把Java代码分为两段,在中间添加html代码
<%
for (int i = 0; i < 10; i++) {
%>
<h1> hello <%=i%></h1>
<%
}
%>
可以看到即使在jsp文件中脚本片段将一个循环分成了缩短,但是在生成的Java文件中该端代码依然是在一个循环内,并且调用了指定的方法实现。
2.5 JSP声明
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void method1(){
System.out.println("进入了JSP声明中的method1方法");
}
%>
生成的Java文件中,使用JSP声明的部分编译后会生成到类中
而除了JSP声明以的JSP表达式和脚本片段,都会生成在_jspService()
方法中
三、JSP指令<%@ … … %>
指令 | 描述 |
---|---|
<%@ page … %> | 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 |
<%@ include … %> | 包含其他文件 |
<%@ taglib … %> | 引入标签库的定义 |
3.1 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 | 确定脚本元素能否被使用 |
定制错误页面
在jsp文件中定义
<%@ page errorPage="error/500.jsp" %>
再web.xml中自定义错误页面
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
3.2 Include指令
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
语法格式
<%@ include file="文件相对 url 地址" %>
<%@include ...%>会将两个页面合二为一
<%@include file = ".../header.jsp"%>
<!--网页主体-->
<%@include file = ".../footer.jsp"%>
//JSP标签jsp:include:拼接三个页面,本质上还是三个页面
<jsp:include page="../header.jsp"/>
<!--网页主体-->
<jsp:include page="../footer.jsp"/>
3.3 Taglib指令
JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。
Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
<%@ taglib uri="uri" prefix="prefixOfTag" %>
等价的XML语法
<jsp:directive.taglib uri="uri" prefix="prefixOfTag" />
uri属性确定标签库的位置,prefix属性指定标签库的前缀。
四、九大内置对象和作用域
- PageContext 存东西
- Request 存东西
- Response
- Sesion 存东西
- Apllication 【ServletContext】存东西
- config 【ServletConfig】
- out
- page
- execption
四种作用域(scope)
pageContext.setAttribute("class1","Java");//保存的数据只在一个页面中有效
request.setAttribute("class2","Python");//保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("class3","C");//保存的数据只在一次会话中有效,从打开网站到关闭网站
application.setAttribute("class4","Golang");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
五、JSP标签
<%--jsp标签写法--%>
<jsp:forward page="error">
<jsp:param name="name" value="张三"></jsp:param>
<jsp:param name="age" value="12"></jsp:param>
</jsp:forward>
JSTL (java server pages standard tag library)
标签库依赖
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
参见菜鸟教程
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
根据JSTL标签所提供的功能,可以将其分为5个类别。
- 核心标签
- 格式化标签
- SQL 标签
- XML 标签
- JSTL 函数
JSTL核心标签
使用JSP核心标签库首先要导入对应的标签库
引用核心标签库
<%@ 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 |
核心标签使用举例:
<%--在JSP中显示数据--%>
<c:out value="调用JSTL中的输出方法" default="默认输出值" escapeXml="true"></c:out>
<%--保存数据--%>
<c:set var="i" value="0"></c:set>
<%--删除数据--%>
<c:remove var="i" scope="page"></c:remove>
<%--循环:从0开始,到3每次+1并输出--%>
<c:forEach begin="0" end="3" step="1" var="i">
i=<c:out value="${i}"></c:out>
</c:forEach>
JSTL是为了弥补jsp标签本身的不足而进行的扩充,扩充后的JSP标签的功能标签与Java语言中一样,如遍历、循环等。