01.反馈-复习-学习目标
反馈
内容 |
---|
idea2018包名写中文无法正常启动服务器 |
作业有没有详细介绍感觉没有思路呢 |
2019版本过滤器在同时配置了注解与XML的情况下同一个过滤器为什么会执行两次 符合拦截路径的每个过滤器都会运行,如果多次需要调试代码 |
重定向和转发跳转,哪个例子用哪个不太清楚 使用了请求域存储数据进行页面跳转肯定使用请求转发,否则都建议使用重定向跳转 |
还行挺简单 |
复习
1.能够说出过滤器的作用
拦截请求与响应
适合解决问题类型:如果某一个操作是你多资源都要进行的,可以将这个操作放入到过滤器中集中处理
2.能够编写过滤器
xml方式:
1、创建一个类实现Filter接口,重写doFilter方法
2、配置web.xml的过滤器拦截路径
注解方式:
1、使用idea提供模板创建过滤器类,重写doFilter方法
2、在注解上@WebFilter里面配置拦截路径
3.能够说出过滤器生命周期相关方法
init方法
doFilter方法
destroy方法
过滤器对象是服务器启动时创建的一个唯一对象
过滤器对象是服务器关闭前销毁
4.能够根据过滤路径判断指定的过滤器是否起作用
1、完全匹配:拦截路径与访问的资源路径一模一样
2、目录匹配:拦截指定目录开头的所有资源,格式要求,以“/”开头,以“/*”结尾
3、扩展名匹配:拦截指定扩展名结尾的所有资源,格式要求:以“*”开头,以“.扩展名”结尾
5.能够说出什么是过滤器链
一个资源被多个过滤器拦截请求与响应,并进行串行执行
可以掌握过滤器执行顺序的修改:
注解方式:修改过滤器的类名,控制类名字符串比较升序
xml方式:配置顺序就是执行顺序
6.能够编写过滤器解决全局乱码
7.过滤器的拦截方式
REQUEST: 过滤器默认拦截浏览器直接访问的资源(重定向)
FORWARD:过滤器拦截间接访问的资源(请求转发,服务器内部跳转)
学习目标
- 能够配置ServletContextListener
- 能够理解ServletContextListener的作用
- 能够使用mvc及三层实现用户的列表查询操作
- 能够使用mvc及三层实现用户的新增操作
- 能够使用mvc及三层实现用户的修改操作
- 能够使用mvc及三层实现用户的删除操作
02.监听器:概述与使用【理解】
目标
- 理解监听器是什么
- 理解创建监听器的步骤
- 理解上下文域对象监听器ServletContextListener的作用
监听器介绍
服务器通过监听器可以监听捕捉三大域对象(request,session,servletContext)的变化。
服务器提供了监听器接口,开发人员实现对应的接口就可以获取域对象变化的时间点,作出自己的业务逻辑控制
监听器接口分类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lTTyy7e9-1606227154464)(assets/1549946193818.png)]
说明
XXXXListener监听器:都可以捕捉到域对象创建与销毁
XXXXAttributeListener监听器:都可以捕捉到域对象里面数据的改变
ServletContextListener介绍
用于捕捉上下文域对象的创建与销毁,通过实现这个监听器可以获取到服务器创建与销毁上下文域的时间点
ServletContextListener监听器注解实现步骤
1、创建类并实现ServletContextListener接口
2、重写创建时间点与销毁时间点对应的方法,就可以获取对应的时间点
3、使用注解@WebListener标识当前类为监听器,这样服务器来管理并调用使用当前类
实现代码
package _01_创建ServletContextListener监听器;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* @author 黑马程序员
*/
@WebListener
public class MyServletContextListener implements ServletContextListener {
//上下文域对象创建时候触发的方法
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("==上下文域对象被创建了==");
//注意:上下文域对象是服务器启动时最先创建的对象,所有启动的时候就会输出上面的信息
//ServletContext servletContextEvent.getServletContext() 获取到服务器创建的上下文域对象
//Object servletContextEvent.getSource() 获取当前监听捕捉的域对象,就是上下文域对象
}
//上下文域对象销毁前触发的方法
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("==上下文域对象将要销毁了==");
//注意:服务器关闭之前销毁上下文域对象,所以服务器关闭就会输出上面的信息
}
}
运行效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkN7qQe4-1606227154466)(assets/image-20200509092840718.png)]
xml方式实现配置监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--配置监听器-->
<listener>
<listener-class>com.itheima.listener.MyServletContextListener</listener-class>
</listener>
</web-app>
小结
-
理解监听器是什么
服务器通过监听器捕捉域对象的变化,让开发人员在对应的时间点进行业务逻辑控制
-
理解创建监听器的步骤
1、实现监听器接口
2、重写监听器的方法
3、注解或xml配置监听器类
-
上下文域对象监听器ServletContextListener可以获取什么时间点?
获取上下文域对象创建与销毁的时间点
03.监听器:ServletContextListener的作用【应用】
目标
掌握ServletContextListener的作用
作用
package _02_ServletContextListener监听器的作用;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author 黑马程序员
*/
@WebListener
public class MyServletContextListener2 implements ServletContextListener {
//上下文域对象创建时候触发的方法
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
/*
* ServletContextListener作用:
* 说明:由于上下文域对象的创建是开发人员获取服务器启动时刻最早一个时间点,可以有如下2个操作
* 1、服务器启动最早的时候加载解析外部配置文件【重要】
* 以后学习springmvc框架,就是通过这个监听器加载spring框架的配置文件
* 2、在服务器启动最早的时候开启定时任务
* 例如:每天更新网站的天气预报数据,这是定时任务,要每天定时获取气象局接口的数据
* */
/*
* 介绍:java的定时器
* 类似js的setInterval(任务代码,间隔毫秒数):循环指定间隔毫秒数执行任务代码
* */
//1、创建定时器类Timer
Timer timer = new Timer();
//2、制订定时任务
//timer.schedule(TimerTask timerTask,long d1,long d2);
// timerTask:执行任务的接口
// d1:距离第一次执行任务的毫秒数
// d2:间隔执行任务的毫秒数
//任务:每3秒执行一次输出hello world
timer.schedule(new TimerTask() {
@Override
public void run() {
//执行任务代码
System.out.println("hello world");
}
},0,3000);
}
//上下文域对象销毁前触发的方法
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
小结
ServletContextListener的作用
1、在服务器启动的时候加载外部配置文件
2、在服务器启动的时候开启定时器
注意:只要是向获取服务器最早时间做任务代码就可以实现这个监听器
04.监听器:ServletContextAttributeListener 介绍【理解】
目标
理解ServletContextAttributeListener 的使用
ServletContextAttributeListener 介绍
对servletContext域对象里面的数据进行监听,当里面数据增、删、改的时候会触发监听器对应的方法运行
ServletContextAttributeListener 作用
监听域对象里面数据的改变
ServletContextAttributeListener 接口方法中的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8pqIBZDA-1606227154468)(assets/image-20191226094206262.png)]
ServletContextAttributeEvent 对象中的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ubalqtGJ-1606227154470)(assets/image-20191226094450065.png)]
案例需求
1、创建一个Servlet资源,在资源里面键上下文域对象的增加数据、修改数据、删除数据操作
2、创建MyServletContextAttributeListener类实现ServletContextAttributeListener接口,监听上下文域数据的变化,在数据变化的时候打印变化的内容
案例效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D7EY6iqI-1606227154473)(assets/image-20200509102624656.png)]
代码
资源Servlet代码
package _03_实现监听上下文域对象数据的变化;
import javax.servlet.ServletContext;
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;
/**
* @author 黑马程序员
*/
@WebServlet(name = "DemoServlet", urlPatterns = "/DemoServlet")
public class DemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取上下文域对象
ServletContext servletContext = getServletContext();
//增加数据
servletContext.setAttribute("username","admin");
//修改数据
servletContext.setAttribute("username","admin2");
//删除数据
servletContext.removeAttribute("username");
}
}
监听器代码
package _03_实现监听上下文域对象数据的变化;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
/**
* @author 黑马程序员
*/
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
//当前上下文域对象添加数据的时候触发
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
//获取添加数据的key
String name = scae.getName();
//获取添加数据的value
String value = (String) scae.getValue();
System.out.println("新增属性名:"+name+",新增属性值:"+value);
}
//当前上下文域对象修改数据的时候触发
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
//获取修改数据的key
String name = scae.getName();
//获取修改前数据的value
String value = (String) scae.getValue();
//获取修改后数据的value
String value2 = (String) scae.getServletContext().getAttribute(name);
System.out.println("修改属性名:"+name+",修改前属性值:"+value+",修改后属性值:"+value2);
}
//当前上下文域对象删除数据的时候触发
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
//获取删除数据的key
String name = scae.getName();
//获取删除前数据的value
String value = (String) scae.getValue();
System.out.println("删除属性名:"+name+",删除前属性值:"+value);
}
}
小结
ServletContextAttributeListener的作用
监听上下文域对象里面的数据的变化
05.查询联系人:Dao层和Service层【应用】
目标
-
搭建MVC和三层架构
-
编写数据访问层和业务层
案例需求
使用三层架构和MVC模式开发代码,完成用户显示列表功能
案例效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q9PgVH7k-1606227154474)(assets/image-20200508173252422.png)]
搭建环境
导入jar包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IF41OnTm-1606227154475)(assets/image-20200430111456949.png)]
搭建MVC+三层架构包结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NlORvift-1606227154476)(assets/image-20200509103438763.png)]
实体类
package com.itheima.entity;
/**
* @author 黑马程序员
*/
public class Contact {
private int id; //编号
private String name; //姓名
private String sex; //性别
private int age; //年龄
private String address; //籍贯
private String qq; //QQ
private String email; //邮箱
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 Contact() {
}
@Override
public String toString() {
return "Contact{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", address='" + address + '\'' +
", qq='" + qq + '\'' +
", 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;
}
}
编写DAO模拟存储数据集合
package com.itheima.dao;
import com.itheima.entity.Contact;
import java.util.ArrayList;
import java.util.List;
/**
* @author 黑马程序员
*/
public class ContactDao {
//1、定义存储数据的集合
private static List<Contact> contactList;
//定义自增的变量,便于操作编号
private static int index = 0;
//2、通过静态代码块初始化
static{
contactList = new ArrayList<>();
//添加数据
contactList.add(new Contact(++index,"猪八戒","男",25,"广东","34567890","346789@qq.com"));
contactList.add(new Contact(++index,"貂蝉","女",18,"湖南","34567890","346789@qq.com"));
contactList.add(new Contact(++index,"孙悟空","男",28,"湖南","34567890","346789@qq.com"));
contactList.add(new Contact(++index,"周瑜","男",25,"广西","34567890","346789@qq.com"));
}
}
导入页面素材
素材
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R7oMDmfJ-1606227154477)(assets/image-20200509104354383.png)]
导入到项目web目录下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G6aiJ6k4-1606227154478)(assets/image-20200509104446664.png)]
Dao层代码编写
获取联系人列表数据返回
//获取联系人列表数据返回
public List<Contact> findAll(){
return contactList;
}
编写业务层代码
package com.itheima.service;
import com.itheima.dao.ContactDao;
import com.itheima.entity.Contact;
import java.util.List;
/**
* @author 黑马程序员
*/
public class ContactService {
//依赖Dao,实例Dao
private ContactDao contactDao = new ContactDao();
//获取联系人列表数据
public List<Contact> findAll(){
//调用dao获取数据
return contactDao.findAll();
}
}
小结
- 创建实体类,生成构造方法
- 创建DAO的类,所有的数据放在集合中
- 创建业务类,调用了DAO类
06.查询联系人:Web层【应用】
目标
-
使用Servlet来调用业务层,得到所有的联系人
-
在JSP上使用JSTL显示请求域中数据
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T27fY4Ea-1606227154479)(assets/image-20191121175550546.png)]
步骤
Servlet代码
package com.itheima.web.servlet;
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;
/**
* @author 黑马程序员
*/
@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 {
/*
* 目标:查询联系人列表数据并跳转到list.jsp页面显示数据
* */
//1、调用service获取联系人列表数据
List<Contact> contactList = contactService.findAll();
//2、存储到请求域中
request.setAttribute("contactList",contactList);
//3、使用请求转发跳转到list.jsp页面显示数据
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
list.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>查询所有联系人</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<style type="text/css">
tr,th {
text-align: center;
}
.col-md-4{
padding-right:0px;
padding-left:0px;
}
</style>
</head>
<body>
<div class="container">
<h3 align="center">联系人管理</h3><br>
<form action="list" method="get" class="form-inline" id="contactForm">
<div class="row text-right" style="margin-bottom: 10px; margin-top: 15px;">
<div class="col-md-4 text-left">
<a class="btn btn-primary" style="width: 120px" href="add.jsp">添加联系人</a>
</div>
</div>
<div class="row">
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<%--使用jstl的forEach标签展现域对象存储的数据集合:contactList--%>
<c:forEach items="${contactList}" var="contact">
<tr>
<td>${contact.id}</td>
<td>${contact.name}</td>
<td>${contact.sex}</td>
<td>${contact.age}</td>
<td>${contact.address}</td>
<td>${contact.qq}</td>
<td>${contact.email}</td>
<td>
<div class="btn-group btn-group-sm">
<a class="btn btn-success btn-xs" href="#">修改</a>
<a class="btn btn-info btn-xs" href="#">删除</a>
</div>
</td>
</tr>
</c:forEach>
</table>
</div>
</form>
</div>
</body>
<script type="text/javascript">
</script>
</html>
小结
查询所有的联系人在JSP上使用JSTL+EL显示请求域中联系人列表
07.添加联系人:DAO层和Service层【应用】
目标
实现联系人的添加
请求添加页面,填写数据,点击提交将用户输入的数据添加到Dao的数据集合里面
实现步骤分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bgKnzIkG-1606227154481)(assets/image-20200509111555829.png)]
DAO层
//添加联系人数据的方法
public void add(Contact contact){
//设置新的contact联系人的id属性递增
contact.setId(++index);
//操作contactList集合添加contact数据
contactList.add(contact);
}
业务层
//添加联系人数据的业务方法
public void addContact(Contact contact){
//调用dao的add方法添加contact数据
contactDao.add(contact);
}
08.添加联系人:Web层【应用】
目标
- 编码的过滤器
- Servlet
效果
点击添加联系人
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XVpkAFVG-1606227154482)(assets/image-20200509114309267.png)]
输入数据提交
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYSneTeI-1606227154483)(assets/image-20200509114400829.png)]
添加后效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7S4yMgLH-1606227154484)(assets/image-20200509114238732.png)]
编码过滤器【素材导入使用】
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dyjte1r4-1606227154485)(assets/image-20200509112454783.png)]
package com.itheima.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author 黑马程序员
*/
@WebFilter(filterName = "EncodingFilter",urlPatterns = "/*")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//0.将转成子接口才有这个方法
HttpServletRequest request = (HttpServletRequest) req;
//1.判断是否是POST方法,注:这里是大写
if (request.getMethod().equals("POST")) {
//2.如果是才进行编码
request.setCharacterEncoding("utf-8");
}
//3.无论是否是POST方法都要放行
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
实现分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ypILfXp5-1606227154486)(assets/image-20200509114012734.png)]
AddContactServlet
package com.itheima.web.servlet;
import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import org.apache.commons.beanutils.BeanUtils;
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.lang.reflect.InvocationTargetException;
import java.util.Map;
/**
* @author 黑马程序员
*/
@WebServlet(name = "AddContactServlet", urlPatterns = "/AddContactServlet")
public class AddContactServlet 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 {
try {
//1、获取添加联系人表单数据封装到Contact对象中
//BeanUtils.populate(javaBean,Map集合); 将Map集合的key与value数据封装到javaBean对象中
//创建Contact对象
Contact contact = new Contact();
//获取表单提交的Map集合数据
Map<String, String[]> map = request.getParameterMap();
//使用BeanUtils封装contact对象
BeanUtils.populate(contact,map);//注意:contact的属性名与map集合中key的名字要一样才可以封装
//2、调用业务层进行添加操作
contactService.addContact(contact);
//3、重新提交查询联系人请求(请求ListContactServlet),达到刷新联系人列表的目标
//注意:在后端跳转页面就是请求资源,由于没有使用请求域对象,所以这里使用重定向请求资源
response.sendRedirect(request.getContextPath()+"/ListContactServlet");
} catch (Exception e) {
e.printStackTrace(); //让开发人看到错误
//通知浏览器服务器出错了
throw new RuntimeException(e);
}
}
}
add.jsp代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I2RJN3Us-1606227154487)(assets/image-20200509114110991.png)]
小结
添加联系人的注意事项:
- 汉字乱码使用过滤器
- 表单中数据复制成contact对象,使用工具BeanUtils.populate()方法
- 添加成功以后跳转到list的Servlet显示数据
09.修改联系人:数据回显DAO和Service层【应用】
目标
实现修改数据的数据回显:在list.jsp联系人列表数据上,点击修改进入修改详情页面,并且展现要修改的数据
后端获取数据展现到修改页面实现分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zts9hoRp-1606227154488)(assets/image-20200509120101569.png)]
结论:
新数据(后端没有): 由前端输入提交后端保存
旧数据(后端有):从后端获取到前端显示
实现步骤
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NHId4YOc-1606227154489)(assets/image-20200509141943225.png)]
代码
ContactDAO代码
//根据编号查找联系人数据
public Contact findById(int id){
//目标:遍历联系人列表集合,对比每个联系人的id,返回符合的数据
//1.判断联系人列表集合是否有元素
if(contactList.size()>0) {
//2、有元素遍历集合
for (Contact contact : contactList) {
//3、对比每个联系人的id与传入的id,一样就说明是要查找的联系人对象并返回
if(contact.getId()==id){
return contact;
}
}
}
//4、查找不到返回null
return null;
}
ContactService
//根据编号查找联系人数据
public Contact findById(int id){
//调用dao获取数据
return contactDao.findById(id);
}
小结
- 写了DAO,通过id来查询1个用户
- 业务层调用了DAO的方法
10.修改联系人:数据回显Web层【应用】
目标
-
list.jsp链接的修改
-
更新页面的数据回显
实现分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EecpRX3D-1606227154490)(assets/image-20200509150304598.png)]
代码
FindContactServlet代码
package com.itheima.web.servlet;
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;
/**
* @author 黑马程序员
*/
@WebServlet(name = "FindContactServlet", urlPatterns = "/FindContactServlet")
public class FindContactServlet 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、获取请求数据的联系人编号
int id = Integer.parseInt(request.getParameter("id"));
//2、根据联系人编号调用业务查找联系人数据
Contact contact = contactService.findById(id);
//3、将联系人数据存储到请求域
request.setAttribute("contact",contact);
//页面上还需要地址列表数据,暂时模拟地址数据
String[] addresses = {"广东","湖南","广西","河北","黑龙江","陕西"};
request.setAttribute("addresses",addresses);
//4、跳转到update.jsp页面展现要修改的数据
request.getRequestDispatcher("/update.jsp").forward(request,response);
}
}
list.jsp代码的修改: 点击修改超链接提交请求给FindContactServlet,并传递id参数
<a class="btn btn-success btn-xs" href="${pageContext.request.contextPath}/FindContactServlet?id=${contact.id}">修改</a>
update.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>修改用户</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery-2.1.0.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" style="width: 400px;">
<h3 style="text-align: center;">修改联系人</h3>
<form action="/day05/update" method="post">
<div class="form-group">
<label for="name">姓名:</label>
<input type="text" class="form-control" id="name" name="name" value="${contact.name}" readonly="readonly" placeholder="请输入姓名" />
</div>
<div class="form-group">
<label>性别:</label>
<input type="radio" name="sex" value="男" ${contact.sex=='男'?'checked="checked"':''} />男
<input type="radio" name="sex" value="女" ${contact.sex=='女'?'checked="checked"':''} />女
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="text" class="form-control" id="age" name="age" value="${contact.age}" placeholder="请输入年龄" />
</div>
<div class="form-group">
<label for="address">籍贯:</label>
<select name="address" class="form-control" >
<c:forEach items="${addresses}" var="address">
<option value="${address}" ${contact.address==address?'selected="selected"':''}>${address}</option>
</c:forEach>
</select>
</div>
<div class="form-group">
<label for="qq">QQ:</label><%--label标签:用于与表单项元素绑定,当label的for="表单项元素的id值"时,效果为:点击label绑定表单项就会获取焦点--%>
<input type="text" class="form-control" id="qq" name="qq" value="${contact.qq}" placeholder="请输入QQ号码"/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" name="email" value="${contact.email}" placeholder="请输入邮箱地址"/>
</div>
<div class="form-group" style="text-align: center">
<input class="btn btn-primary" type="submit" value="提交" />
<input class="btn btn-default" type="reset" value="重置" />
<input class="btn btn-default" type="button" value="返回"/>
</div>
</form>
</div>
</body>
</html>
小结
使用EL表达式从请求域中取出联系人的属性显示
- 性别是单选:${contact.sex==“男”?‘checked=“checked”’:’’}
- 下拉列表处理
<%--从数组中取出每个省份显示--%>
<c:forEach items="${addresses}" var="address">
<%--如果数组中省份名字等于当前联系人的省份就选中--%>
<option value="${address}" ${contact.address==address?'selected="selected"':''}>${address}</option>
</c:forEach>
11.修改联系人:更新操作【应用】
目标
将用户修改后的信息写入数据库
实现分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FMRnn3LW-1606227154491)(assets/image-20200509153413988.png)]
代码
ContactDAO代码
//根据修改的Contact对象修改联系人数据
public void update(Contact contact){
//1、判断内存集合contactList是否有元素
if(contactList.size()>0) {
//2、有元素遍历集合每个元素
for (int i = 0; i < contactList.size() ; i++) {
//3、对比集合中每个元素的id与要修改联系人contact的id
if(contactList.get(i).getId()==contact.getId()) {
//4、 如果id一样,将要修改contact数据更新到集合中覆盖已有contact;
//语法:contactList.set(int index,Contact contact);
//含义:更新覆盖指定位置元素数据
contactList.set(i,contact);
return ; //更新结束
}
}
}
}
ContactService
//根据修改的Contact对象修改联系人数据
public void updateContact(Contact contact){
//调用dao修改联系人数据
contactDao.update(contact);
}
UpdateContactServlet
package com.itheima.web.servlet;
import com.itheima.entity.Contact;
import com.itheima.service.ContactService;
import org.apache.commons.beanutils.BeanUtils;
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.lang.reflect.InvocationTargetException;
import java.util.Map;
/**
* @author 黑马程序员
*/
@WebServlet(name = "UpdateContactServlet", urlPatterns = "/UpdateContactServlet")
public class UpdateContactServlet 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 {
try {
//1、获取修改数据封装到Contact对象中
//创建Contact对象
Contact contact = new Contact();
//获取表单所有有数据Map集合
Map<String, String[]> map = request.getParameterMap();
//使用BeanUtils封装
BeanUtils.populate(contact,map);
//2、调用业务层修改联系人数据
contactService.updateContact(contact);
//3、修改后从新提交查询联系人列表请求,达到刷新联系人列表数据目标
response.sendRedirect(request.getContextPath()+"/ListContactServlet");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);//抛出的目的,通知用户发生错误了
}
}
}
update.jsp代码
<form action="${pageContext.request.contextPath}/UpdateContactServlet" method="post">
<%--表单元素上加一个隐藏域用于传递id给后端(浏览器用户不看,后端要获取)--%>
<input type="hidden" name="id" value="${contact.id}">
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DcAdMlvX-1606227154492)(assets/image-20200509153239177.png)]
小结
- 更新页面上必须有一个id的值传递,使用隐藏表单域
- DAO更新联系人
- 业务层调用DAO
- Servlet
-
得到用户提交的参数
-
调用业务层
-
显示不同的页面给用户
-
12.通过ID删除联系人【应用】
目标
- 实现联系人的删除
- 删除前有确认
实现步骤
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJiJvnVD-1606227154494)(assets/image-20200509160314194.png)]
DAO层
//根据id删除联系人数据
public void del(int id){
//1.判断内存集合contactList是否有元素
if(contactList.size()>0) {
//2.遍历集合每个元素
for (Contact contact : contactList) {
//3.对比每个元素的id与要删除的id是否一样
if(contact.getId() == id) {
//4.如果一样,进行删除元素数据
contactList.remove(contact);
return ;
}
}
}
}
业务层
//业务根据id删除联系人数据
public void delContact(int id){
//调用dao根据id删除联系人
contactDao.del(id);
}
DelContactServlet
package com.itheima.web.servlet;
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;
/**
* @author 黑马程序员
*/
@WebServlet(name = "DelContactServlet", urlPatterns = "/DelContactServlet")
public class DelContactServlet 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.获取请求数据要删除联系人的id数据
int id = Integer.parseInt(request.getParameter("id"));
//2.调用业务根据id删除联系人数据
contactService.delContact(id);
//3.重新提交查询联系人列表请求,刷新联系人列表
response.sendRedirect(request.getContextPath()+"/ListContactServlet");
}
}
list.jsp
<div class="btn-group btn-group-sm">
<a class="btn btn-success btn-xs" href="${pageContext.request.contextPath}/FindContactServlet?id=${contact.id}">修改</a>
<%--<a class="btn btn-info btn-xs" href="${pageContext.request.contextPath}/DelContactServlet?id=${contact.id}">删除</a>--%>
<%--需求升级:点击删除,首先弹出确认提示框,确认后再提交删除请求
实现分析:给删除超链接注册点击事件,里面使用js代码confirm()确认提示框提示操作
超链接注册点击事件有2种方式:
方式1:<a onlick="js代码">xx</a> 缺点:鼠标移动在超链接上的时候没有手指效果
方式2:<a href="javascript:js代码">xx</a> 优点:由于有href属性,当鼠标移动到超链接上的时候有手指效果
--%>
<a class="btn btn-info btn-xs" href="javascript:onDelContact(${contact.id})">删除</a>
</div>
点击删除事件js代码
<script type="text/javascript">
//注意:最好将js代码写到forEach标签外边,这样不会循环多次js代码
//点击删除的点击事件
function onDelContact(id) {
//1.弹出确认提示框
if(confirm("您确认要删除当前行数据吗?")) {
//2.确认后提交删除请求
location.href="${pageContext.request.contextPath}/DelContactServlet?id="+id;
}
}
</script>
截图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSwPasOv-1606227154495)(assets/image-20200509160250480.png)]
13.session的钝化与激活【扩展】
目标
理解服务器正常关闭与重启session数据不会丢失
session钝化介绍
session激活介绍
实现前提
需求
效果
服务器关闭产生了session数据的钝化的文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8RqGyikV-1606227154496)(assets/1566204508300.png)]
运行startup.bat启动服务器,进行反序列化操作,钝化文件消失,session数据恢复到了内存中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ef46rMRC-1606227154497)(assets/1566204615778.png)]
实现步骤
实现代码
小结
14.总结
-
能够配置ServletContextListener
监听器含义:服务器对三大域对象改变的监听
ServletContextListener作用:可以监听到上下文域对象的创建与销毁
开发监听器的步骤:
1、创建类实现监听器接口ServletContextListener
2、重写监听器里面的方法
3、配置注解@WebListener
-
能够理解ServletContextListener的作用
说明:这个监听器是开发人员获取服务器启动最早的时间点,只要是最早执行的任务的代码都可以放在这里
1、加载解析非系统的配置文件
2、开启定时器
-
能够使用mvc及三层实现用户的列表查询操作
-
能够使用mvc及三层实现用户的新增操作
-
能够使用mvc及三层实现用户的修改操作
-
能够使用mvc及三层实现用户的删除操作
这些案例多练习,后面还有很多案例,尽量多敲多思考就可以
单词
单词 | 含义 | 音标 |
---|---|---|
listener | 监听 | /ˈlɪsənər/ |
label | 标签 | /ˈleɪbl/ |
populate | 构造,居住于 | /ˈpɑːpjuleɪt/ |
hidden | 隐藏 | /'hɪdn/ |
pt">
//注意:最好将js代码写到forEach标签外边,这样不会循环多次js代码
//点击删除的点击事件
function onDelContact(id) {
//1.弹出确认提示框
if(confirm(“您确认要删除当前行数据吗?”)) {
//2.确认后提交删除请求
location.href="${pageContext.request.contextPath}/DelContactServlet?id="+id;
}
}
截图
[外链图片转存中...(img-oSwPasOv-1606227154495)]
## 13.session的钝化与激活【扩展】
### 目标
理解服务器正常关闭与重启session数据不会丢失
### session钝化介绍
### session激活介绍
### 实现前提
### 需求
### 效果
服务器关闭产生了session数据的钝化的文件
[外链图片转存中...(img-8RqGyikV-1606227154496)]
运行startup.bat启动服务器,进行反序列化操作,钝化文件消失,session数据恢复到了内存中
[外链图片转存中...(img-ef46rMRC-1606227154497)]
### 实现步骤
### 实现代码
### 小结
## 14.总结
1. 能够配置ServletContextListener
> 监听器含义:服务器对三大域对象改变的监听
>
> ServletContextListener作用:可以监听到上下文域对象的创建与销毁
>
> 开发监听器的步骤:
>
> 1、创建类实现监听器接口ServletContextListener
>
> 2、重写监听器里面的方法
>
> 3、配置注解@WebListener
2. 能够理解ServletContextListener的作用
> 说明:这个监听器是开发人员获取服务器启动最早的时间点,只要是最早执行的任务的代码都可以放在这里
>
> 1、加载解析非系统的配置文件
>
> 2、开启定时器
>
>
3. 能够使用mvc及三层实现用户的列表查询操作
4. 能够使用mvc及三层实现用户的新增操作
5. 能够使用mvc及三层实现用户的修改操作
6. 能够使用mvc及三层实现用户的删除操作
> 这些案例多练习,后面还有很多案例,尽量多敲多思考就可以
单词
| 单词 | 含义 | 音标 |
| -------- | ------------ | ------------- |
| listener | 监听 | /ˈlɪsənər/ |
| label | 标签 | /ˈleɪbl/ |
| populate | 构造,居住于 | /ˈpɑːpjuleɪt/ |
| hidden | 隐藏 | /'hɪdn/ |