一文把Servlet整的明明白白!2️⃣
五、JSP
5.1、JSP的作用
JSP——Java Server Page运行在服务器端的 Java 页面,以前学习的 HTML 运行在浏览器端。JSP 是运行在服务器上,最终还是解析成静态的HTML,运行在浏览器。我们在浏览器上看到的HTML页面,其实是 JSP 在服务器上运行的结果。
JSP 的主要作用是代替 Servlet 程序回传 html 页面的数据。因为 Servlet 程序回传 html 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。
5.2、JSP的优势
技术 | 特点 |
---|---|
HTML | 静态页面 优点:方便页面美化操作,写JS脚本和CSS代码都比较方便。 缺点:不能写动态的内容。 |
Servlet | 运行在服务器上小 Java 程序 优点:制作动态内容 缺点:不方便写 HTML 以及 CSS 和 JS 代码 |
JSP | JSP = HTML + Servlet 特点:既有 HTML 的优点:方便美化和编写 JS 代码。 又有 Servlet 优点:可以在页面写 Java 代码,可以制作动态内容(不建议)。 |
5.3、JSP的原理
**JSP页面本质上是一个 Servlet 程序。**当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为.class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:
我们跟踪原代码发现,HttpJspBase 类。它直接地继承了 HttpServlet 类。也就是说。jsp 翻译出来的 java 类,它间接了继承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序。
翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传
给客户端。
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("
<title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("
a.jsp 页面\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
5.4、JSP运行过程
JspServlet 首先会将 jsp 文件代码翻译成 Servlet 的 Java 代码,然后再编译成字节码文件执行,其底层就是一个 Servlet。
- 浏览器请求 JSP 页面,Tomcat 中的 JspServlet 会先 JSP 文件翻译成 Servlet 文件:xxx_jsp.java。
- 将 xxx_jsp.java 文件编译产生字节码文件:xxx_jsp.class。
- 加载字节码文件 xxx_jsp.class 并创建 xxx_jsp 对象。
- 调用 xxx_jsp 的 service 方法处理请求并响应数据。
浏览器第一次访问 JSP 的时候,由 Tomcat 将 JSP 翻译成了 Servlet,并且编译成字节码文件,只生成1次。如果这期间修改了JSP内容,就会重新翻译。
六、转发和重定向
6.1、转发和重定向的作用
用于 web 组件的跳转,从A 组件跳到另一个组件B。
6.2、转发
6.2.1、跳转位置
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。在服务器端进行的组件(资源)的跳转。
6.2.2、转发的方法
request.getRequestDispatcher("/要跳转到的地址").forward(request, response);
6.3、重定向
6.3.1、跳转的位置
在浏览器端进行的页面(组件/资源)跳转。
6.3.2、重定向的方法
response.sendRedirect("要跳转的地址")
6.4、转发和重定向的区别
区别 | 转发 forward | 重定向 redirect |
---|---|---|
目录 | 可以访问WEB-INF目录下的资源 | 不可以访问WEB-INF目录下的资源 |
地址栏 | 地址栏不会发生变化,还是上一个地址 | 会变化,显示新的地址 |
跳转位置 | 在服务端进行跳转 | 在浏览器端跳转 |
请求对象(域) | 请求域数据不会丢失,因为是同一个请求 | 请求域数据会丢失,因为不是同一个请求 |
6.5、注意
- 无论是重定向还是转发,后续代码都会执行,但一般转发或重定向后面不会有代码,没有执行的意义了,因为不管是转发还是重定向浏览器最终显示的都是跳转后页面的数据。
- 如果需要保留请求域中的数据,必须使用转发。
- 如果需要跳转到WEB-INF目录中的资源,必须使用转发。
- 如果需要跨域,必须使用重定向。
七、三大作用域
7.1、什么是作用域
用于 Servlet 之间数据共享的服务器内存区域,作用域结构是一个Map<String, Object>。
7.2、作用域类型
作用域 | 类型 | 作用范围 |
---|---|---|
请求域 | HttpServletRequest | 只在同一次请求中起作用 |
会话域 | HttpSession | 同一个会话中起作用 浏览器第1次访问服务器直到浏览器关闭 的整个过程称为1次会话 |
上下文域 | ServletContext | 同一个应用中起作用 服务器启动直到服务器关闭的整个过程都起作用 |
7.3、作用域方法
与作用域有关的方法 | 作用 |
---|---|
Object getAttribute(“键”) | 从中得到一个值 |
void setAttribute(“键”,Object数据) | 向作用域中存储键值对数据 |
void removeAttribute(“键”) | 删除作用域中的键值对数据 |
7.4、如何选择作用域
先考虑作用范围小的作用域,如果小作用范围的作用域能满足需求就使用小作用范围的作用域。
八、EL表达式
8.1、什么是EL表达式
EL 表达式的全称是:Expression Language
。是表达式语言。
EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。因为 EL 表达式在输出数据的时候,要比 jsp 的表达式脚本要简洁很多。
8.2、EL表达式运算
8.2.1、算数运算
算术运算符 | 说明 | 举例 | 结果 |
---|---|---|---|
+ | 加法 | ${12+18} | 30 |
- | 减法 | ${18-8} | 10 |
* | 乘法 | ${12*12} | 144 |
/(div) | 除法 | {6 div 3} | 2 |
%(mod) | 取模 | {10%3} 或{10 mod 3} | 1 |
8.2.2、逻辑运算
逻辑运算符 | 说明 | 举例 | 结果 |
---|---|---|---|
&& 或 and | 与运算 | ${ 12 == 12 && 12 < 11 } 或 ${ 12 == 12 and 12 < 11 } | false |
| 或 or | 或运算 | ${ 12 = = 12 || 12<11}或 ${12= =12 or 12<11} | true |
! 或 not | 取反运算 | ${!true} 后 ${not true} | false |
8.2.3、关系运算
关系运算 | 说明 | 举例 | 结果 |
---|---|---|---|
== 或 eq | 等于 | ${5 == 5} 或 ${5 eq 5} | true |
!= 或 ne | 不等于 | ${5 !=5} 或 ${5 ne 5} | false |
< 或 lt | 小于 | ${3 < 5} 或 ${3 lt 5} | true |
> 或 gt | 大于 | ${2 > 10} 或 ${2 gt 10} | false |
<= 或 le | 小于等于 | ${ 5 <= 12 } 或 ${ 5 le 12 } | true |
>= 或 ge | 大于等于 | ${ 3 >= 5 }或 ${ 3 ge 5 } | false |
8.2.4、三元运算
表达式 1?表达式 2:表达式 3
如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值。
8.2.5、判空运算
判空:判断的是内容是否为空,不是对象是否为空。
8.3、EL 从四个作用域中取值
EL 获取数据的方式是从 4 个作用域对象中,从小到大的去获取,如果需要指定作用域获取数据,可使用以下 EL 的内置对象来指定。
8.3.1、PageContext 对象
JSP 本质是 Servlet,但比 Servlet 多了一个作用域:页面域,在 JSP 中有四大作用域。页面域是只在一个JSP页面中起作用,不同的JSP之间不能实现数据的共享,比请求域范围还要小。
PageContext 操作有关的方法 | 说明 |
---|---|
void setAttribute(String key, Object value) | 向页面域中添加键和值 |
Object getAttribute(String key) | 从页面域中得到值 |
void removeAttribute(String key) | 删除四个域中同名的键 |
Object findAttribute(String key) | 自动从四个作用域中去查某个键, 从小到大的范围来查找,如果找到就停止。 如果没有找到,返回null |
<%
//向页面域中添加一个字符串
pageContext.setAttribute("name","我是页面域");
%>
8.3.2、 EL 指定域获取数据
作用域 | EL的写法 |
---|---|
页面域 | ${pageScope.键名} |
请求域 | ${requestScope.键名} |
会话域 | ${sessionScope.键名} |
上下文域 | ${applicationScope.键名} |
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL指定域获取数据</title>
</head>
<body>
<%
// 向页面域中添加一个字符串
pageContext.setAttribute("name", "页面域");
// 请求域
request.setAttribute("name", "请求域");
// 会话域
session.setAttribute("name", "会话域");
// 上下文域
application.setAttribute("name", "上下文域");
%>
从页面域获取:${pageScope.name}
<hr>
从请求域获取:${requestScope.name}
<hr>
从会话域获取:${sessionScope.name}
<hr>
从上下文域获取:${applicationScope.name}
<hr>
自动查找作用域获取:${name}
<hr>
</body>
</html>
九、JSTL 标签库
JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标签库。EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面变得更佳简洁。JSTL 由五个不同功能的标签库组成。
功能范围 | URL | 前缀 |
---|---|---|
核心标签库 | http://java.sun.com/jsp/jstl/core | c |
格式化 | http://java.sun.com/jsp/jstl/fmt | fmt |
函数 | http://java.sun.com/jsp/jstl/functions | fn |
9.1、使用步骤
9.1.1、导入jar包
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
9.1.2、引入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
9.1.3、使用标签
9.2、核心标签库常用标签
9.2.1、<c:if />
用于页面上单条件判断。
属性名 | 是否支持EL | 属性类型 | 属 性 描 述 |
---|---|---|---|
test | 支持,必须是 EL | boolean值 | EL 中条件为真则执行标签体内容 注意:没有对应 else 标签 |
<%--
ii.<c:if />
if 标签用来做 if 判断。
test 属性表示判断的条件(使用 EL 表达式输出)
--%>
<c:if test="${ a == b }">
<h1>如果a等于b</h1>
</c:if>
<c:if test="${ a != b }">
<h1>如果a不等于b</h1>
</c:if>
9.2.2、<c:choose>
用于多分支判断(多条件判断),类似于跟 switch … case … default 。
标签名 | 作用 |
---|---|
choose | 类似于 java 中swtich, choose只是一个容器,包含下面两个元素 |
when | 可以出现多个,用于每个判断条件,类似于 switch 中 case。有一个 test 属性,与 if 功能相同 |
otherwise | 如果上面所有的条件都不满足,执行 otherwise 内容。类似于 switch 中 default |
9.2.3、<c:forEach>
用于遍历集合或数组(最为常用)。
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
items | true | 数组或集合 | 使用 EL 表达式,代表集合或数组 |
var | false | String | var 的变量名代表集合中的每一个元素 |
varStatus | false | String | 代表每个元素的状态对象, 一共有4个属性,属性的含义见下表 |
varStatus属性表:
属性 | 数据类型 | 含义 |
---|---|---|
index | int | 当前遍历到的这个元素索引号,从 0 开始 |
count | int | 遍历到当前为止,一共遍历了多少个元素,从1 开始 |
first | boolean | 如果当前遍历的是第1个元素,则返回true |
last | boolean | 如果当前遍历的是最后1个元素,则返回true |
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>学生信息表</title>
<style>
tr {
text-align: center;
}
</style>
</head>
<body>
<table align="center" border="1" cellspacing="0" cellpadding="0" width="80%">
<caption>学生信息列表</caption>
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>成绩</th>
</tr>
<%--
forEach标签:用于JSP页面遍历集合和数组
items属性:设置要遍历的集合或数组:一般从作用域中获取
var属性:设置一个变量名:用来接收遍历到的每一个元素
varStatus属性:设置一个变量名:记录当前遍历元素的状态(状态对象)
index 属性:当前遍历元素的在集合中的索引值:从0开始
count 属性:遍历到当前元素为止已经遍历了多少个元素,从 1 开始
--%>
<c:forEach items="${stus}" var="stu" varStatus="status">
<!-- 给偶数行设置背景颜色 -->
<tr style="background-color:${status.count % 2 == 0 ? 'gray;' : ''}">
<td>${status.count}</td>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.gender? "男":"女"}</td>
<td>${stu.score}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
9.3、格式化标签库常用标签
9.3.1、<fmt:formatDate>
用于对日期进行格式化。
属性名 | 属性类型 | 属 性 描 述 |
---|---|---|
test | Date | 要格式化的日期对象 |
pattern | String | 指定日期格式 |
- 点赞
- 收藏
- 关注作者
评论(0)