目录
一、jsp是什么?有什么用?
二、jsp 怎么创建放在什么位置?
三、jsp 本质
四、jsp 头部的 page 标签
五、jsp 脚本
六、jsp 中的三种注释
七、jsp 中的九大内置对象
八、jsp 四大域对象
九、jsp 中 out.print 输出 和 response.getWriter().print 输出 的区别
十、jsp 中 包含
十一、请求转发的应用
十二、Listener 监听器
十三、EL表达式
十四、EL表达式的运算符
十五、EL表达式中隐含的 11 个对象
十六、JSTL 标签库
一、jsp是什么?有什么用?
jsp 全称:java serverpages ,java的服务器页面jsp的主要作用是代替 Servlet 程序回传 html 页面的数据。这是因为在 Servlet 中响应 html 页面是非常麻烦的事情,开发成本较高。
二、jsp 怎么创建放在什么位置?
和创建 html 页面一样,放在 web目录下。
三、jsp 本质
jsp 本质就是一个 Servlet 程序,。为什么说是一个 Servlet 程序呢?
找到 CATALINA_base 目录:
Using CATALINA_base: "C:Users杨照光.IntelliJIdea2019.1systemtomcatUnnamed_jsp_01"
在 Tomcat 服务器未启动时,我们看 jsp 目录下是空的。
当服务器启动时,并且访问jsp页面,在 jsp 目录下 jsp 页面 会被 Tomcat 编译成 源文件和.class 字节码文件。
打开源文件可以看看 这个 jsp 类是继承 org.apache.jasper.runtime.HttpJspbase,而这个类继承了HttpServlet 。所以简单来说 一个 jsp 就是一个 Servlet
public final class jsp_005f01_jsp extends org.apache.jasper.runtime.HttpJspbase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceimports,
org.apache.jasper.runtime.JspSourceDirectives {
}
四、jsp 头部的 page 标签
page 标签可更改一些重要属性:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
language: 表示 jsp 翻译过后是什么语言文件,目前只支持 java 语言contentType:表示 jsp 返回的数据类型是什么,也是源码中 response.setContendType() 的参数值pageEncoding:表示当前 jsp 页面文件本身的字符集。默认是 UTF-8 ,不用更改import:用于导包errorPage: 当jsp 页面出错后,跳转到哪个页面。"页面路径"
设置错误页面之后:
isErrorPage:设置当前 jsp 页面是否是错误信息页面。默认是false。session:设置访问当前 jsp 页面,是否会创建 HttpSession 对象,默认 trueextends:设置 jsp 翻译出来的 java类 默认继承谁。
以下俩个属性是给 out 输出流使用:
autoFlush:设置 out 输出流缓冲区满了之后,是否自动刷新冲级区,默认值是:truebuffer:设置 out 缓冲区的大小,默认是 8kb
当缓冲区设置比较小,内容较多,并且不自动更新时,会报:缓冲区溢出错误。一般默认是自动更新的,不用改。
五、jsp 脚本
声明脚本(很少用)
格式:<%! java代码 %>
作用:
可以给 jsp 翻译出来的 java类定义属性和方法,内部类等在 Tomcat 编辑的源文件中会和 jsp 中的代码对应~
表达式脚本(常用)
格式: <%= 表达式 %>
作用:往 jsp 页面上输出数据
字符串对象基本数据类型
表达式的特点:
所有表达式脚本都会被翻译到源文件中的 _jspService 方法中,所以 _jspService 中的对象以及方法都能使用表达式脚本都会被翻译称为 out.print() 翻译表达式脚本不要加分号结尾
代码脚本
代码格式: <% java语句 %>
作用:在 jsp 页面中实现功能。(编写的是java语句,方法需使用声明脚本)
if 语句while语句for 循环
特点:
代码脚本翻译之后都在 _jspService 方法中,可以用 _jspService 中的对象。可以由多个代码块共同完成一个java语句 代码脚本还可以和表达式脚本配合使用,输出到 jsp 页面中。
表达式脚本配合代码脚本::
六、jsp 中的三种注释
html
不能写在代码脚本和表达式脚本中java
// 单行注释出现在代码脚本和表达式脚本中jsp
<%--jsp注释--%>可以出现在任意位置
七、jsp 中的九大内置对象
request 请求对象response 响应对象pageContext jsp 上下文对象session 会话对象application ServletContext 对象config ServletConfig对象out jsp 输出流对象page 指向当前 jsp 页面的对象,代表当前 jsp 页面exception jsp 异常对象【需要开启: isErrorPage=true】
八、jsp 四大域对象
pageContext jsp 页面范围内有效request 请求域对象【一次请求内有效】session 会话域对象【一个会话内有效:浏览器访问服务器 ----> 浏览器关闭】application 应用域对象【服务器启动到关闭内有效】
使用顺序,优先从最小的域选择:pageContext < request < session < application
pageContext jsp 页面范围内有效request 请求域对象【一次请求内有效】session 会话域对象【一个会话内有效:浏览器访问服务器 ----> 浏览器关闭】application 应用域对象【服务器启动到关闭内有效】
使用顺序,优先从最小的域选择:pageContext < request < session < application
在当前 jsp 页面范围内:
pageContext 肯定能取出来,因为存数据,取数据在同一个 jsp 页面内request 也能取出来,因为浏览器只发送了一次请求:http://localhost:8080/jsp_01/jsp_05.jspsession 能取出数据,因为浏览器没有关闭application能取出数据,服务器没有关闭
不在当前 jsp 页面范围内
pageContext 无法取出数据,这是因为在 jsp_05 页面存数据,jsp_06页面取数据,是俩个页面,不在范围内。request能出来,是因为转发是一次请求。
不在同一 jsp 页面范围内,并且是俩次请求。
pageContext 和 request 对象都不能取出数据。
当我们打开浏览器,直接访问 http://localhost:8080/jsp_01/jsp_06.jsp
session 域中也取不出数据,因为 在 jsp_05 页面 存数据,而这个页面并没有被打开,所以超过会话范围。
当我们重新部署 Tomcat 服务器时,application 也会取不到数据。
九、jsp 中 out.print 输出 和 response.getWriter().print 输出 的区别
out.print 和 response.getWriter().print 都是向浏览器输出的。
但是我们发现以下,应该是 out.print 先执行,输出到浏览器中,为什么response.getWriter().print 会先输出呢?
out 输出 会直接写到out缓冲区里,response 输出 会直接写到 response 缓冲区里
当 jsp 页面所有代码都执行完会执行俩个操作:
执行 out.flush() 操作,会把out缓冲区中的数据追加到 response 缓冲区里执行 response.flush() 操作,将response 缓冲区的数据输出到浏览器中
十、jsp 中 包含
静态包含:会将指定的页面输出到包含位置上。
path:被包含的页面路径特点:
不会把被包含的 jsp 页面翻译成源文件原理:会将被包含的 jsp 页面的代码 拷贝到源代码中。
<%@include file="path" %>
他会将 jsp_07 页面的 jsp 代码 拷贝到 jsp_08 的源码当中。
动态包含:也会将指定的页面输出到包含位置上
格式:
<%--动态包含--%>
特点:
会将被包含的 jsp 页面翻译成源文件。并生成.class字节码文件
底层其实会调用这样一串代码来实现动态包含。
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "jsp_07.jsp", out, false);
请求转发
<%--请求转发--%>
十一、请求转发的应用
客户端访问流程:
举例说明:Servlet + jsp 输出十个学生的信息【不需要查询数据库】
学生属性:
public class Student { private String name ; private int id ; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Student(String name, int id) { this.name = name; this.id = id; } }Servlet程序:
public class StudentServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Liststudents = new ArrayList<>(); for (int i = 0; i < 10; i++) { int temp = i + 1; Student student = new Student("name" + temp, ++temp); students.add(student); } request.setAttribute("students", students); request.getRequestDispatcher("/jsp_09.jsp").forward(request, response); } } WEB.xml文件:
Student yangzhaoguang.StudentServlet Student /list jsp页面:
Title table, th, tr, td { border: rebeccapurple 1px solid; border-collapse: collapse; } <% List students = (List ) request.getAttribute("students"); int i = 0 ; %>
<%--以上都是固定的,静态的--%> <%--以下数据都应该是从数据库中取--%> <%for (Student student : students) { %> 序号 姓名 年龄 <%--获取学生信息--%> <%}%><%out.print(++i);%> <%= student.getName()%> <%= student.getId()%> 从浏览器上访问:要先访问 Servlet 程序。通过转发跳转到 jsp 页面。
十二、Listener 监听器
什么是监听器?
Listener 监听器 是 JavaWeb 三大组件之一,JavaWeb三大组件:Servlet 程序,Filter 过滤器,Listener 监听器Listener 是 javaEE规范之一,也是个接口
作用:监听某种事务的变化,然后通过回调函数,返回给客户端去做一些相应的操作ServletContextListener 监听器yangzhaoguang.StudentServlet
ServletContextListener 监听器可以监听 ServletContext 对象的创建和销毁ServletContext对象从服务器开始时创建,关闭时销毁在ServletContext对象创建和销毁时都会调用回调函数:
// 初始化执行的
void contextInitialized(ServletContextEvent var1);
// 销毁时执行的
void contextDestroyed(ServletContextEvent var1);
配置监听器步骤:
创建类 ServletContextListener 接口,并重写以上俩个
public class ServletContextListenerImpl implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//编写 ServletContext对象 创建时准备 执行的代码。。。。
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//编写 ServletContext对象 销毁时准备 执行的代码。。。。
}
}
在 web.xml 文件配置监听器
yangzhaoguang.ServletContextListenerImpl
十三、EL表达式
什么是 EL表达式?EL 表达式的作用?
EL表达式的全称:expression Language,是表达式语言,EL表达式的作用:代替 jsp 页面中表达式脚本在 jsp 页面进行数据的输出。因为 EL表达式在输出数据的时候,要比 jsp 的表达式脚本简洁的多。
当我们向页面中输出一个域中不存在的值,会发现俩种输出方式不同:
EL表达式比表达式脚本更加的方便。
演示用 EL表达式输出数组,list集合,map集合
<% ELTest el = new ELTest(); el.setId(12); el.setAdd(new String[]{"河北省唐山市","河北省承德市","河北省石家庄市"}); Mapmap = new HashMap<>(); map.put("key1","张三"); map.put("key2","李四"); map.put("key3","王五"); map.put("key4","木头刘"); el.setMap(map); List 使用 EL 表达式获取属性的时候,底层也是调用 get 的方法。
十四、EL表达式的运算符
. 和 [] 运算符:当域中的 key 中有特殊符号的时候,需要加将 .key 变成 [ 'key' ] 或者 [ "key" ]
十五、EL表达式中隐含的 11 个对象
| 变量 | 类型 | 作用 |
| pageContext | pageContextImpl | 可以获取jsp中九大内置对象 |
| pageScope | Map | 获取 pageContext 域中的数据 【域中的数据通常由键值对形式存储】 |
| requestScope | Map | 获取request域中的数据 |
| sessionScope | Map | 获取session域中的数据 |
| applicationScope | Map | 获取ServletContext域中的数据 |
| param | Map | 获取请求参数的信息 |
| paramValues | Map | 获取请求参数的信息 可以获取多个值 |
| header | Map | 获取请求头的信息 |
| headerValues | Map | 获取请求头的信息 可以获取多个值 |
| cookie | Map | 获取当前请求的 cookie信息 |
| initParam | Map | 获取web.xml中配置的 |
<%
request.setAttribute("key","requestValue");
%>
<%--俩种方式都可以--%>
request域中的数据:${requestScope.key}
request域中的数据:${key}
既然俩种方式都可以,况且 直接用 key 获取value,不是更简洁吗?为什么还有使用 requestScope 呢?
如果我们多个域中有相同的key,那么直接用 key 的方式,获取value ,他会自动从最小的域中开始搜索。
从四大域中获取数据的方法:
pageContext的使用方法:可以获取九大内置对象。
常用的方法:
通常的用法可以将 request 对象放到 request 域中,比较简洁:
param 和 paramValue 的区别:
请求参数:
http://localhost:8080/jsp_01/jsp_14.jsp?userName=zhangsan&password=123&hobby=smoke&hobby=drink
当请求参数有多个时,建议使用 paramvalues
请求参数只有一个,使用 param
header 和 headerValues 的用法:
与浏览器中的一致:
十六、JSTL 标签库
JSTL 标签库,全称是指 JSP Standard Tag Library ,JSP 标准标签库,是一个不断完善的开放源代码的 JSP 标签库。
EL表达式 主要是为了 替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本,这样式的整个 jsp 页面边的更加简洁
JSTL 由5个不同功能的标签库组成:
| 功能范围 | URI | 前缀 |
| 核心标签库 | http://java.sun.com/jsp/jstl/core | c |
| 格式化 | http://java/sum/com/jsp/jstl/fmt | fmt |
| 函数 | http://java/sum/com/jsp/jstl/functions | fn |
| 数据库 | http://java/sum/com/jsp/jstl/sql | sql |
| XML | http://java/sum/com/jsp/jstl/xml | x |
使用步骤:
先将下载好 jar 包 导进去
导入标签库
//核心标签库 prefix:前缀 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> //格式化标签库 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> //函数标签库 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> //数据库标签库 <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> //XML标签库 <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
核心标签库中常用的标签的使用:
| 标签 | 作用 | 属性 |
| 往域中增加数据 | scope属性:指明往哪个域中增加数据 page:PageContext域 request:Request 域 session:Session 域 application:ServletContext域 var 属性:key 值 value属性:value 值 | |
| if判断 | test 属性:判断条件,使用EL表达式 | |
| | 多路判断 和 switch....case...default 差不多 | 注意:标签里不能使用 html 注释。可以使用jsp标签 |
| 循环 | begin 属性:设置开始的索引 end 属性:设置结束的索引 var属性:设置循环变量 item属性:表示遍历的数据源(集合,数组.....) |
演示:
<%--
:往 域中保存数据
scope属性:保存到哪个域中
page“:PageContext域
request:Request域
session:Session域
application:ServletContext 域
var 属性:key值
value 属性:value值
>--%>
<%--取数据--%>
${sessionScope.key}
<%--
标签
test 属性:判断条件,使用EL表达式
--%>
条件为true才会执行
<%--
标签
注意: 标签里不能使用 html 注释,使用 jsp 注释
在 里面在对条件进行判断,需要在加 标签
--%>
<%
request.setAttribute("weight",222);
%>
体重超过100公斤
体重超过80公斤
体重小于80公斤
<%--
标签
begin属性:设置开始的索引
end属性:设置结束的索引
var属性:表示循环的变量
--%>
${i}
<%--
遍历数组
for(String item:arr){}
--%>
<%
request.setAttribute("arr",new String[]{"1302811111","15066668888","13522222222"});
%>
${item}
<%--遍历map集合--%>
<%
Map map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
request.setAttribute("map",map);
// for (Map.Entry entry:map.entrySet()) {
// java 输出
// }
%>
<%--获取所有的 key,会调用Map.Entry中的 getKey()方法。--%>
<%--获取所有的 value,会调用Map.Entry中的 getValue()方法。--%>
${entry.key} = ${entry.value}
演示结果:
使用:
Title
table,tr,th,td {
border: rebeccapurple solid 1px;
border-collapse: collapse;
}
学生信息
姓名
ID
操作
${student.name}
${student.id}
增加 修改 删除



