概述
目录
一、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 对象,默认 true
- extends:设置 jsp 翻译出来的 java类 默认继承谁。
以下俩个属性是给 out 输出流使用:
- autoFlush:设置 out 输出流缓冲区满了之后,是否自动刷新冲级区,默认值是:true
- buffer:设置 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
- <!--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
- 在当前 jsp 页面范围内:
- pageContext 肯定能取出来,因为存数据,取数据在同一个 jsp 页面内
- request 也能取出来,因为浏览器只发送了一次请求:http://localhost:8080/jsp_01/jsp_05.jsp
- session 能取出数据,因为浏览器没有关闭
- 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:include page="path"></jsp:include>
特点:
会将被包含的 jsp 页面翻译成源文件。并生成.class字节码文件
底层其实会调用这样一串代码来实现动态包含。
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "jsp_07.jsp", out, false);
- 请求转发
<%--请求转发--%>
<jsp:forward page="jsp_06.jsp"></jsp:forward>
十一、请求转发的应用
客户端访问流程:
举例说明: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程序:
/*Servlet程序*/ public class StudentServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*1、获取请求信息参数*/ /*2、执行sql语句*/ /*3、数据库查询数据*/ /*以后这些数据都是从数据库中取*/ List<Student> students = 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文件:
<servlet> <servlet-name>Student</servlet-name> <servlet-class>yangzhaoguang.StudentServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Student</servlet-name> <url-pattern>/list</url-pattern> </servlet-mapping>
jsp页面:
<html> <head> <title>Title</title> <style type="text/css"> table, th, tr, td { border: rebeccapurple 1px solid; border-collapse: collapse; } </style> </head> <body> <% /*从请求域中取出数据*/ List<Student> students = (List<Student>) request.getAttribute("students"); int i = 0 ; %> <table> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> </tr> <%--以上都是固定的,静态的--%> <%--以下数据都应该是从数据库中取--%> <%for (Student student : students) { %> <tr> <%--获取学生信息--%> <td><%out.print(++i);%></td> <td><%= student.getName()%></td> <td><%= student.getId()%></td> </tr> <%}%> </table> </body> </html>
从浏览器上访问:要先访问 Servlet 程序。通过转发跳转到 jsp 页面。
十二、Listener 监听器
- 什么是监听器?
- Listener 监听器 是 JavaWeb 三大组件之一,JavaWeb三大组件:Servlet 程序,Filter 过滤器,Listener 监听器
- Listener 是 javaEE规范之一,也是个接口
<listener> <listener-class>yangzhaoguang.StudentServlet</listener-class> </listener>
- 作用:监听某种事务的变化,然后通过回调函数,返回给客户端去做一些相应的操作
- ServletContextListener 监听器
- 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 文件配置监听器
<listener>
<listener-class>yangzhaoguang.ServletContextListenerImpl </listener-class>
</listener>
十三、EL表达式
什么是 EL表达式?EL 表达式的作用?
- EL表达式的全称:Expression Language,是表达式语言,
- EL表达式的作用:代替 jsp 页面中表达式脚本在 jsp 页面进行数据的输出。因为 EL表达式在输出数据的时候,要比 jsp 的表达式脚本简洁的多。
当我们向页面中输出一个域中不存在的值,会发现俩种输出方式不同:
EL表达式比表达式脚本更加的方便。
演示用 EL表达式输出数组,list集合,map集合
<body> <% ELTest el = new ELTest(); el.setId(12); /*增加String数组*/ el.setAdd(new String[]{"河北省唐山市","河北省承德市","河北省石家庄市"}); /*增加map集合*/ Map<String,String> map = new HashMap<>(); map.put("key1","张三"); map.put("key2","李四"); map.put("key3","王五"); map.put("key4","木头刘"); el.setMap(map); /*增加list集合*/ List<Object> list = new ArrayList<>(); list.add("130281199909194444"); list.add("130281199909195555"); list.add("130281199909194092"); el.setList(list); /*放到 request 域中*/ request.setAttribute("info",el); %> <%--输出info--%> 输出 info:${info}<br> <%--通过在向域中存放数据时取得名字来获取域中的数据--%> 输出ELTest中的id属性:${info.id}<br> 输出ELTest中list集合:${info.list}<br> <%--如果指向访问集合中的某个数据: 使用 get 方法可以 也可以使用下标,底层使用的也是 get 方法。 --%> 通过get方法输出list集合中某个数据:${info.list.get(2)}<br> 通过下标获取list集合中的数据:${info.list[2]}<br> 输出ELTest中的map集合:${info.map}<br> <%--想问 map 集合中的某个数据 可以直接 .key, key就是map集合中的键值,但是底层也是调用的 get 方法。 也可以用 get 方法 --%> 通过key输出map集合中的某个数据:${info.map.key3}<br> 通过get方法输出map集合中的某个数据:${info.map.get("key3")}<br> <%--输出String数组--%> <%--访问某个元素,也可通过下标的方法--%> 通过下标输出String数组中的某个元素:${info.add[1]}<br> </body>
使用 EL 表达式获取属性的时候,底层也是调用 get 的方法。
十四、EL表达式的运算符
. 和 [] 运算符:当域中的 key 中有特殊符号的时候,需要加将 .key 变成 [ 'key' ] 或者 [ "key" ]
十五、EL表达式中隐含的 11 个对象
变量 | 类型 | 作用 |
pageContext | pageContextImpl | 可以获取jsp中九大内置对象 |
pageScope | Map<String,Object> | 获取 pageContext 域中的数据 【域中的数据通常由键值对形式存储】 |
requestScope | Map<String,Object> | 获取request域中的数据 |
sessionScope | Map<String,Object> | 获取session域中的数据 |
applicationScope | Map<String,Object> | 获取ServletContext域中的数据 |
param | Map<String,Object> | 获取请求参数的信息 |
paramValues | Map<String,String[]> | 获取请求参数的信息 可以获取多个值 |
header | Map<String,Object> | 获取请求头的信息 |
headerValues | Map<S tring,Object> | 获取请求头的信息 可以获取多个值 |
cookie | Map<String,Object> | 获取当前请求的 cookie信息 |
initParam | Map<String,Object> | 获取web.xml中配置的<context-param> 上下文参数 |
<%
request.setAttribute("key","requestValue");
%>
<%--俩种方式都可以--%>
request域中的数据:${requestScope.key}<br>
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" %>
核心标签库中常用的标签的使用:
标签 | 作用 | 属性 |
<c:set /> | 往域中增加数据 | scope属性:指明往哪个域中增加数据 page:PageContext域 request:Request 域 session:Session 域 application:ServletContext域 var 属性:key 值 value属性:value 值 |
<c:if></c:if> | if判断 | test 属性:判断条件,使用EL表达式 <c:if>条件为true执行的语句</c:if> |
<c:choose><c:when> <c:otherwise> | 多路判断 和 switch....case...default 差不多 | <c:choose>:开始判断,相当于switch <c:when>:判断每一种结果,相当于case <c:otherwise>:剩下的结果,相当于 default 注意:标签里不能使用 html 注释。可以使用jsp标签 |
<c:forEach></c:forEach> | 循环 | begin 属性:设置开始的索引 end 属性:设置结束的索引 var属性:设置循环变量 item属性:表示遍历的数据源(集合,数组.....) |
演示:
<body>
<%--
<c:set /> :往 域中保存数据
scope属性:保存到哪个域中
page“:PageContext域
request:Request域
session:Session域
application:ServletContext 域
var 属性:key值
value 属性:value值
>--%>
<c:set scope="session" var="key" value="sessionValue" />
<%--取数据--%>
${sessionScope.key}
<%--
<c:if /> 标签
test 属性:判断条件,使用EL表达式
--%>
<c:if test="${12 == 12}" >
<h3>条件为true才会执行</h3>
</c:if>
<%--
<c:choose> <c:when > <c:otherwise>标签
注意:<c:choose></c:choose> 标签里不能使用 html 注释,使用 jsp 注释
在<c:otherwise> <c:when> 里面在对条件进行判断,需要在加<c:choose></c:choose>标签
--%>
<%
request.setAttribute("weight",222);
%>
<c:choose>
<c:when test="${ requestScope.weight > 100}">
<h3>体重超过100公斤</h3>
</c:when>
<c:when test="${ requestScope.weight > 80}">
<h3>体重超过80公斤</h3>
</c:when>
<c:otherwise>
<h3>体重小于80公斤</h3>
</c:otherwise>
</c:choose>
<%--
<c:forEach>标签
begin属性:设置开始的索引
end属性:设置结束的索引
var属性:表示循环的变量
--%>
<c:forEach begin="1" end="10" var="i">
${i} <br>
</c:forEach>
<br>
<%--
遍历数组
for(String item:arr){}
--%>
<%
request.setAttribute("arr",new String[]{"1302811111","15066668888","13522222222"});
%>
<c:forEach items="${ requestScope.arr }" var="item">
${item}<br>
</c:forEach>
<%--遍历map集合--%>
<%
Map<String,String> 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<String,String> entry:map.entrySet()) {
// java 输出
// }
%>
<c:forEach items="${ requestScope.map}" var="entry">
<%--获取所有的 key,会调用Map.Entry中的 getKey()方法。--%>
<%--获取所有的 value,会调用Map.Entry中的 getValue()方法。--%>
<h3> ${entry.key} = ${entry.value} </h3>
</c:forEach>
</body>
演示结果:
使用:<c:forEach> + Servlet 程序+表格的方式 遍历学生的信息【不用mysql】
<html> <head> <title>Title</title> <style type="text/css"> table,tr,th,td { border: rebeccapurple solid 1px; border-collapse: collapse; } </style> </head> <body> <h1>学生信息</h1> <table > <tr> <th>姓名</th> <th>ID</th> <th>操作</th> </tr> <c:forEach items="${ requestScope.students }" var="student"> <tr> <td> ${student.name} </td> <td> ${student.id} </td> <td>增加 修改 删除</td> </tr> </c:forEach> </table> </body> </html>
最后
以上就是唠叨鸭子为你收集整理的Jsp内容复习大纲的全部内容,希望文章能够帮你解决Jsp内容复习大纲所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复