JSP(Java Server Pages)
- 为什么学习JSP
Servlet技术需要输出标签的时候,需要拼接字符串,麻烦而且容易出错,而JSP可以解决这个问题 - 概念
JSP是java的服务器页面,是sun公司开发用于动态web的一门技术 - 特点
在jsp页面,即可以编写java代码,也可以编写html代码
JSP初体验
目标:完成一个加法案例
<%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/8
Time: 10:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>加法</title>
</head>
<body>
<%
int num1 = 1;
int num2 = 2;
//out.write()方法会将数字转成ASCLL码表上的字符
String result = num1 + num2 + "";
%>
<span style="color:red"><% out.write(num1 + "+" + num2 + " = " + result);%></span>
</body>
</html>
结果:
3. JSP的执行原理
- 疑问:
- 为什么jsp既可以编写java代码也可以直接编写html代码呢?
解答:
jsp本质上还是一个Servlet程序,所以可以编写java代码,之所以可以编写html代码是因为jsp文件可以将我们写的标签用out.write()的形式拼接在页面上,实际跟我们在servlet程序上拼接标签是一样的 - jsp页面为什么可以直接使用out,request,session这些对象呢?
解答:
我们在jsp文件中编写的java代码全部都落入到sp的翻译文件中的service方法内部,在service方法一开始的时候就已经定义了大量这些对象提供我们去使用
注意事项
- 访问一个jsp文件,本质上并不是访问了jsp页面,而是访问了jsp的翻译文件。jsp的, 翻译文件是一个java文件
- jsp的翻译文件本质上就是一个Servlet程序
- jsp的基本语法
4.1 注释格式:
<%–需要注释的内容–%>或者使用html的注释格式
java的注释格式也可以,但是要放在<% %>内
4.2 html注释与jsp注释的区别:
- jsp页面上可以使用html注释也可以使用jsp注释,但是jsp的安全性更好(在网页中查看源代码可以看到html注释)
- 如果在jstl标签上使用html注释会报错
4.3 jsp上描写java代码的三种方式:
- 脚本代码格式:<% java代码 %>
脚本代码注意事项:
- 一个jsp可以编写多个脚本代码片段
- 不不同脚本代码片段的代码可以相互访问,是因为脚本代码块片段的代码全部都在service方法内部
-
jsp声明
作用:可以定义jsp本质servlet类的成员变量或成员方法
格式:<%! 成员变量或成员方法 %>注意事项:
- 使用jsp声明的时候,千万不要定义与翻译文件同名的方法。一旦出现同名的函数就会报错
- 脚本表达式
作用:用于取代out.write()语句,输出体不需要写在write()函数里面
格式:<%= 变量|常量 %>
举例:
<% String userName = “小黄” %><%=userName%>
注意事项:脚本表达式不需要以;(分号)结束
重点
企业动态资源开发实践
问题:jsp和servlet都可以开发动态资源,处理请求和响应,那怎么选用jsp和servlet呢?
解答:
首先查看jsp和servlet的区别
jsp:编写html布局代码方便,所以主要负责显示布局动态资源数据
servlet:写的都是java代码,所以主要负责产生动态资源数据
所以jsp与servlet配合使用,用户请求servlet负责从数据库获取数据,存储到域对象里面,之后跳转到jsp页面显示布局动态资源数据
最佳实践:Servlet负责产生数据,jsp只负责显示数据
EL表达式
- 体验EL表达式
- EL表达式的格式:${表达式的内容}
- EL表达式的作用:从域对象中查找指定的数据,并且输出
- EL表达式的格式的作用
EL全称:Expression Language
作用:代替jsp中脚本表达式的功能,简化对java的操作
举例: ${city}等价于<%=request.getAttribute(“city”) %> - 注意事项:
- el表达式的作用是从域对象中查找指定名字的数据,然后输出,在域中默认的搜索顺序是从小到大搜索,排序是request < session < servletContext
- 如果需要指定域对象,需要指定在哪个域对象
取出request域的数据: r e q u e s t S c o p e . c i t y 取 出 s e s s i o n 域 的 数 据 : {requestScope.city} 取出session域的数据: requestScope.city取出session域的数据:{sessionScope.city}
取出servletContext域的数据:${applicationScope.city}
- EL表达式的基本使用
- 取出域对象数据并输出
c i t y 等 价 于 < 取 出 r e q u e s t 域 的 数 据 : {city}等价于<%=request.getAttribute("city") %> 取出request域的数据: city等价于<取出request域的数据:{requestScope.city}
取出session域的数据: s e s s i o n S c o p e . c i t y 取 出 s e r v l e t C o n t e x t 域 的 数 据 : {sessionScope.city} 取出servletContext域的数据: sessionScope.city取出servletContext域的数据:{applicationScope.city} - el表达式获取javabean的属性数据(重点)
简单来说,javabean是一个类,满足所以成员变量都有get,set方法,并存在无参数的构造方法- 格式:${对象.属性名}
- 显示javabean属性数据需要注意的事项
- el表达式显示javabean的属性数据底层是依赖getXXX方法,如果缺少get方法,会报错,出现javax.el.PropertyNotFoundException,找不到属性的错误
- 在el表达式中一个javabean是否具备指定的属性是看是否存在getXXX方法,与成员变量无关
- el表达式获取集合类型数据(数组,list,Map)
注意,一定要将要获取的数据存储在域对象中- 获取数组的数据
数 组 名 [ 索 引 值 ] 举 例 : {数组名[索引值]} 举例: 数组名[索引值]举例:{arr[1]} - 获取List集合的数据
${集合名[索引值]} - 获取Map集合的数据
格式一:${集合名.key}
格式二: ${集合名[‘key’]} 可以针对key有特殊符号的数据
举例:
Map<String,String> map = new HashMap<>()
map.put(“a”,“张三”)
request.getSession().setAttribute(“map”,map)
则 ${map.a}可以得到张三
- EL表达式执行运算
格式: 域 对 象 1 运 算 符 域 对 象 2 举 例 : {域对象1 运算符 域对象2} 举例: 域对象1运算符域对象2举例:{num1 + num2}
运算符为算数运算符或者逻辑运算符 - 特殊运算符:empty运算符
作用:- 可以判断变量是否为null
- 可以判断集合是否为空元素(null或者没有元素)
- 返回值是true或者false
格式:
${empty 变量名或集合名}
- 获取数组的数据
JSTL的核心标签库
- jstl概念:
jsp的标准标签库(Jsp Standard Tag Library),简称JSTL。jsp标准标签库,由很多标签组成,这些标签称为服务器端标签。服务区端标签的作用是封装了具有特定的功能的java代码,以标签形式编写,代替特定功能的java代码
另外,jstl的核心标签库为core - jstl标签的使用
- 导入jar包
- 使用taglib指令在jsp页面导入要使用的jstl标签库
<%@taglib uri=“标签库的地址(http://java.sun.com/jsp/jstl/core)” prefix=“标签的前缀©” %>
2.1 if标签的使用
格式:<c:if></c:if>
<c:if>标签的属性:
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
test | true | boolean | 决定是否处理标签体中的内容的条件表达式 |
var | false | String | 用于指定将test属性的执行结果保存到某个Web域中的某个属性名称 |
scope | false | String | 指定将test属性的执行结果保存到哪个Web域中 |
代码演示
<%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/8
Time: 21:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>if标签的使用</title>
</head>
<body>
<%
/*
test:编写布尔表达式,判断的条件
scope:指定结果存储到指定的域中
var:指定一个名字存储布尔表达式的结果
*/
%>
<%-- 当test属性的值为true,则会输出标签里的内容--%>
<c:if test="${age >= 18}" scope="session" var="reslut">
已经成年
</c:if>
<%
/*
上面的代码表示:session.setAttribute("reslut",true)
可以通过${result}获得结果true
*/
%>
</body>
</html>
注意,if标签只能处理一种情况,没有else
2.2choose标签的使用
- 格式
<c:choose>
<c:when test=“条件1”></c:when>
<c:when test=“条件2”></c:when>
<c:when test=“条件3”></c:when>
…
<c:otherwise>不符合上述条件要执行的代码
</c:choose>
代码:
<%@ page import="mobel.Person" %><%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/8
Time: 22:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>choose标签的使用</title>
</head>
<body>
<%
Person person = new Person(1,"小黄",19);
request.setAttribute("isLogin",person);
%>
<%-- 使用choose标签--%>
<%--注意:--%>
<%-- 1. 多个when只会选择一个 --%>
<%-- 2. 不可以嵌套使用,既在<c:when></c:when>之间不能使用<c:when></"when>标签--%>
<%-- 3. otherwise只能出现一个--%>
<c:choose>
<c:when test="${!empty isLogin}">
不为空
</c:when>
<c:when test="${isLogin.age >= 18}">
已经成年1
</c:when>
<c:otherwise>
未成年1
</c:otherwise>
</c:choose>
</body>
</html>
2.3. foreach标签
- 作用:用于遍历数组,集合
- 格式:<c:foreach></c:foreach>
- foreach的属性
- items:指定遍历的目标 使用:iteams = “${集合名}”
- var:指定遍历出来每个元素的存储在域中的名字
注意:两个属性要配合使用 - begin:指定开始遍历的索引值(包括)
- end:指定遍历结束的索引值(包括)
注意:区间为[begin,end]包头也包尾 - step:指定遍历的步长
- varStatus:指定存储遍历信息对象的名字
注意:一个集合在遍历的过程中会产生大量的信息,比如index(索引值),count(序号),这些信息都被封装到一个对象中了。其中varStatus这个属性用来指定这个对象的名字,通过名字来使用这个域对象。比如域对象.setAttributes(“指定的名字”,status) 假定status是这个对象
- 使用:foreach标签遍历List集合
代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="mobel.Person" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/10
Time: 10:29
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>foreach标签的使用</title>
</head>
<body>
<%
List<Person> list = new ArrayList<>();
list.add(new Person(110,"张三",20));
list.add(new Person(220,"李四",21));
list.add(new Person(330,"王五",22));
//加入域对象
request.setAttribute("list",list);
%>
<%-- 设置table,循环输出 --%>
<table cellpadding="0px" cellspacing="0px" border="1px" align="center">
<tr>
<th>
序号
</th>
<th>
身份号
</th>
<th>
姓名
</th>
<th>
年龄
</th>
</tr>
<%--
iteams:指定遍历的对象
var:遍历单个对象的名字
varStatus:信息对象的名称
step:步长
begin:开始位置
end:结束位置
--%>
<c:forEach items="${list}" var="listItem" varStatus="status" step="2" begin="0" end="2">
<tr>
<td>
${status.count}
</td>
<td>
${listItem.id}
</td>
<td>
${listItem.name}
</td>
<td>
${listItem.age}
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
foreach遍历数组,使用方式和遍历List集合相同
代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/10
Time: 11:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>foreach遍历数组</title>
</head>
<body>
<%
String[] arr = {"a","b","c"};
request.setAttribute("arr",arr);
%>
<%-- 开始遍历数组 --%>
<c:forEach items="${arr}" var="item">
遍历数组:${item}
</c:forEach>
</body>
</html>
foreach遍历map集合
代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: 小黄
Date: 2021/3/10
Time: 11:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>foreach遍历Map集合</title>
</head>
<body>
<%
Map<String, String> map = new HashMap<>();
map.put("a","张三");
map.put("b","李四");
map.put("c","王五");
request.setAttribute("map",map);
%>
<%-- 注意:遍历Map集合,每个元素是一个entry对象 --%>
遍历map集合:<br>
<c:forEach items="${map}" var="entry">
key:${entry.key}
value:${entry.value}
</c:forEach>
</body>
</html>
开发模式
- 概念:
开发模式就算我们程序员在实际开发中累积下来的优秀开发模式。(项目的管理经验)
2. JSP开发模式
2.1 JSP +Model1(最早期)
2.2 JSP+Model2(MVC模式)
- 介绍:比JSP+Model1有所改进,把业务逻辑的内容放到了javaBean中,而JSP页面只负责显示,servlet负责处理请求与调度的工作。但是javaBean依然要封装数据,处理业务和操作数据库等混合在一起
2.处理模式
MVC模式:M model(javaBean),V(view):视图(jsp) C(control):控制器 (Servlet)
2.3 MVC+三层架构
- 介绍:
JSP模式是理论基础,但在实际开发中,我们常将服务器端程序,根据逻辑进行分层。一般比较常见的是分三层,即三层架构体系。三层分别是:表示层,业务逻辑层,数据访问层。
表示层:又称为web层,与浏览器进行数据交互
业务逻辑层:又称为service层,专门用于处理业务数据的
数据访问层:又称为dao层,与数据库进行数据交换的。将数据库的一条记录与JavaBean进行对应