09.el表达式介绍与作用
jsp的问题
页面上太多脚本代码,全都是<%
或%>
,导致页面很乱,由于我们用的最多就是脚本代码片段与脚本表达式,所以就需要将这些脚本使用更好的技术替代
脚本表达式------->使用el替代
脚本代码片段----->使用jstl替代
目标
使用el代替页面上的脚本表达式,简化输出
el使用格式
Expression Language;
${ 域里面的key或表达式}
el作用
-
从域里面获取数据进行显示
-
可以使用运算符表达式
以后servlet从数据库获取的数据放到域对象中,jsp使用el技术从域里面获取数据显示
el体验案例需求
设置域对象存储2个数据10,20,之后从域里面获取进行求和运算
el体验效果
实现代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
需求:设置域对象存储2个数据10,20,之后从域里面获取进行求和运算
--%>
<%
//设置域存储数据(暂时放在这里,以后设置域的数据放在servlet里面)
request.setAttribute("one",10);
request.setAttribute("two",20);
%>
<h2>传统方式—jsp脚本表达式输出</h2>
<p><%=Integer.parseInt(request.getAttribute("one").toString()) + Integer.parseInt(request.getAttribute("two").toString())%></p>
<h2>现代推荐方式—el表达式输出</h2>
<p>${one + two}</p>
</body>
</html>
小结
-
el表达式的作用?
简化输出,代替脚本表达式
10.el作用1-jsp内置四大域对象
目标
掌握jsp的四大域对象与应用场景
jsp的4个内置域对象
pageContext,页面域,在一个页面内(一个资源内)有效,一个servlet内,不能实现资源之间传递数据的
request,请求域,一次请求内有效,适合转发传递数据
session,会话域,一次会话内有效,应用场景存储验证码和用户登录数据
servletContext(application别名),上下文域,整个应用程序有效,存储的数据所有用户共享,应用场景统计某个资源访问量等等
pageContext相关方法
页面域操作有关的方法 | 说明 |
---|---|
void setAttribute(String key, Object value) | 向页面域中添加键和值 |
Object getAttribute(String key) | 从页面域中得到值 |
void removeAttribute(String key) | 删除页面域中键值对 |
Object findAttribute(String key) | 自动从四个作用域中去查某个键,从小到大的范围来查找,如果找到就停止。如果没有找到,返回null |
案例需求
使用不同的域对象存储一个key=one, 不同的域value不一样,使用pageContext查找域中的数据
实现代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--需求:使用不同的域对象存储一个key=one, 不同的域value不一样,使用pageContext查找域中的数据--%>
<%
//1.是不同的域对象存储数据
request.setAttribute("one","admin1");
session.setAttribute("one","admin2");
application.setAttribute("one","admin3");
//2.使用pageContext.findAttribute方法查找数据
String one = (String) pageContext.findAttribute("one");//根据键查找数据,依次从pageContext,request,session,application4个域中查找,找到为止
%>
<p>one = <%=one%></p> <%--输出admin1--%>
</body>
</html>
实现效果
http://localhost:8080/day28_jsp_el_jstl_war_exploded/el/02_demo.jsp
小结
pageContext的作用?
jsp的内置页面域对象,在一个页面内数据共享
11.el作用1-获取指定域对象里面的数据
目标
使用el从4个指定域对象里面获取数据显示
实现代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
目标:使用el获取指定4个域对象里面的数据
获取数据格式:${el的域对象.域里面的key}
jsp域对象表示-----------------el获取指定域对象的表示
pageContext pageScope, 获取pageContext里面的数据
request requestScope,获取request里面的数据
session sessionScope,获取session里面的数据
application applicationScope,获取application里面的数据
--%>
<h3>使用el获取指定4个域对象里面的数据</h3>
<%
//1.是不同的域对象存储数据
pageContext.setAttribute("one","admin");
request.setAttribute("one","admin1");
session.setAttribute("one","admin2");
application.setAttribute("one","admin3");
%>
<%--使用el分别获取4个域里面的数据并输出--%>
<p>pageContext的域数据:${pageScope.one}</p> <%--输出admin--%>
<p>request的域数据:${requestScope.one}</p> <%--输出admin1--%>
<p>session的域数据:${sessionScope.one}</p> <%--输出admin2--%>
<p>application的域数据:${applicationScope.one}</p> <%--输出admin3--%>
<p>直接获取域的数据:${one}</p> <%--输出admin, 如果没有指定域对象获取,会一次从pageContext,request,session,application查找,找到为止--%>
</body>
</html>
效果
http://localhost:8080/day28_jsp_el_jstl_war_exploded/el/03_demo.jsp
小结
12.el作用1-获取域中不同类型的数据
目标
会使用el获取域里面常用类型的数据(javaBean,Map,数组,List)
实现代码
User类代码
package com.itheima.entity;
public class User {
private String username;
private int age;
//省略getter/setter封装方法
}
04_demo.jsp代码
<%@ page import="com.itheima.entity.User" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--目标:会使用el获取域里面常用类型的数据(javaBean,Map,数组,List)--%>
<h2>使用el获取域中【JavaBean类型】数据</h2>
<%
//创建对象
User user = new User("张三",20);
//将对象写入域中
request.setAttribute("user",user);
%>
<%--使用el获取JavaBean数据格式:${域里面的key.javaBean对象的属性名} el会自动调用属性的get封装方法获取数据--%>
<p>获取user对象username属性值:${user.username}</p>
<p>获取user对象age属性值:${user.age}</p>
<h2>使用el获取域中【Map类型】数据</h2>
<%
//创建对象
Map<String,User> map = new HashMap<>();
map.put("zhangsan", new User("张三",20));
map.put("lisi", new User("李四",22));
//将对象写入域中
request.setAttribute("userMap",map);
%>
<%--使用el获取Map数据格式:${域里面的key.map里面的key} 获取map里面key的value的数据--%>
<p>获取map对象key=zhangsan的value用户对象username属性值:${userMap.zhangsan.username}</p>
<p>获取map对象key=zhangsan的value用户对象age属性值:${userMap.zhangsan.age}</p>
<p>获取map对象key=lisi的value用户对象username属性值:${userMap.lisi.username}</p>
<p>获取map对象key=lisi的value用户对象age属性值:${userMap.lisi.age}</p>
<h2>使用el获取域中【List类型】数据</h2>
<%
//创建对象
List<User> userList = new ArrayList<>();
userList.add(new User("张三",20));
userList.add(new User("李四",22));
//将对象写入域中
request.setAttribute("userList",userList);
%>
<%--使用el获取List数据格式:${域里面的key[索引]} 索引从0开始,代表获取指定集合指定位置的元素对象--%>
<p>获取List对象第一个元素用户对象username属性值:${userList[0].username}</p>
<p>获取List对象第一个元素用户对象age属性值:${userList[0].age}</p>
<p>获取List对象第二个元素用户对象username属性值:${userList[1].username}</p>
<p>获取List对象第二个元素用户对象age属性值:${userList[1].age}</p>
<h2>使用el获取域中【数组类型】数据</h2>
<%
//创建对象
User[] users ={new User("张三",20),new User("李四",22)};
//将对象写入域中
request.setAttribute("users",users);
%>
<%--使用el获取数组数据格式:${域里面的key[索引]} 索引从0开始,代表获取指定数组指定位置的元素对象--%>
<p>获取数组对象第一个元素用户对象username属性值:${users[0].username}</p>
<p>获取数组对象第一个元素用户对象age属性值:${users[0].age}</p>
<p>获取数组对象第二个元素用户对象username属性值:${users[1].username}</p>
<p>获取数组对象第二个元素用户对象age属性值:${users[1].age}</p>
</body>
</html>
效果
小结
-
el获取哪里的数据?
数据一定要存储在域里面,el就可以获取
13.el作用2-el中使用运算符表达式
常用如下【重点】
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el的运算符</title>
</head>
<body>
<h2>算术运算符</h2>
<p>${5/2}</p> <%--结果2.5, 如果除不尽会保留16位小数,四舍五入--%>
<p>1+2+3+a=${1+2+3+a}</p> <%--结果6, a没有在域里面设置所以取不到,el里面取不到或为null数据不参与运算--%>
<h2>三元运算符</h2>
<p>${16>=18?"成年人":"未成年人"}</p> <%--结果“未成年人”--%>
<h2>判空表达式</h2>
<%--
格式:${empty 表达式}
作用:
1.判断表达式是否null, null返回true, 否则返回false
2.判断表达式是否为空字符串, 空字符串返回true, 否则返回false
3.判断表达式是集合是否有元素, 集合对象不为空,但是里面没有元素返回true, 否则返回false
--%>
<p>空字符串:${empty ""}</p> <%--结果true--%>
<p>空对象:${empty null}</p> <%--结果true--%>
<%
List<String> list =new ArrayList<>();
request.setAttribute("list",list);
%>
<p>空集合:${empty list}</p> <%--结果true--%>
<%
list.add("abc");
request.setAttribute("list",list);
%>
<p>有元素集合:${empty list}</p> <%--false--%>
<h2>获取资源部署名字路径</h2>
<p>获取项目部署路径:${pageContext.request.contextPath}
<%--相当于java代码: pageContext.getRequest().getContextPath() 或 request.getContextPath() 功能一样--%>
</p>
</body>
</html>
效果
http://localhost:8080/day28_jsp_el_jstl_war_exploded/el/05_demo.jsp
14.jstl核心标签库介绍与使用步骤
jstl介绍
Java Standard Tag Library Java标准标签库,apache开源组织开发的
目标
使用jstl标签代替页面上的脚本代码片段
使用的步骤
1.导入jar包
2.jsp页面导入核心标准标签库
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--使用taglib指令导入jstl核心标准标签库
uri="http://java.sun.com/jsp/jstl/core" 标签库的地址,所有的标签都在这个地址里面
prefix="c" 使用jstl核心标签库标签的前缀
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3.在jsp页面上使用jstl提供的标签
if,choose,forEach 共3个标签
小结
-
如何在jsp页面上使用jstl标签?
1.导入jstl的jar包 2.在jsp页面上使用taglib资料导入标准标签库
16.jstl常用标签1-if和choose分支标签
目标
掌握if与choose条件判断标签的使用
实现代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>if标签【重点】</h2>
<%--
作用:用于条件判断,相当于java代码if语句块
格式:<c:if test="${ 条件 }">
符合条件允许的代码
</c:if>
需求:往session域里面写入登录数据,使用if标签判断是否有登录数据,显示不同的信息
--%>
<%
//写入登录数据到session
session.setAttribute("loginUser","admin");
%>
<%--jsp页面使用if判断是否登录--%>
<c:if test="${empty loginUser}">
<p>请登录。。。</p>
</c:if>
<c:if test="${not empty loginUser}">
<p>欢迎您${loginUser}登录成功!</p> <%--结果为这个数据--%>
</c:if>
<h2>choose标签</h2>
<%--
作用:用于条件判断,相当于java代码if-else的语句块
格式:<c:choose>
<c:when test="${ 条件1 }"></c:when> ---》if
<c:when test="${ 条件2 }"></c:when> ---》else if
<c:otherwise></c:otherwise> ---》else
</c:choose>
需求:往session域里面写入登录数据,使用if标签判断是否有登录数据,显示不同的信息
--%>
<%
//写入登录数据到session
session.setAttribute("loginUser",null);
%>
<c:choose>
<c:when test="${empty loginUser}">
<p>请登录。。。</p> <%--结果为这个数据--%>
</c:when>
<c:otherwise>
<p>欢迎您${loginUser}登录成功!</p>
</c:otherwise>
</c:choose>
</body>
</html>
效果
http://localhost:8080/day28_jsp_el_jstl_war_exploded/jstl/02_demo.jsp
17.jstl常用标签2-foreach循环标签
目标
使用foreach标签实现循环,代替脚本代码片段
实现代码
<%@ page import="com.itheima.entity.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>foreach标签</h2>
<%--
作用:用于循环
1.次数循环格式:
<c:forEach begin="开始数字" end="结束数字" var="循环变量名称,相当于i" step="步长默认为1,循环变量递增值,类似i++">
循环体代码
</c:forEach>
2.List集合、数组循环格式【以后使用最多】:
<c:forEach items="使用el获取遍历的集合" var="集合的每个元素" varStatus="循环过程信息">
循环体代码
</c:forEach>
varStatus,循环过程信息,在线循环过程中foreach标签将一些数据放入到这个属性中,循环过程信息如下:
index,循环的索引,从0开始
count,循环的次数,从1开始
3.Map循环格式:
<c:forEach items="使用el获取遍历的Map集合" var="集合的每个元素类似每个entry" varStatus="循环过程信息">
获取每个元素的key=${entry.key} 获取每个元素的value=${entry.value}
</c:forEach>
java代码分析:
Set<Entry<String,Object>> set= Map.entrySet();
一个Entry包含着一个键值对
--%>
<h4>1.次数循环</h4>
<%--目标:输出5遍hello world--%>
<c:forEach begin="1" end="5" step="1">
<p>hello world</p>
</c:forEach>
<h4>2.List集合、数组循环</h4>
<%--目标:遍历用户列表集合--%>
<%
//定义用户列表List集合
List<User> userList = new ArrayList<>();
userList.add(new User("张三",20));
userList.add(new User("李四",22));
userList.add(new User("王五",23));
//写入域中
request.setAttribute("userList",userList);
%>
<c:forEach items="${userList}" var="user" varStatus="status">
<p>${status.count},${user.username},${user.age}</p>
</c:forEach>
<h4>3.Map循环格式</h4>
<%--目标:遍历用户列表Map集合--%>
<%
Map<String,User> map = new HashMap<>();
map.put("zhangsan", new User("张三",20));
map.put("lisi", new User("李四",22));
map.put("wangwu", new User("王五",23));
request.setAttribute("map",map);
%>
<c:forEach items="${map}" var="entry" varStatus="status">
<p>${status.index},${entry.key},${entry.value.username},${entry.value.age}</p>
</c:forEach>
</body>
</html>
效果
http://localhost:8080/day28_jsp_el_jstl_war_exploded/jstl/03_foreach.jsp
18.MVC+三层架构开发模式
传统三层架构的问题
MVC结构
现代模式:MVC+三层架构模式
使用MVC优化传统三层架构
servlet职责:调用业务获取数据,存储到域,跳转到jsp页面
jsp职责:专门用于展现数据,使用el获取域里面的数据进行展现
19.综合案例:完成用户显示列表案例
需求
使用三层架构和MVC模式开发代码,完成用户显示列表功能。
效果
实现分析
实现步骤
环境搭建
sql数据库表准备
create table contact(
id int primary key auto_increment ,
name varchar(20) not null ,
sex char(1) ,
age int(3) unsigned , -- 无符号
address varchar(10) , -- 籍贯
qq varchar(18) ,
email varchar(25)
) ;
-- 插入记录
insert into contact(name,sex,age,address,qq,email) values
('猪八戒','男',25,'广东','834523234','zhuzhuxia@itcast.cn'),
('貂蝉','女',18,'湖南','59869834','diaochan@qq.com'),
('孙悟空','男',28,'湖南','87967822','wukong@itheima.com'),
('周瑜','男',25,'广西','2743759345','zhou@163.com');
select * from contact;
创建实体类
package com.itheima.entity;
public class Contact {
private int id;
private String name;
private String sex;
private int age;
private String address;
private String qq;
private String email;
@Override
public String toString() {
return "Contact{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", address='" + address + '\'' +
", qq='" + qq + '\'' +
", email='" + email + '\'' +
'}';
}
public Contact() {
}
public Contact(int id, String name, String sex, int age, String address, String qq, String email) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.address = address;
this.qq = qq;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
引入资源jar包,配置文件,最后目录结构
实现分析
IContactDao代码
package com.itheima.dao;
import com.itheima.entity.Contact;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface IContactDao {
//查询联系人列表
@Select("SELECT * FROM contact")
List<Contact> findAll();
}
service代码
package com.itheima.service;
import com.itheima.dao.IContactDao;
import com.itheima.entity.Contact;
import com.itheima.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class ContactService {
//查询联系人列表
public List<Contact> findAll(){
//1.获取SqlSession连接对象
SqlSession sqlSession = MybatisUtils.getSession();
//2.dao代理对象
IContactDao contactDao = sqlSession.getMapper(IContactDao.class);
//3.调用数据访问层获取
List<Contact> contactList = contactDao.findAll();
//4.释放连接
MybatisUtils.closeSession(sqlSession);
//5.返回结果
return contactList;
}
}
servlet代码
package com.itheima.web;
import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "ListContactServlet", urlPatterns = "/ListContactServlet")
public class ListContactServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
//实例业务类
private ContactService contactService = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用业务层获取联系人列表
List<Contact> contactList = contactService.findAll();
//2.存储到请求域
request.setAttribute("contactList",contactList);
//3.转发到list.jsp页面
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
list.jsp代码
展现数据