前言
第一次发理论技术类文章,可能写的不是很完善,还请各位看客多多指点。
本文内容一万余字,以HTTP协议内容与Servlet API接口为中心,图文并茂地发散讲解Java Web中各项重要技术如Cookie、JSP、JDBC、Filter过滤器等。实乃小白入门、期末恶补的好助手。
本文以理论基础为重点,内容大纲取自于狂神说Java Web,文章中的相关实验也在该视频教材中。时间充裕的话,建议跟随视频手撕一遍代码,加深理解。
---再小的帆,也能远航!
(一)介绍
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个Java初学web的人来说,它是最佳的选择
(二)Tomcat启动
(三)Tomcat配置
可以配置启动的端口号
可以配置主机的名称
(一)什么是HTTP
HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。
HTTP协议
(二)工作流程
(三)特点(无连接的,无状态的)
(四)HTTP1.0与HTTP1.1区别
(五)HTTPS(安全性)与HTTP的差异
概述:HTTPS采用了DH和SSL等加密算法实现对HTTP报文的加密传输,实现数据的安全性
HTTPS工作在TCP协议443端口,它的工作流程一般如以下方式:
1) 完成TCP三次同步握手
2) 客户端验证服务器数字证书
3) DH算法协商对称加密算法的密钥、hash算法的密钥
4) SSL安全加密隧道协商完成
5)网页以加密的方式传输,用协商的对称加密算法和密钥加密保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改
(七)其他信息
1、常见状态码
2、HTTP请求与相应
(1)请求头
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
(2)响应头
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;
(八)网站是如何进行访问
谈谈网站是如何进行访问的
1、输入一个域名(域名系统)
2、检查本机的 C:\Windows\System32\drivers\etc\hosts(本地域名服务器缓存)配置文件下有没有这个域名映射;
a、有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
b、没有:去DNS服务器找,找到的话(DNS域名服务器解析域名过程)就返回,找不到就返回404;
白话文概述:
首先分析一下一个域名结构,比如www.baidu.com,这域名实际上是一个层次结构,最后面的com是顶级域名,在后面的baidu是二级域名,www表示这个是个万维网站点,当然这个域名很短,其实后面还有三级域名等等。
然后这些域名会有相应的服务器,最上一层的服务器叫做根域名服务器,这个服务器指明这个域名应该向哪个顶级域名服务器的发送查询请求,而顶级域名服务器存储的是该顶级域名服务器下所有二级域名与ip地址的映射,再下面是权限域名服务器,这个服务器分布很广,它存储的是后续域名与ip地址的映射。再有一个是本地域名服务器,它是首个介绍到域名解析请求的服务器,它负责去向其他服务器发送解析域名请求,而不是让浏览器去负责解析请求。
了解完这些,接下来就是域名与ip地址的映射流程。主要分两种方式,一种是迭代,每次解析都由本地服务器去请求,一种是递归,由本地域名发送请求后,再由根域名服务器访问后续顶级域名服务器,顶级域名服务器在向下进行请求,依次一直查询,返回就是按原路返回。这里我们讲讲迭代的方式。首先浏览器发起一个域名的请求,它会想发送至本地域名服务器,本地域名服务器再向根域名服务器发起请求,根域名服务器将相对应的顶级域名服务器发送给本地域名服务器,本地域名服务器再向这个顶级域名服务器发请求,顶级域名服务器再返回相应权限域名服务器的,依次一直迭代,如果查询到了IP,本地域名服务器就将其返回给浏览器,否则就404。
找到了IP地址就可以建立TCP连接了,然后再使用HTTP协议传送一些万维网的文档。
我为什么要学习这个技术?
在Javaweb开发中,需要使用大量的jar包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。
由此,Maven诞生了!
(一)Maven项目架构管理工具
Maven是一个项目架构管理工具
我们目前用来就是方便导入jar包的!
Maven的核心思想:约定大于配置
有约束,不要去违反。
Maven会规定好你该如何去编写我们的Java代码,必须要按照这个规范来;
(二)pom文件
pom.xml 是Maven的核心配置文件
maven由于他的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
src/main/resources
**/*.properties
**/*.xml
true
src/main/java
**/*.properties
**/*.xml
true
(三)Maven中jar包联系关系图
(四)Maven仓库使用
地址:https://mvnrepository.com/
(一)Servlet简介
编写一个普通类
实现Servlet接口,这里我们直接继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter(); //响应流
writer.print("Hello,Serlvet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、编写Servlet的映射
hello
com.kuang.servlet.HelloServlet
hello
/hello
4、配置Tomcat,启动
(三)Servlet原理
1、Servlet是由Web服务器(Tomcat)调用WEB服务器在接收到浏览器的请求后,如果是首次访问,就会创建一个Servlet的class文件,此后直接调用这个class文件即可,这就是为什么Servlet项目在首次比较慢,后面比较快的原因。
2、同时WEB服务器还会产生两个东对象,一个是请求,一个是响应,这两个对象会被Servlet接口中的方法调用,而这个方法是被我们重写的,于是请求和响应也就被我们接管处理,我们直接根据自己的要求完成相应功能即可。
(四)ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它是一个全局性文件,它代表了当前的web应用;
1、共享数据
我在这个Servlet中保存的数据,可以在另外一个servlet中拿到,这里说的另一个servlet指的是另一个实现了servlet接口的类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter() 初始化参数
//this.getServletConfig() Servlet配置
//this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String username = "秦疆"; //数据
context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、获取初始化参数
url
jdbc:mysql://localhost:3306/mybatis
(五)读取资源文件
Properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:
思路:需要一个文件流;
(六)HttpServletRequest与HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
如果要获取客户端请求过来的参数:找HttpServletRequest
如果要给客户端响应一些信息:找HttpServletResponse
1、HttpServletRequest
(1) HttpServletRequest代表客户端的请求
(2)HttpServletRequest存储页面间传递的数据
Jsp-Servlet常见 两种 页面间传递数据方式(request转发和session)
①request转发(麻烦):一次request转发只适合,两个页面间传值(一次传值)。俗称:一次request转发 :【一个转发链】
②session(推荐):使用session比较简单。在小项目,需要创建的session不多,服务器压力不大时,平时推荐用session。除非特殊需求。
@RequestMapping("/getRequestDispatcher")
public void getRequestDispatcher(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("user", "李四");
request.getRequestDispatcher("/WEB-INF/views/welcome.jsp").forward(request, response);
}
2、HttpServletResponse
(1)响应的方法
i.负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
ii.负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);//编码方式
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);//响应体类型
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);//设置响应头
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
iii.实现重定向
void sendRedirect(String var1) throws IOException;
(七)重定向和转发的区别
相同点
页面都会实现跳转
不同点
转发:当使用转发时,servlet会调用内部的一个方法完成请求处理和转发动作,首次请求和后续的转发动作都是在同一个请求里面完成的。于是在浏览器地址栏显示的仍然是第一次访问的地址,它对本次动作并不知情。
重定向:当使用重定向时,servlet会将这页面跳转的请求响应给浏览器,让浏览器去亲自发送请求,于是浏览器的地址栏里的地址时会发生变化的。
(一)会话、Cookie与Session
会话可以简单理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
会话需要解决的问题:
每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每一个用户的数据。
例如:用户点击超链接通过一个servlet购买了一个商品,程序应该保存用户购买的商品,以便于用户点结账servlet时,结账 servlet可以得到用户商品为用户结账。
用户购买的商品保存在request或servletContext中行不行?
首先我们知道HTTP协议是无状态的,也就是说同一个浏览器对同一个服务器发送多次请求,得到的结果是一样的,也就是说服务器是不识别用户的。而有些时候我们的服务器是需要知道用户的信息的,比如我们在网上购物的时候,我们通常会将我们要买的东西放入购物车内,再一起买走。由于HTTP是无状态的,于是服务器根本无法记录我们到底往我们的购物车里放了啥,因此Cookie和Session技术就出现了。它们的作用就是识别和确认用户,解决HTTP的无状态情况。
1、Cookie
Cookie是客户端技术,cookie是小段文本信息,在网络服务器上生成,并发送给浏览器,在客户端上存储,且每次请求都会携带这些cookie。通过使用cookie可以标识用户身份,记录用户名和密码,跟踪重复用户等。
依旧是购物车的例子,当我们看上了一个商品,将它放入购物车后,服务器就会将这个商品信息封装在cookie中并返回给浏览器,往后每次放入购物车就会产生一个cookie,最后我们结账付款的时候,服务器就可以根据我们的这些cookie获取我们所有要购买的东西。
2、Session
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,并将其信息存储在服务器端,并且往客户端的发送一个保存了这个session id值的cookie。
再拿我们购物车的例子,当我们往购物车里放入我们想要的商品时,服务器就会根据浏览器传来的cookie获取该用户的session id,进而得到服务器端存储这个用户的session,于是服务器就在这个session中存储我们放入购物车的商品。最后我们结账的时候,直接根据用户session中的信息获取我们想购买的所有商品。
注:cookie原理中用户分别发送了三次请求(电视,手机,结账);上述原理图中最大的区分点在信息的存储位置(客户端or服务端)
管理HTTP协议会话状态 :Cookie 和Session
Cookie:将用户相关数据,保存客户端 , 用户每次访问服务器自动携带cookie数据 。
Session : 将用户相关数据,保存服务器端,为每个客户端生成一个独立Session数据对象,雅思周末班通过对象唯一编号,区分哪个浏览器对应哪个Session。
(二)Cookie技术
Cookie获得访问时间小结:
1、通过服务器向客户端写cookie
Cookie cookie=new Cookie(name,value);
response.addCookie(cookie);
在HTTP协议响应头信息中 Set-Cookie: last=1339556457609
2、当客户端存在cookie之后,以后每次请求自动携带 HTTP协议请求头信息 Cookie: last=1339556456859
服务器端获得需要cookie数据
Cookie[] cookies=request.getCookies(); //获得客户端所有cookie
if(cookies==null){} //判断cookie是否存在,遍历cookie获得需要信息
什么是会话cookie ,什么是持久cookie ?
(三)Session技术
session(推荐):使用session比较简单。在小项目,需要创建的session不多,服务器压力不大时,平时推荐用session。除非特殊需求。
(四)总结
1、cookie与session出现的原因是,http是无状态的,比如你用浏览器访问淘宝网登录了,按道理说,你就可以查看自己账号购物车里的宝贝列表了,但假设不用cookie与session等技术保存用户的信息,http是不知道你对淘宝网的多次请求是同一个人的。
2、cookie保存在客户端,也就是浏览器端。每次往服务器发请求,都会在请求头里带这些cookie,缺点显而易见,浪费流量、降低效率。
3、session将用户信息保存在服务端,只需要往客户端的cookie中保存一个session id值就可以了。这样每次往服务器发请求,cookie的size很小,在服务端只需要根据cookie传过来的seesion id进行匹配session,从session中获取用户信息就可以了。
(一)什么是JSP
Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术!
最大的特点:
(二)JSP原理
思路:JSP到底怎么执行的!
JSP最终也会被转换成为一个Java类!
JSP 本质上就是一个Servlet
(三)基本语法
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 1; i <=100 ; i++) {
sum+=i;
}
out.println("Sum="+sum+"
");
%>
(四)基本指令
<%@page args.... %>//用以设置页面的静态属性
<%@include file=""%>
<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
网页主体
<%@include file="common/footer.jsp"%>
<%--jSP标签
jsp:include:拼接页面,本质还是三个
--%>
网页主体
(五)九大内置对象
名称 | 对象 | 类型 | 作用域 |
---|---|---|---|
request | 请求对象 | ServletRequest | Request |
response | 响应对象 | SrvletResponse | Page |
pageContext | 页面上下文对象 | PageContext | Page |
session | 会话对象 | HttpSession | Session |
application | 应用程序对象 | ServletContext | Application |
out | 输出对象 | JspWriter | Page |
config | 配置对象 | ServletConfig | Page |
page | 页面对象 | Object | Page |
exception | 异常对象 | Throwable | Page |
pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","秦疆4号"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器
(六)JSTL标签与EL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!
JSTL是为弥补HTML标签不足而定义的具有语法功能的标签
EL表达式是为了使JSP写起来更加简单,它是一种脚本语言,允许通过JSP访问Java组件。
EL表达式: ${ }
<%--判断如果提交的用户名是管理员,则登录成功--%>
<%--自闭合标签--%>
(一)什么是JavaBean
JavaBean 是一种JAVA语言写成的可重用组件。
JavaBean符合一定规范编写的Java类,不是一种技术,而是一种规范。
JavaBean有特定的写法:
(二)与POJO与ENTITY的区别
1、POJO 简单的Java对象,实际就是普通JavaBeans,其中有一些属性及其getter、setter方法的类,没有业务逻辑,不允许有其他方法
2、ENTITY是一个实体类,对其理解众说风云,我的理解是:为与数据库表相适应而提出的一个Java实体类规范
(三)实体类的规范
(四)ORM
ORM:对象关系映射zd(Object Relational Mapping,简称ORM),目的是想像操作对象一样操作数据库.因为数据库不是面向对象的,所以需要编程进行映射,一般用来和数据库的字段做映射==>ORM
ORM :对象关系映射
people表
id | name | age | address |
---|---|---|---|
1 | 秦疆1号 | 3 | 西安 |
2 | 秦疆2号 | 18 | 西安 |
3 | 秦疆3号 | 100 | 西安 |
class People{
private int id;
private String name;
private int id;
private String address;
}
class A{
new People(1,"秦疆1号",3,"西安");
new People(2,"秦疆2号",3,"西安");
new People(3,"秦疆3号",3,"西安");
}
在早期java开发中,如果要使java连接数据库,就需要安装相应数据库的连接驱动,而各个不同的数据库的驱动实现是大不相同的,因此各数据库之间的差异很大,使得开发人对数据库的连接十分繁琐,因此JDBC应运而生,它统一了所有数据库的连接方式,各个数据库仅需要对JDBC提供相应的实现,而开发人员直接连接JDBC即可轻松地连接各种不同的数据库。
(一)JDBC是什么
JDBC(Java DataBase Connectivity),是一种用于执行SQL语句的Java 接口,由一组用Java语言编写的类和接口组成,是Java和数据库之间的一个桥梁,是一个规范而不是一个特定的实现,而由各个数据库提供相应的实现。
(二)建立JDBC和数据库之间的Connection连接
这里需要提供:数据库服务端的IP地址:127.0.0.1
数据库的端口号: 3306
数据库名称 DBName
编码方式 UTF-8
账号 root
密码 admin
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8", "root", "admin");
(三)创建Statement或者PreparedStatement接口,执行SQL语句
Statement接口创建之后,可以执行SQL语句,完成对数据库的增删改查。其中 ,增删改只需要改变SQL语句的内容就能完成,然而查询略显复杂。在Statement中使用字符串拼接的方式,该方式存在句法复杂,容易犯错等缺点,具体在下文中的对比中介绍。所以Statement在实际过程中使用的非常的少,所以具体的放到PreparedStatement那里给出详细代码。
Statement s = conn.createStatement();
// 准备sql语句
// 注意: 字符串要用单引号'
String sql = "insert into t_courses values(null,"+"'数学')";
//在statement中使用字符串拼接的方式,这种方式存在诸多问题
s.execute(sql);
System.out.println("执行插入语句成功");
与 Statement一样,PreparedStatement也是用来执行sql语句(含占位符)的与创建Statement不同的是,需要根据sql语句创建PreparedStatement。除此之外,还能够通过设置参数,指定相应的值,而不是Statement那样使用字符串拼接。
String sql = "insert into t_course(course_name) values(?)";
conn = DbUtil.getConnection();
pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setString(1, courseName); //给占位符赋值
pstmt.executeUpdate(); //执行
差异:
1、使用PreparedStatement时,是采用占位符的方式“?”在这里就起到占位符的作用。这种方式除了避免了statement拼接字符串的繁琐之外,每次SQL语句都是一样的,java类就不会再次编译,且这里的参数索引是从1开始的。
2、增删改都使用pstmt.executeUpdate();语句进行SQL语句的提交下文的查询。
3、 PreparedStatement接口提供了相应的批量操作的方法。
for(int i=1;i<100;i++){
pstmt.setInt(1,8000+i);
pstmt.setString(2,"赵_"+i);
pstmt.addBatch();
//批量更新
if(i%10==0){
pstmt.executeBatch();
}
PreparedStatement的优点:
1、其使用参数设置,可读性好,不易记错。在statement中使用字符串拼接,可读性和维护性比较差。
2、其具有预编译机制,性能比statement更快。
3、其能够有效防止SQL注入攻击。
(四)处理和显示结果
执行查询语句,并把结果集返回给集合ResultSet
ResultSet rs = s.executeQuery(sql);
利用While(ResultSet.next()){…}循环将集合ResultSet中的结果遍历出来。每个记录对应一个对象
while (rs.next()){
int courseId = rs.getInt("course_id");
String courseName = rs.getString("course_name");
//每个记录对应一个对象
Course course = new Course();
//在我的项目中创建了course类,其中定义了set方法,所以这里将查询到的值传给了course,也可以直接打印到控制台
course.setCourseId(courseId);
course.setCourseName(courseName);
//将对象放到集合中
courseList.add(course);
}
(五)释放资源
在JDBC编码的过程中我们创建了Connection、Statement、ResultSet等资源,这些资源在使用完毕之后是一定要进行关闭的。关闭的过程中遵循从里到外的原则。这里我将这些关闭的操作写成一个方法和建立连接的方法一起放到一份工具类中
public static void close(PreparedStatement pstmt){
if(pstmt != null){ //避免出现空指针异常
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
public static void close(Connection conn){
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public static void close(ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
(一)什么是MVC(早期框架)
MVC的全名是Model View Controller,分别表示是模型-视图-控制器,是一种软件设计典范。
它主要特点是是用采用分离 业务逻辑 、 数据 与 界面显示 的方式来组织代码。
各部分职责
Model
View
Controller (Servlet)
白话文概述:
首先我们面对的是MVC层中的View部分,也就是视图部分,它会给我们显示一些页面信息并提供一些功能的请求接口(a标签),当我需要执行某些功能时,就会点击这些接口,这些接口就会调用Controller层中的方法,接收我们提交的请求,并调用相应的Model层中业务代码,待Model中将业务处理好后,就会返回相应的数据给Controller,Controller再将这些数据返回给前端并进行页面跳转,于是我们就可以获得相应回来的信息了。
(一)介绍
Filter:过滤器 ,顾名思义,用来过滤网站的请求与数据;
通过在web.xml配置过滤器选择过滤的范围
实现Filter接口,重写对应的方法即可
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现!
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//Chain : 链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前....");
chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁:web服务器关闭的时候,过滤会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
3、在web.xml中配置 Filter
CharacterEncodingFilter
com.kuang.filter.CharacterEncodingFilter
CharacterEncodingFilter
/servlet/*
(一)介绍
监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
Servlet监听器(不需要配置,但是监听器仍需要进行注册)
在Servlet规范中定义了多种类型的监听器,ServletContextListener, HttpSessionListener 和 ServletRequestListener,它们用于监听的事件源为 ServletContext, HttpSession 和 ServletRequest 这三个域对象。
(二)创建案例(HttpSessionListener)
1、编写一个监听器,实现监听器的接口
//统计网站在线人数 : 统计session
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200520132401174.png)public class OnlineCountListener implements HttpSessionListener {
//创建session监听: 看你的一举一动
//一旦创建Session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁session监听
//一旦销毁Session就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
/*
Session销毁:
1. 手动销毁 getSession().invalidate();
2. 自动销毁
*/
}
2、web.xml中注册监听器
com.kuang.listener.OnlineCountListener
参考:
[1]【狂神说Java】JavaWeb入门到实战
[2] Cookie及通过Cookie常见应用
[3] JDBC详细介绍
[4] JSP九大内置对象
[5] 计算机网络(第7版)-谢希仁