🙈作者简介:练习时长两年半的Java up主
🙉个人主页:老茶icon
🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎
📚系列专栏:Java全栈,计算机系列(火速更新中)
💭 格言:种一棵树最好的时间是十年前,其次是现在
🏡动动小手,点个关注不迷路,感谢宝子们一键三连
目录
- 课程名:JavaWeb
- 内容/作用:知识点/设计/实验/作业/练习
- 学习:JavaWeb+JSP内置对象+Session+Cookie+ 过滤器Filter+ 监听器Listener(超详细)
- 内容:
- 续前章内容:在线图书商城
- 续前章内容:在线图书商城
- 带有外键关联的表的查询
- 表结构
- 实体类
- 数据访问层
- 方式一:定义连接查询的sql语句,适合关联字段比较少的情况
- 方式二:分别编写不同表的查询,使用子查询。
- JSP内置对象
- Session和Cookie
- session
- session共享数据的原理
- session对象常用方法
- 设置项目全局session有效时长
- cookie
- 创建cookie
- 保存cookie
- 遍历cookie
- session和cookie的对比
- 过滤器Filter
- 使用
- 监听器Listener
- 常用的监听器
- 实现一个监听器
- 完整代码
- 总结
课程名:JavaWeb
内容/作用:知识点/设计/实验/作业/练习
学习:JavaWeb+JSP内置对象+Session+Cookie+ 过滤器Filter+ 监听器Listener(超详细)
内容:
续前章内容:在线图书商城
续前章内容:在线图书商城
带有外键关联的表的查询
表结构
主表book_type
从表
实体类
主表
public class BookType{
private int typeId;
private String typeName;
}
从表
public class BookInfo {
private int bookId;
//外键
private int typeId;
private String bookName;
private String bookAuthor;
private int bookPrice;
private String publisher;
private String publishDate;
private int bookNum;
private String bookImg;
//额外添加一个属性:外键关联的表的实体对象
private BookType bt;
}
数据访问层
方式一:定义连接查询的sql语句,适合关联字段比较少的情况
BookInfoDao类
public class BookInfoDao{
private Connection conn;
private PreparedStatement pst;
private ResultSet rs;
/*
查询从表数据
*/
public List<BookInfo> queryAll() {
List<BookInfo> list = new ArrayList<>();
//定制连接查询的sql
String sql = "select bi.*,type_name from book_info bi,book_type bt where bi.type_id=bt.type_id";
conn = DBHelper.getConn();
try {
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
/*
1-9是bi.*表示从表中的数据
*/
int bookId = rs.getInt(1);
int typeId = rs.getInt(2);
int bookPrice = rs.getInt(5);
int bookNum = rs.getInt(8);
String bookName = rs.getString(3);
String bookAuthor = rs.getString(4);
String publisher = rs.getString(6);
String publishDate = rs.getString(7);
String bookImg = rs.getString(9);
//10是额外的主表中的数据type_name
String typeName= rs.getString(10);
//创建从表对象,不包含外键属性
BookInfo bookInfo = new BookInfo(bookId, typeId, bookName, bookAuthor, bookPrice, publisher, publishDate, bookNum, bookImg);
//给外键属性赋值
bookInfo.setBt(new BookType(typeId,typeName));
list.add(bookInfo);
}
} catch (SQLException e) {
System.out.println("查询所有异常" + e);
} finally {
DBHelper.release(conn, pst, rs);
}
return list;
}
}
方式二:分别编写不同表的查询,使用子查询。
BookTypeDao
public class BookTypeDao{
private Connection conn;
private PreparedStatement pst;
private ResultSet rs;
/*
根据类型编号查询类型对象
*/
public BookType findByTypeId(int typeId){
String sql = "select * from book_type where type_id=?";
conn = DBHelper.getConn();
try {
pst = conn.prepareStatement(sql);
pst.setInt(1,typeId);
rs = pst.executeQuery();
while (rs.next()) {
//返回查询到的图书类型对象
return new BookType(rs.getInt(1),rs.getString(2));
}catch (SQLException e) {
System.out.println("根据类型编号查询类型异常" + e);
} finally {
DBHelper.release(conn, pst, rs);
}
return null;
}
}
}
BookInfoDao
public class BookInfoDao{
private Connection conn;
private PreparedStatement pst;
private ResultSet rs;
//子查询时,需要用到另一个dao类中的方法
private BookTypeDao bookTypeDao = new BookTypeDao();
/*
查询从表数据
*/
public List<BookInfo> queryAll() {
List<BookInfo> list = new ArrayList<>();
//定制连接查询的sql
String sql = "select * from book_info";
conn = DBHelper.getConn();
try {
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
/*
1-9是bi.*表示从表中的数据
*/
int bookId = rs.getInt(1);
int typeId = rs.getInt(2);
int bookPrice = rs.getInt(5);
int bookNum = rs.getInt(8);
String bookName = rs.getString(3);
String bookAuthor = rs.getString(4);
String publisher = rs.getString(6);
String publishDate = rs.getString(7);
String bookImg = rs.getString(9);
//调用根据类型编号查询类型对象的方法
BookType bt= bookTypeDao.findByTypeId(typeId);
//创建从表实体对象
BookInfo bookInfo = new BookInfo(bookId, typeId, bookName, bookAuthor, bookPrice, publisher, publishDate, bookNum, bookImg);
//给外键属性赋值
bookInfo.setBt(bt);
list.add(bookInfo);
}
} catch (SQLException e) {
System.out.println("查询所有异常" + e);
} finally {
DBHelper.release(conn, pst, rs);
}
return list;
}
}
JSP内置对象
在JSP中,可以不用定义,就能直接使用的对象,称为内置对象。
一共有9个内置对象
“rrppsoace”
-
pageContext
作用域对象,当前页面作用域。
-
request
作用域对象,请求作用域。
-
session
作用域对象,会话作用域。
-
application
作用域对象,项目作用域。
-
response
响应对象
-
out
输出对象,相当于Servlet中的response.getWriter()方法的返回值对象
-
page
表示当前页面自身对象,相当于servlet中的this
-
config
配置对象,获取servlet的配置信息
-
exception
异常对象,只能使用在有isErrorPage="true"声明的jsp页面中,用于获取异常对象
Session和Cookie
session
session称为会话,是一个作用域,使用session.setAttribute()保存数据,使用session.getAttribute()获取数据。
默认session会话有效期为30分钟,可以更改,超时或关闭浏览器,session失效。
保存在session中的数据,可以在同一个站点下的不同页面中共享。
session共享数据的原理
-
访问任意JSP页面时,默认都会创建一个JSESSIONID(可以取消自动创建),是一段session编号,保存在一个cookie文件中
<%--所有jsp页面中,默认开启了session--%> <%@ page session="true"%> <%--让页面默认不使用session--%> <%@ page session="false"%>
自动生成的cookie文件信息,可以看出,随着浏览器关闭,session到期
- 再次访问该页面时,会查询JSESSIONID是否存在,如果存在,直接使用,如果不存在,重新创建新的JSESSIONID
- 保存该JSESSIONID的cookie文件,有效期为浏览会话结束。所以关闭浏览器,session失效
session对象常用方法
常用方法 | 说明 |
---|---|
getAttribute(String str) | 获取session中保存的数据,返回值为Object类型 |
setAttribute(String str,Object obj) | 将obj保存在session中,命名为str |
removeAttribute(String str) | 移除保存在session中的对象str |
invalidate() | 销毁session |
getId() | 获取JSESSIONID |
getMaxInactiveInterval() | 获取session有效时长,单位为秒,默认为1800 |
setMaxInactiveInterval(int second) | 设置session有效时长,单位为秒 |
getCreationTime() | 获取session创建时间,返回值为时间毫秒 |
getLastAccessedTime() | 获取最后一次访问session的时间,返回值为时间毫秒 |
设置项目全局session有效时长
在web.xml文件中设置,单位为分钟
<!--设置项目中所有session的有效时长,单位分钟-->
<session-config>
<session-timeout>5</session-timeout>
</session-config>
cookie
cookie是一个用于保存数据的对象,实际是一个保存在客户本地的文件。关闭浏览器,cookie依然存在。手动清理或自动超时清理后,数据随之消失。
cookie通常用于更久地保存数据,即便关闭浏览器,也能一直存在。如登录信息、购物车信息等
cookie中保存的数据有上限(4kb),
cookie在浏览器中保存的数量也有上限(30~300根据浏览器不同略有变化)。
创建cookie
//Cookie(String name,String value);
Cookie ck = new Cookie("str","hello");
//设置有效时长,单位为秒,如果不设置,关闭浏览器,cookie失效
ck.setMaxAge(7*24*3600);//7天
保存cookie
response.addCookie(ck);
遍历cookie
Cookie[] cks = request.getCookies();
for(Cookie ck : cks){
ck.getName();//获取name
ck.getValue();//获取value
}
session和cookie的对比
-
session中保存的数据可以是任意类型,没有大小限制;cookie中保存的是键值对,单个值大小上限为4kb
-
session中保存的数据存在服务器中,cookie中保存的数据存在浏览器中。
-
session到期或随着浏览器关闭而失效,cookie如果设置了有效时长,即使关闭浏览器也会存在,在到期或手动清理时失效
过滤器Filter
是一个特殊的servlet
使用
1.新建一个类,继承HttpFilter
2.重写doFilter()方法,设置过滤条件
package com.hqyj.book_shop.filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
* 自定义过滤器
* 1.创建一个类,继承HttpFilter
* 2.重写受保护的doFilter方法
* 3.配置过滤器
* */
public class MyFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
//获取当前访问的uri(地址)
String uri = req.getRequestURI();
System.out.println(uri + "访问过滤器");
//如果登录成功后,session会保存customer。
//过滤器中判断当前session中是否存在customer
if (req.getSession().getAttribute("customer") != null) {
chain.doFilter(req, res);
return;
}
//如果session中没有customer,只能放行登录、注册页及其相关静态资源和customer模块
if (uri.contains("html") || uri.contains("jquery")|| uri.contains("customer")) {
chain.doFilter(req, res);
}else{
//否则跳转登录页
res.sendRedirect("http://localhost:8080/book_shop/pages/login.html");
}
}
}
3.配置过滤器,过滤一切请求
<!--声明一个过滤器-->
<filter>
<!--过滤器名,无限制-->
<filter-name>myFilter</filter-name>
<!--过滤器类全限定名-->
<filter-class>com.hqyj.book_shop.filter.MyFilter</filter-class>
</filter>
<!--配置过滤器映射-->
<filter-mapping>
<!--过滤器名,与上方对应-->
<filter-name>myFilter</filter-name>
<!--过滤一切请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
监听器Listener
监听一些特殊的事件,当这些事件发生的时候,监听器的代码就会执行 作用:框架的加载和初始化, 记录日志。。。
常用的监听器
-
ServletContextListenser application监听器
-
HttpSessionListener session监听器
-
ServletRequestListenser request监听器
实现一个监听器
- 创建一个类,实现监听器接口
- 重写初始化和销毁的方法
- 在web.xml中配置监听器
<!-- 配置监听器-->
<listener>
<!-- 监听器的类名-->
<listener-class>com.hqyj.book_shop.listener.MyListener</listener-class>
</listener>
- 也可以通过注解的方式配置监听器: @WebListener
完整代码
package com.hqyj.book_shop.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MyListener implements ServletContextListener, HttpSessionListener,
ServletRequestListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("应用初始化:tomcat服务器启动时执行");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("应用销毁:tomcat停止时");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("请求结束:一个请求后台响应完成后执行");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("请求开始:发起请求时执行");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session创建:浏览器第一次发送请求时执行");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session销毁: 超时之后(或代码结束session)执行");
}
}
总结
好好学习,天天向上。
往期专栏 |
---|
Java全栈开发 |
数据结构与算法 |
计算机组成原理 |
操作系统 |
数据库系统 |
物联网控制原理与技术 |