个人主页:Hello Code.
本文专栏:《Java Web从入门到实战》
篇幅较长,并未完结,后续内容会持续更新
本文后续也会分篇发布,方便大家阅读
如没有Java基础,请先前往《Java零基础指南》专栏学习相应知识
如有问题,欢迎指正,一起学习~~
文章目录
Linux
初识LinuxLinux的安装和使用
VmwareSecureCRT目录和文件时间同步克隆与快照 系统与设置命令
账号管理用户组系统管理相关命令进程相关命令目录管理文件基本属性综合案例 文件管理
touchvi/vim编辑器文件查看echo命令awk命令软连接 压缩命令
查找命令gzip命令gunzip命令tar命令zip命令unzip命令bzip2命令 网络与磁盘管理
网络管理磁盘管理yumrpm shell
初识shell注释和变量数组运算符选择语句循环语句函数 Nginx
概述安装发布项目 JavaWeb核心
企业开发简介
JavaEE规范WEB概述系统结构 tomcat
服务器Tomcat基本使用Java WEB项目配置文件 HTTP协议
概述协议的请求协议的响应 发布资源案例
Servlet介绍 Servlet
概述执行过程实现方式生命周期线程安全问题映射方式创建时机默认Servlet ServletConfig
配置方式常用方法 ServletContext
域对象配置方式常用方法 注解开发
自动注解开发手动创建容器(了解) 学生管理系统1请求对象
获取各种路径获取请求头获取请求参数信息流对象获取请求信息中文乱码问题请求域请求转发请求包含 响应对象
常见状态码字节流响应消息字符流响应消息响应图片设置缓存定时刷新请求重定向文件下载 学生管理系统2cookie
会话概述cookie属性方法练习注意事项 Session
常用方法对象获取练习注意事项 JSP
快速入门执行过程语法指令注意事项MVC模型 学生管理系统3EL表达式
快速入门获取数据注意事项运算符隐式对象 JSTL
核心标签 Filter
概述FilterChain过滤器使用使用细节生命周期FilterConfig五种拦截行为 Listener
监听器监听器的使用 学生管理系统优化
解决乱码检查登录优化JSP页面 MYSQLJDBCMybatisJavascriptjQueryAJAXVue + ElementRedisMaven基础Web项目实战-黑马页面
Linux 初识Linux操作系统:管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石。
主流操作系统
桌面操作系统:Window系列、macOS、Linux服务器操作系统:Linux、Windows Server嵌入式操作系统:Linux移动设备操作系统:Unix(Linux、ios)
Linux发展历程
1984年Minix(只用于教学)1991年编写驱动程序,年底公开Linux内核源码1994年Linux1.0(Linus Torvalds)至此开始流行起来
Linux特点
Linux是一套免费使用和自由传播的类Unix操作系统是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统两个基本思想
一切都是文件每个软件都有确定的用途 完全兼容POSIX1.0标准多用户、多任务良好的界面支持多种平台
Linux与其它操作系统的区别
开源情况硬件适用本质不同系统界面驱动程序系统使用软件与支持
Windows更适用于家庭个人使用
Linux更适用于企业服务器使用
Linux发行商和常见发行版
Redhat公司--------Red Hat Linux(最著名的Linux版本、收费)-----免费的CentOSCentOS特点:主流、免费、更新方便 Linux的安装和使用
先安装虚拟机,再安装Centos
VmwareVmware简介
不需要分区或者重开机就能在同一台PC上使用两种以上的操作系统完全隔离并且保护不同操作系统的环境以及所有的软件、资料不同的操作系统之间还可以进行互动操作有复原功能能够设置并且随时修改操作系统的操作环境常见虚拟机软件:VMware workstation、VirtualBox
Vmware下载:https://www.vmware.com/cn.html
CentOS镜像下载:https://www.centos.org/download/
高速下载地址
http://mirrors.aliyun.comhttp://mirrors.sohu.comhttp://mirrors.163.comhttp://mirrors.cqu.edu.cn/CentOS SecureCRT
简介:SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录Unix或Linux服务器主机的软件。
目录和文件Linux没有盘符这个概念,只有一个根目录/,所有文件都在他下面etc表示系统中的配置文件usr、usr/bin、usr/sbin都表示系统预设执行文件的放置目录var/log表示程序运行日志的存放目录切换根目录:cd /查看目录内容:ls -l 时间同步
克隆与快照克隆:将原系统完完全全的拷贝一份,原系统丢失后克隆的系统还能正常使用
占用空间大原系统不存在,克隆体还能用
快照:记录系统当前状态,并不会把系统完整拷贝
占用空间小原系统不存在,快照也就无法使用
系统与设置命令 账号管理克隆和拍摄快照时都需要关闭虚拟机
与用户相关的命令,必须在管理员权限下才能执行
命令:su root
创建用户:useradd (选项) 用户名用户口令:passwd (选项) 用户名
密码不能是一个回文长度必须大于8位必须是字母和数字的结合
在root权限下切换其它用户可直接切换,无需输入密码
修改用户:usermod 选项 用户名
删除用户:userdel (选项) 用户名
用户组将用户分成小组,方便对用户的管理
创建用户组:groupadd (选项) 用户组名修改用户组:groupmod (选项) 用户组名
查询用户所属组:groups 用户名删除用户组:groupdel 用户组名管理用户组内成员:gpasswd (可选项) 组名
gpasswd是Linux下的管理工具,用于将一个用户添加到组或者从组中删除
-a:添加用户到组-d:从组中删除用户-A:指定管理员-M:指定组员和-A的用途差不多-r:删除密码-R:限制用户登入组,只有组中的成员才可以用newgrp加入该组
系统管理相关命令
日期管理:date [参数选项]
参数选项:
-d "字符串":显示字符串所指的日期与时间。字符串前后必须加上双引号-s "字符串":根据字符串来设置日期与时间。字符串前后必须加上双引号-u:显示GMT(北京时间为CST)--help:在线帮助--version:显示版本信息 显示登陆账号的信息:logname切换用户:su 用户名查看当前用户详细信息(用户id、群组id、所属组):id 用户名提高普通用户的操作权限:sudo [参数选项] 进程相关命令
实时显示process的动态 :top
pid:每个进程的id
user:进程是属于哪个用户
PR:进程的优先级
NI:进程优先级(负数为高优先级,正数为低优先级)
VIRT:当前进程占用虚拟内存的总量
S:当前进程的状态
实时显示所有进程信息(显示完整命令):top -c实时显示指定进程的信息:top -p PID结束实时监控:q
查看当前正在运行的进程信息:ps
显示系统中所有的进程信息:ps -A显示系统中所有的进程信息(完整信息):ps -ef显示指定用户的进程信息:ps -u 用户名
中断执行中的程序:kill PID
例如:kill 1111表示杀死PID为1111的进程kill -9 PID:强制杀死指定PID的进程killall -u 用户名:杀死这个用户中的所有进程kill -9 $(ps -ef|grep 用户名):杀死指定用户的所有进程kill -l:查看对应编号
关机命令:shutdown(延迟关机)
shutdown -h now:立即关机shutdown +1 "1分钟以后关机":延迟一分钟以后关机,并给出警告信息shutdown -r +1 "准备重启了":延迟一分钟以后重启,并给出警告信息shutdown -c:取消关机命令
重启命令:reboot(立即重启)
显示当前登录系统的用户:who
who -H:显示明细(标题)信息
校正服务器时间、时区:timedatectl
几个小概念
| 项目 | 说明 |
|---|---|
| 时区 | 因时区不同显示的时间不同,牵扯到夏令时和调整等问题,date命令可查看 |
| 系统时钟:System Clock | Linux OS的时间,date命令可查看 |
| 硬件时钟:RTC:Real Time Clock | 主板上由电池供电的BIOS时间,hwclock -r可查看 |
| NTP:Network Time Protocol | 本机时间和实际的时间之间的经常会有差别,一般使用NTP服务器进行时间校准 |
timedatectl status:显示系统的当前时间和日期timedatectl list-timezones:查看所有可用的时区timedatectl set-timezone "Asia/Shanghai":设置本地时区timedatectl set-ntp false:禁用时间同步timedatectl set-time "2022-02-22 20:20:00":设置时间timedatectl set-ntp true:启用时间同步
清除屏幕:clear
目录管理| 常见命令 | 作用 |
|---|---|
| ls | 列出目录 |
| cd | 切换目录 |
| pwd | 显示目前的目录 |
| mkdir | 创建新目录 |
| rmdir | 删除空目录 |
| cp | 复制文件或目录 |
| rm | 删除文件或目录 |
| mv | 移动文件或目录 修改文件或者目录的名字 |
ls命令相当于在Windows系统中打开文件夹,看到的目录以及文件的明细。
语法:ls [参数选项] 目录名称-a:显示所有文件或目录(包含隐藏)-d:仅列出目录本身,而不是列出目录内的文件数据(常用)-l:长数据串列出,包含文件的属性与权限等等数据(常用)
pwd -P:查看当前所在目录cd [相对路径或绝对路径]:切换目录ls:显示不隐藏的文件与文件夹
ls -l:显示不隐藏的文件与文件夹的详细信息
ls -al:显示所有文件与文件夹的详细信息
cd ..:返回上一级目录 mkdir
mkdir 文件夹的名字:创建单级目录创建多级文件夹,使用mkdir -p aaa/bbb rmdir
rmdir 文件夹名字:删除空目录rmdir -p aaa/bbb:删除多级目录(先删bbb,如果删完aaa也为空,则aaa也一起删除) rm
rm 文件路径:删除文件rm -r 目录路径:删除目录和目录里面所有的内容(单级目录或多级目录都行) touch 文件名.后缀名:创建一个文件cp
cp 数据源 目的地:文件复制(仅文件)cp -r aaa
public class RequestDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取所有数据
Map 用IO流获取请求信息时,不支持get方式,只支持post提交方式 GET方式 请求域(request域):可以在一次请求范围内进行共享数据。一般用于请求转发的多个资源中共享数据请求对象操作共享数据方法
请求转发:客户端的一次请求到达以后,发现需要借助其他 Servlet 来实现功能(浏览器请求,A发现做不了,转发给B去做)特点
浏览器地址栏不变域对象中的数据不丢失负责转发的Servlet 转发前后的响应正文会丢失由转发的目的地来响应客户端
请求包含:可以合并其他Servlet 中的功能一起响应给客户端(浏览器请求,A只能做一半,另一半让B做)特点
浏览器地址栏不变域对象中的数据不丢失被包含的 Servlet 响应头会丢失
响应:回馈结果。在 BS 架构中,就是服务器给客户浏览器反馈结果响应对象:就是在项目中用于发送响应的对象 和请求对象一样,不需要我们去写实现类,在Tomcat 服务器创建好,在执行 doGet 或者 doPost 方法时,服务器会把相应的实现类对象传递 步骤: 获取到的字节输出流对象不需要close释放,会由响应对象处理并释放 未出现乱码问题:浏览器默认gbk编码,idea默认UTF-8编码;但是getBytes方法在将字符串转为字节数组时,如果不传递参数指定编码,就会根据当前系统平台默认编码进行转换,Windows系统默认编码为gbk,和浏览器一致,故未出现乱码 步骤和上面字节流一样,同样不需要自己close释放资源 缓存:对于不经常变化的数据,我们可以设置合理的缓存时间,以避免浏览器频繁请求服务器。以此来提高效率
例:resp.setDateHeader("Expires",System.currentTimeMillis() + 1*60*60*1000); 设置一个小时缓存时间 定时刷新:过了指定时间后,页面自动进行跳转
例:resp.setHeader("Refresh","3;URL=要跳转的路径") 请求重定向:客户端的一次请求到达后,发现需要借助其他Servlet 来实现功能特点:浏览器地址栏会发生改变,两次请求,请求域对象中不能共享数据,可以重定向到其他服务器重定向实现原理
资源准备
会话:浏览器和服务器之间的多次请求和响应为了实现一些功能,浏览器和服务器之间可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束(关闭浏览器、到了过期时间)。这期间产生的多次请求和响应加在一起就称之为浏览器和服务器之间的一次会话会话过程所产生的一些数据,可以通过会话技术(cookie 和 Session)保存。
概述
cookie: 客户端会话管理技术 是一个普通的Java类两个必须属性:name 和value发送:HttpServletResponse.addcookie(cookie对象)每个网站最多20个cookie,浏览器存储的cookie总数不大于300个,每个cookie大小限制在4kb获取所有cookie对象:HttpServletRequest.getcookie()
cookie属性
向客户端添加cookie:void HttpServletResponse.addcookie(cookie cookie)获取所有的cookie:cookie[] HttpServletRequest.getcookies()
练习
需求说明:通过cookie记录最后访问时间,并在浏览器上显示出来最终目的:掌握cookie的基本使用,从创建到添加客户端,再到从服务器端获取实现步骤
数量限制 HttpSession:服务器端会话管理技术 只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中。 HttpSession 是一个接口,对应的实现类对象是通过HttpServletRequest 对象来获取
需求说明:通过第一个Servlet 设置共享数据用户名,并在第二个Servlet 获取到最终目的:掌握HttpSession 的基本使用,如何获取和使用实现步骤
唯一标识的查看:借助浏览器开发者工具浏览器禁用cookie 钝化:序列化。把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上活化:相反的状态 钝化时间 HttpSession 的序列化由服务器自动完成,我们无需关心 JSP(Java Server Pages):是一种动态网页技术标准JSP 部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成 HTML、XML 或其他格式文档的 Web网页,然后再响应给客户端。Jsp 是基于Java 语言的,它的本质就是 Servlet
文件内容介绍 生成的Java 文件目录 JSP注释:<%-- 注释的内容 --%>Java代码块:<% Java代码 %>JSP表达式:<%=表达式%>JSP声明:<%! 声明变量或方法 %>
System.out.println():普通输出语句,输出在控制台上 page 指令:<%@ page 属性名=属性值 属性名=属性值... %>
九大隐式对象(不用创建,可以直接使用)
是 JSP 独有的, Servlet 中没有是四大域对象之一的页面域对象,还可以操作其他三个域对象中的属性可以获取其他八个隐式对象生命周期是随着 JSP 的创建而存在,随着 JSP 的结束而消失。每个JSP 页面都有一个 PageContext 对象
四大域对象 M(Model):模型。 用于封装数据,封装的是数据模型V(View):视图。 用于显示数据,动态资源用 JSP页面,静态资源用 HTML 页面C(Controller):控制器。 用于处理请求和响应,例如 Servlet
登录功能 EL(expression Language):表达式语言在 JSP 2.0 规范中加入的内容,也是 Servlet 规范的一部分作用:在 JSP 页面中获取数据,让我们的 JSP 脱离 Java代码块和 JSP 表达式语法:${表达式内容}
快速入门
EL 表达式没有空指针异常EL 表达式没有索引越界异常EL 表达式没有字符串的拼接
使用细节 EL 表达式能够获取到四大域对象的数据,根据名称从小到大在域对象中查找还可以获取 JSP 其他八个隐式对象,并调用对象中的方法
运算符
关系运算符
JSTL(Java Server Pages Standarded Tag Library):JSP 标准标签库主要提供给开发人员一个标准通用的标签库开发人员可以利用这些标签来取代 JSP 页面上的Java代码,从而提高程序的可读性,降低程序的维护难度
使用步骤 在程序中访问服务器资源时,当一个请求到来,服务器首先判断是否有过滤器与请求资源相关联,如果有,过滤器可以将请求拦截下来,完成一些特定的功能,再由过滤器决定是否交给请求资源。如果没有相关联的过滤器则像之前那样直接请求资源了。响应也是类似的过滤器一般完成用于通用的操作,例如:登录验证、统一编码处理、敏感字符过滤等等…
概述
是一个接口。如果想实现过滤器的功能,必须实现该接口核心方法
FilterChain 是一个接口,代表过滤器链对象。由Servlet 容器提供实现类对象。直接使用即可过滤器可以定义多个,就会组成过滤器链核心方法
如果有多个过滤器,在第一个过滤器中调用下一个过滤器,依此类推。直到到达最终访问资源。 需求说明:通过 Filter 过滤器解决多个资源写出中文乱码的问题实现步骤
配置方式 创建 FilterConfig 是一个接口。代表过滤器的配置对象,可以加载一些初始化参数 核心方法 Filter 过滤器默认拦截的是请求,但是在实际开发中,我们还有请求转发和请求包含,以及由服务器触发调用的全局错误页面。默认情况下过滤器是不参与过滤的,要想使用,就需要我们配置 拦截方式 REQUEST:默认值,浏览器直接请求的资源会被过滤器拦截 FORWARD:转发访问资源会被过滤器拦截 INCLUDE:包含访问资源 ERROR:全局错误跳转资源 ASYNC:异步访问资源 全局错误页面配置 观察者设计模式,所有的监听器都是基于观察者设计模式的三个组成部分
监听对象的创建和销毁的监听器 ServletContextListener:用于监听 ServletContext 对象的创建和销毁 核心方法 参数:ServletContextEvent 代表事件对象 HttpSessionListener:用于监听 HttpSession 对象的创建和销毁 核心方法 参数:HttpSessionEvent 代表事件对象 ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁 核心方法 参数:ServletRequestEvent 代表事件对象 监听域对象属性变化的监听器 ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化 核心方法 参数:ServletContextAttributeEvent 代表事件对象 HttpSessionAttributeListener:用于监听 HttpSession 会话域中属性的变化 核心方法 参数:HttpSessionBindingEvent 代表事件对象 ServletRequestAttributeListener:用于监听 ServletRequest 请求域中属性的变化 核心方法 参数:ServletRequestAttributeEvent 代表事件对象 监听会话相关的感知型监听器 感知型监听器:在定义好之后就可以直接使用,不需要再通过注解或xml文件进行配置 HttpSessionBindingListener:用于感知对象和会话域绑定的监听器 核心方法 参数:HttpSessionBindingEvent 代表事件对象 HttpSessionActivationListener:用于感知会话域对象钝化和活化的监听器 核心方法 参数:HttpSessionEvent 代表事件对象 监听对象的 监听属性变化的 会话相关的感知型 配置监听器 注解方式:@WebListenerxml文档方式 使用过滤器实现所有资源的编码统一 使用过滤器解决登录检查 注解配置过滤器时指定多个拦截路径 通过EL表达式和JSTL替换之前的Java代码块和JSP表达式 完整代码:https://github.com/HelloCode66/StudentSystempackage study.servlet;
import org.apache.commons.beanutils.BeanUtils;
import study.servlet.bean.Student;
public class RequestDemo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取所有数据
Map
流对象获取请求信息
返回值 方法名 说明 BufferedReader getReader() 获取字符输入流 ServletInputStream getInputStream() 获取字节输入流
获得到的流对象都不是自己new出来的,不需要close释放资源,会由请求对象处理并释放package study.servlet;
import org.apache.commons.beanutils.BeanUtils;
import study.servlet.bean.Student;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;
@WebServlet("/request7")
public class RequestDemo7 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 字符流(必须是post请求方式)
BufferedReader br = req.getReader();
String line;
while((line = br.readLine()) != null) System.out.println(line);
// 字节流
ServletInputStream is = req.getInputStream();
byte[] arr = new byte[1024];
int len;
while((len = is.read(arr)) != -1){
System.out.println(new String(arr, 0, len));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
中文乱码问题
没有乱码问题,在Tomcat 8 版本后已经解决POST方式
有乱码问题,可以通过 setCharacterEncoding() 方法来解决(编码格式要和页面编码格式一致)
package study.servlet;
@WebServlet("/request8")
public class RequestDemo8 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String name = req.getParameter("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求域
请求转发
返回值 方法名 说明 void setAttribute(String name, Object value) 向请求域对象中存储数据 Object getAttribute(String name) 通过名称获取请求域对象中的数据 void removeAttribute(String name) 通过名称移除请求域对象中的数据 返回值 方法名 说明 RequestDispatcher getRequestDispatcher(String name) 获取请求调度对象 void forward(ServletRequest req, ServletResponse resp) 实现转发(用请求调度对象调用) package study.servlet.request;
@WebServlet("/request9")
public class RequestDemo9 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置共享数据
req.setAttribute("name","张三");
// 获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/request10");
// 请求转发
rd.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
package study.servlet.request;
@WebServlet("/request10")
public class RequestDemo10 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取共享数据
System.out.println(req.getAttribute("name"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求包含
返回值 方法名 说明 RequestDispatcher getRequestDispatcher(String name) 获取请求调度对象 void include(ServletRequest req, ServletResponse resp) 实现包含 package study.servlet.request;
@WebServlet("/request11")
public class RequestDemo11 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置共享数据
req.setAttribute("name","张三");
// 获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/request10");
// 请求转发
rd.include(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
响应对象
ServletResponse(接口)
HttpServletResponse(继承自ServletResponse,基于http协议的接口)
常见状态码
字节流响应消息
状态码 说明 200 成功 302 重定向 304 请求资源未改变,使用缓存 400 请求错误,常见于请求参数错误 404 请求资源未找到 405 请求方式不支持 500 服务器错误 返回值 方法名 说明 ServletOutputStream getOutputStream() 获取响应字节输出流对象 void setContentType(“text/html;charset=UTF-8”) 设置响应内容类型,解决中文乱码问题 获取字节输出流对象定义一个消息(一个字符串)通过字节流对象输出
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取字节输出流
ServletOutputStream os = resp.getOutputStream();
String s = "字节输出流响应消息";
os.write(s.getBytes());
}
// 统一编码格式为UTF-8并解决乱码问题
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置相应内容类型,并设置编码格式(告知浏览器应该采用的编码格式)
resp.setContentType("text/html;charset=UTF-8");
// 获取字节输出流
ServletOutputStream os = resp.getOutputStream();
String s = "字节输出流响应消息";
os.write(s.getBytes("UTF-8"));
}
字符流响应消息
返回值 方法名 说明 PrintWriter getWriter() 获取响应字符输出流对象 void setContentType(“text/html;charset=UTF-8”) 设置响应内容类型,解决中文乱码问题
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置相应内容类型,并设置编码格式(告知浏览器应该采用的编码格式)
resp.setContentType("text/html;charset=UTF-8");
// 获取字符输出流对象
PrintWriter pw = resp.getWriter();
pw.write("字符输出流响应消息");
}
响应图片
通过文件的相对路径获取绝对路径(getRealPath)创建字节输入流对象,关联读取的图片路径通过响应对象获取字节输出流对象循环读取和写出图片
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realPath = getServletContext().getRealPath("/img/tx.png");
// 创建字节输入流对象,关联图片
BufferedInputStream is = new BufferedInputStream(new FileInputStream(realPath));
// 获取字节输出流对象,响应图片
ServletOutputStream os = resp.getOutputStream();
// 循环读写
byte[] arr = new byte[1024];
int len;
while((len = is.read(arr)) != -1){
os.write(arr, 0, len);
}
// 释放资源
is.close();
}
设置缓存
返回值 方法名 说明 void setDateHeader(String name,long time) 设置消息头添加缓存
定时刷新
Expires 就是过期的意思
时间单位为毫秒,1秒等于1000毫秒返回值 方法名 说明 void setHeader(String name,String value) 设置消息头定时刷新
请求重定向
单位为秒设置响应状态码为302:resp.setStatus(302);设置响应的资源路径(响应到哪里去,通过响应消息头 location 来指定):resp.setHeader("location","/response/responseDemo")
响应对象重定向方法
文件下载
返回值 方法名 说明 void sendRedirect(String name) 设置重定向 创建字节输入流,关联读取的文件设置响应消息头支持的类型:resp.setHeader("Content-Type","application/octet-stream")
Content-Type:消息头名称,代表所支持的类型
application/octet-stream:消息头参数,代表应用的类型为字节流设置响应消息头以下载方式打开资源:resp.setHeader("Content-Disposition","attachment;filename=下载的文件名称")
Content-Disposition:消息头名称,代表处理形式
attachment;filename=xxx:消息头参数,代表附件的形式进行处理,filename代表指定下载文件的名称通过响应对象获取字节输出流对象循环读写释放资源@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建字节输入流,关联读取的文件
String realPath = req.getServletContext().getRealPath("/img/tx.png");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
// 设置响应消息头支持的类型
resp.setHeader("Content-Type", "application/octet-stream");
// 设置响应消息头以下载方式打开资源
resp.setHeader("Content-Disposition","attachment;filename=file.png");
// 通过响应对象获取字节输出流对象
ServletOutputStream os = resp.getOutputStream();
int len;
byte[] arr = new byte[1024];
while((len = bis.read(arr)) != -1){
os.write(arr, 0, len);
}
// 释放资源
bis.close();
}
学生管理系统2
创建一个 web 项目在web 目录下创建一个 index.html,包含两个超链接标签(添加学生、查看学生)在 web目录下创建一个 addStudent.html,用于实现添加功能的表单页面在 src 下创建一个 Student 类,用于封装学生信息
// list.java
package studentServlet;
import studentServlet.bean.Student;
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.*;
import java.util.ArrayList;
@WebServlet("/list")
public class list extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\Java\code\StudentServlet\stu.txt"));
ArrayList
");
}
br.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
cookie
会话
学生信息管理系统
添加学生信息
查看学生信息
把要共享的数据保存到客户端
每次请求时,把会话信息带到服务器端,从而实现多次请求的数据共享作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率特点:
方法
属性名 作用 是否重要 name cookie的名称 必须属性 value cookie的值(不支持中文) 必须属性 path cookie的路径 重要 domain cookie的域名 重要 maxAge cookie的存活时间(s) 重要 version cookie的版本号 不重要 comment cookie的描述 不重要 方法名 作用 cookie(String name, String value) 构造方法创建对象 属性对应的set和get方法 赋值和获取值(name有final修饰,无set方法) 通过响应对象写出一个提示信息创建cookie对象,指定name和value设置cookie最大存活时间通过响应对象将cookie对象添加到客户端通过请求对象获取cookie对象将cookie对象中的访问时间写出
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过响应对象写出一个提示信息
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.write("您的最后访问时间为:");
pw.write("
注意事项
");
// 创建cookie对象,指定name和value
cookie cookie = new cookie("time", System.currentTimeMillis()+"");
// 设置cookie最大存活时间
cookie.setMaxAge(3600);
// 通过响应对象将cookie对象添加到客户端
resp.addcookie(cookie);
// 通过请求对象获取cookie对象
cookie[] cookies = req.getcookies();
// 将cookie对象中的访问时间写出
for(cookie ck : cookies){
if("time".equals(ck.getName())){
String value = ck.getValue();
// 格式化时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String lastTime = sdf.format(new Date(Long.parseLong(value)));
pw.write(lastTime);
}
}
}
每个网站最多只能用20个cookie,且大小不能超过4kb,所有网站的cookie总数不超过300个名称限制
cookie的名称只能包含ASCII码表中的字母、数字字符。不能包含逗号、分号、空格,不能以$开头。
cookie的值不支持中文存活时间限制:setMaxAge()方法接收数字
负整数:当前会话有效,浏览器关闭则清除(默认)
0:立即清除
正整数:以秒为单位设置存活时间访问路径限制
取自第一次访问的资源路径前缀
只要以这个前缀开头(包括子级路径)就能获取到,反之获取不到
设置路径:setPath()方法设置指定路径
Session
本质也是采用客户端会话管理技术
作用:可以实现数据共享
每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享
是Servlet规范中四大域对象之一的会话域对象
常用方法
域对象 功能 作用 ServletContext 应用域 在整个应用之间实现数据共享 ServletRequest 请求域 在当前的请求或请求转发之间实现数据共享 HttpSession 会话域 在当前会话范围之间实现数据共享
对象获取
返回值 方法名 说明 void setAttribute(String name, Object value) 设置共享数据 Object getAttribute(String name) 获取共享数据 void removeAttribute(String name) 移除共享数据 String getId() 获取唯一标识名称 void Invalidate() 让session立即失效
练习
返回值 方法名 说明 HttpSession getSession() 获取HttpSession对象 HttpSession getSession(boolean create) 获取HttpSession对象,未获取到是否自动创建(默认true) 在第一个 Servlet 中获取请求的用户名获取 HttpSession 对象将用户名设置到共享数据中在第二个 Servlet 中获取 HttpSession 对象获取共享数据用户名将获取到的用户名响应给客户端浏览器
// Session01
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 在第一个 Servlet 中获取请求的用户名
String username = req.getParameter("username");
// 获取 HttpSession 对象
HttpSession session = req.getSession();
// 将用户名设置到共享数据中
session.setAttribute("username",username);
}
// session02
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 在第二个 Servlet 中获取 HttpSession 对象
HttpSession session = req.getSession();
// 获取共享数据用户名
Object username = session.getAttribute("username");
// 将获取到的用户名响应给客户端浏览器
PrintWriter pw = resp.getWriter();
pw.write(username+"");
}
注意事项
方式一:通过提示信息告知用户,大部分网站采用的解决方式【推荐】
方式二:通过resp.enconeURL方法实现url重写(地址栏拼接jsessionid)【了解】钝化和活化
第一种情况: 当访问量很大时,服务器会根据getLastAccessTime 来进行排序,对长时间不用,但还没到过期时间的HttpSession进行序列化
第二种情况: 当服务器进行重启的时候,为了保持客户HttpSession 中的数据,也要对其进行序列化
JSP
快速入门
类别 使用场景 HTML 开发静态资源,无法添加动态资源 CSS 美化页面 Javascript 给网页添加一些动态效果 Servlet 编写Java 代码,实现后台功能处理 JSP 包含了显示页面技术,也具备Java代码功能 创建一个web项目在web 目录下创建一个 index.jsp 文件在文件中写一句内容为:这是我的第一个jsp部署并启动项目通过浏览器测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
执行过程
客户端浏览器发送请求到Tomcat 服务器Tomcat 服务器解析请求地址找到具体的应用找到对应的jsp文件将jsp文件翻译为.java的文件编译Java文件响应给客户端
继承自 HttpJspbase类,而HttpJspbase继承自 HttpServlet(JSP本质上就是一个 Servlet)
jsp显示页面本质上就是通过获取输出流对象并通过write写出
语法
指令
out.println():JspWriter 对象,将内容输出在浏览器页面上,不会自动换行
<%="要输出的内容"%>就相当于out.println("要输出的内容")
在声明中,如果加!,代表声明的是成员变量;如果不加!,代表声明的是局部变量;如果是声明方法,就必须加!
include 指令:可以包含其他页面属性名 作用 contentType 响应正文支持的类型和设置编码格式 language 使用的语言,默认是Java errorPage 当前页面出现异常后跳转的页面 isErrorPage 是否抓住异常,如果为true则页面中就可以使用异常对象,默认是false import 导包 import= “java.util.ArrayList” session 是否创建 HttpSession 对象,默认是true buffer 设定 JspWriter 输出jsp内容缓存的大小,默认8kb pageEncoding 翻译jsp时所用的编码格式 isEIgnored 是否忽略EL表达式,默认是false
<%@ include file=包含的页面 %>taglib 指令:可以引入外部标签库
<%@ taglib uri=标签库的地址 prefix=前缀名称 %>
注意事项
PageContext 对象
隐式对象名称 代表实际对象 request javax.servlet.http.HttpServletRequest response javax.servlet.http.HttpServletResponse session javax.servlet.http.HttpSession application javax.servlet.ServletContext page java.lang.Object config javax.servlet.ServletConfig exception java.lang.Throwable out javax.servlet.jsp.JspWriter pageContext javax.servlet.jsp.PageContext
MVC模型
域对象名称 范围 级别 备注 PageContext 页面范围 最小,只能在当前页面使用 因范围太小,开发中用的很少 ServletRequest 请求范围 一次请求或当前请求转发用 请求转发之后,再次转发时请求域丢失 HttpSession 会话范围 多次请求数据共享时使用 多次请求共享数据,但不同的客户端不能共享 ServletContext 应用范围 最大,整个应用都可以使用 尽量少用,如果对数据有修改需要做同步处理 创建一个web目录在web目录下创建一个index.jsp在页面中获取会话域中的用户名,获取到了就显示添加和查看功能的超链接,没获取到就显示登录功能的超链接在web目录下创建一个login.jsp。实现登录页面创建 LoginServlet,获取用户名和密码如果用户名为空,则重定向到登录页面如果不为空,将用户名添加到会话域中,再重定向到首页
<%-- login.jsp --%>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 20:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
// login.java
package studentServlet;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String username = req.getParameter("username");
String password = req.getParameter("password");
resp.setContentType("text/html;charset=UTF-8");
if(null == username || "".equals(username)){
resp.getWriter().write("账号不能为空,请重新输入(2s后返回...)");
resp.setHeader("Refresh","2;URL=/login.jsp");
}else{
if("admin".equals(username) && "abc123".equals(password)){
session.setAttribute("username",username);
resp.sendRedirect("/index.jsp");
}else{
resp.getWriter().write("账号密码不正确,请重新输入(2s后返回...)");
resp.setHeader("Refresh","2;URL=/login.jsp");
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<%-- index.jsp --%>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 19:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<% if(session.getAttribute("username") == null){ %>
请登录
<% } else { %>
添加学生信息
查看学生信息
<% } %>
<%-- list.jsp --%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="studentServlet.bean.Student" %>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 20:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
ArrayList姓名
年龄
成绩
<% } %>
<%=stu.getUsername()%>
<%=stu.getAge()%>
<%=stu.getScore()%>
// list.java
package studentServlet;
import studentServlet.bean.Student;
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.*;
import java.util.ArrayList;
@WebServlet("/list")
public class list extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\Java\code\StudentServlet\stu.txt"));
ArrayList
EL表达式
创建一个web 项目在web 目录下创建 jsp文件在文件中向域对象添加数据使用三种方式获取域对象中的数据(Java代码块、JSP表达式、EL表达式)部署并启动项目通过浏览器测试
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/25
Time: 10:04
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
获取数据
<%-- jsp表达式 --%>
<%=request.getAttribute("username")%>
<%--EL表达式--%>
${username}
获取基本数据类型的数据
${数据名}获取自定义对象类型的数据
${对象名.属性名}
这里获取到对象的成员变量的原理是通过调用get方法获取,所以不必担心private私有问题获取数组类型的数据
${数组名[索引]}获取List 集合类型的数据
${集合[索引]}获取 Map 集合类型的数据
${集合.key值}:获取key对应的value<%@ page import="study.servlet.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/25
Time: 10:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
注意事项
<%--获取自定义对象类型的数据--%>
${arr[2]}
<%--获取数组类型的数据--%>
${list[1]}
<%--获取List 集合类型的数据--%>
${map.user} <%--获取 Map 集合类型的数据--%>
逻辑运算符
运算符 作用 示例 结果 == 或 eq 等于 ${5 == 5} 或 ${5 eq 5} true != 或 ne 不等于 ${5 != 5} 或 ${5 ne 5} false < 或 lt 小于 ${3 < 5} 或 ${3 lt 5} true > 或 gt 大于 ${3 > 5} 或 ${3 gt 5} false <= 或 le 小于等于 ${3 <= 5} 或 ${3 le 5} true >= 或 ge 大于等于 ${3 >= 5} 或 ${3 ge 5} false
其他运算符
运算符 作用 示例 结果 && 或 and 并且 ${A && B} 或 ${A and B} true / false || 或 or 或者 ${A || B} 或 ${A or B} true / false ! 或 not 取反 ${!A} 或 ${not A} true / false
隐式对象
运算符 作用 empty 1. 判断对象是否为null
2. 判断字符串是否为空字符串
3. 判断容器元素是否为0条件 ? 表达式1 : 表达式2 三元运算符 隐式对象名称 对应JSP隐式对象 说明 pageContext pageContext 功能完全相同 applicationScope 无 操作应用域对象数据 sessionScope 无 操作会话域对象数据 requestScope 无 操作请求域对象数据 pageScope 无 操作页面域对象数据 header 无 获取请求头数据 headerValues 无 获取请求头数据(多个值) param 无 获取请求参数数据 paramValues 无 获取请求参数数据(多个值) initParam 无 获取全局配置参数数据 cookie 无 获取cookie对象 <%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/25
Time: 10:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
JSTL
<%--applicationScope sessionScope requestScope pageScope 操作四大域对象中的数据--%>
${pageContext.setAttribute("username","zhangsan")}
${pageScope.username}
<%--header headerValues 获取请求头数据--%>
${header["connection"]}
${headerValues["connection"][0]}
${header.connection}
<%--param paramValues 获取请求参数数据--%>
${param.username}
${paramValues.hobby[0]}
<%--initParam 获取全局配置参数--%>
${initParam.globaldesc}
<%--cookie 获取cookie信息--%>
${cookie} <%--直接写cookie获取到的是一个map集合--%>
${cookie.JSESSIONID.value}
核心标签
组成 作用 说明 core 核心标签库 通用的逻辑处理 fmt 国际化 不同地域显示不同语言 functions EL 函数 EL 表达式可以使用的方法 sql 操作数据库 了解 xml 操作XML 了解 标签名称 功能分类 属性 作用 <标签名:if> 流程控制 核心标签库 用于条件判断 <标签名:choose>
<标签名:when>
<标签名:otherwise>流程控制 核心标签库 用于多条件判断 <标签名:forEach> 迭代遍历 核心标签库 用于循环遍历 创建一个 web 项目在 web目录下创建一个 WEB-INF 目录在 WEB-INF 目录下创建一个 libs 目录,将 JSTL 的 jar 包导入创建 JSP 文件,通过 taglib 导入 JSTL 标签库对流程控制和迭代遍历的标签进行使用部署并启动项目通过浏览器查看
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/25
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入核心库并起标签名--%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
Filter
<%--多条件判断--%>
<%--循环遍历--%>
<%
ArrayList
配置方式返回值 方法名 作用 void init(FilterConfig config) 初始化方法 void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 对请求资源和响应资源过滤 void destroy() 销毁方法
方式一:配置文件(web.xml)
方式二:注解方式
FilterChain
返回值 方法名 说明 void doFilter(ServletRequest request, ServletResponse response) 放行方法
过滤器使用
如果只有一个过滤器,放行时,就会直接到达最终访问资源创建一个 web 项目创建两个 Servlet 功能类,都向客户端写出中文数据创建一个 Filter 过滤器实现类,重写 doFilter 核心方法在方法内解决中文乱码,并放行部署并启动项目通过浏览器测试
package study.servlet.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/filter01")
public class filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filter执行了");
// 处理乱码
servletResponse.setContentType("text/html;charset=UTF-8");
// 放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {}
}
使用细节
注解方式:@WebFilter(拦截路径)
配置文件方式
多个过滤器使用顺序
如果有多个过滤器,取决于过滤器映射的顺序
生命周期
当应用加载时实例化对象并执行init初始化方法服务
对象提供服务的过程,执行 doFilter 方法销毁
当应用卸载时或服务器停止时对象销毁。执行 destroy 方法
FilterConfig
返回值 方法名 作用 String getFilterName() 获取过滤器对象名称 String getInitParameter(String name) 根据name获取 value Enumeration getInitParameterNames() 获取所有参数的key ServletContext getServletContext() 获取应用上下文对象
五种拦截行为
Listener
事件源:触发事件的对象事件:触发的动作,封装了事件源监听器:当事件源触发事件后,可以完成功能
在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听Servlet 规范中共计 8 个监听器,监听器都是以接口形式提供,具体功能需要我们自己来完成
监听器
返回值 方法名 作用 void contextInitialized(ServletContextEvent sce) 对象创建时执行该方法 void contextDestroyed(ServletContextEvent sce) 对象销毁时执行该方法
事件对象中封装了事件源,也就是 ServletContext
真正的事件指的是创建或销毁 ServletContext 对象的操作返回值 方法名 作用 void sessionCreated(HttpSessionEvent se) 对象创建时执行该方法 void sessionDestroyed(HttpSessionEvent se) 对象销毁时执行该方法
事件对象中封装了事件源,也就是 HttpSession
真正的事件指的是创建或销毁 HttpSession 对象的操作返回值 方法名 作用 void requestInitialized(ServletRequestEvent sre) 对象创建时执行该方法 void requestDestroyed(ServletRequestEvent sre) 对象销毁时执行该方法
事件对象中封装了事件源,也就是 ServletRequest
真正的事件指的是创建或销毁 ServletRequest 对象的操作返回值 方法名 作用 void attributeAdded(ServletContextAttributeEvent scae) 域中添加属性时执行该方法 void attributeRemoved(ServletContextAttributeEvent scae) 域中移除属性时执行该方法 void attributeReplaced(ServletContextAttributeEvent scae) 域中替换属性时执行该方法
事件对象中封装了事件源,也就是 ServletContext
真正的事件指的是添加、移除、替换应用域中属性的操作返回值 方法名 作用 void attributeAdded(HttpSessionBindingEvent se) 域中添加属性时执行该方法 void attributeRemoved(HttpSessionBindingEvent se) 域中移除属性时执行该方法 void attributeReplaced(HttpSessionBindingEvent se) 域中替换属性时执行该方法
事件对象中封装了事件源,也就是 HttpSession
真正的事件指的是添加、移除、替换会话域中属性的操作返回值 方法名 作用 void attributeAdded(ServletRequestAttributeEvent srae) 域中添加属性时执行该方法 void attributeRemoved(ServletRequestAttributeEvent srae) 域中移除属性时执行该方法 void attributeReplaced(ServletRequestAttributeEvent srae) 域中替换属性时执行该方法
事件对象中封装了事件源,也就是 ServletRequest
真正的事件指的是添加、移除、替换请求域中属性的操作
返回值 方法名 作用 void valueBound(HttpSessionBindingEvent event) 数据添加到会话域中(绑定)时执行该方法 void valueUnbound(HttpSessionBindingEvent event) 数据从会话域中移除(解绑)时执行该方法
事件对象中封装了事件源,也就是 HttpSession
真正的事件指的是添加、移除会话域中数据的操作返回值 方法名 作用 void sessionWillPassivate(HttpSessionEvent se) 会话域中数据钝化时执行该方法 void sessionDidActivate(HttpSessionEvent se) 会话域中数据活化时执行该方法
监听器的使用
事件对象中封装了事件源,也就是 HttpSession
真正的事件指的是会话域中数据钝化、活化的操作
ServletContextListener
HttpSessionListener
ServletRequestListener
package study.servlet.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.annotation.WebServlet;
@WebServlet("/listener01")
@WebListener
public class listener01 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("监听到了对象的创建");
ServletContext servletContext = servletContextEvent.getServletContext();
// 添加属性
servletContext.setAttribute("username","张三");
// 替换属性
servletContext.setAttribute("username","李四");
// 移除属性
servletContext.removeAttribute("username");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("监听到了对象的销毁");
}
}
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
package study.servlet.listener;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
@WebServlet("/listener02")
public class listener02 implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了属性的添加");
ServletContext servletContext = servletContextAttributeEvent.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了属性的移除");
ServletContext servletContext = servletContextAttributeEvent.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("监听到了属性的替换");
ServletContext servletContext = servletContextAttributeEvent.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
}
HttpSessionBindingListener
HttpSessionActivationListener
学生管理系统优化
解决乱码
将请求和响应对象转换为和HTTP相关的HttpServletRequest和HttpServletResponse设置编码格式放行
package studentSystem.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 将请求和响应对象转换为和HTTP相关的HttpServletRequest和HttpServletResponse
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 设置编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 放行
filterChain.doFilter(request, response);
}
}
检查登录
将请求和响应对象转换为和HTTP相关的HttpServletRequest和HttpServletResponse获取会话域对象中的数据判断用户名重定向(或定时刷新)到登录页面或放行
@WebFilter(value = {"/拦截路径一", "/拦截路径二", ...})package studentSystem.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(value = {"/add.jsp", "/list.jsp"})
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 将请求和响应对象转换为和HTTP相关的HttpServletRequest和HttpServletResponse
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取会话域对象中的数据
HttpSession session = request.getSession();
Object username = session.getAttribute("username");
Object password = session.getAttribute("password");
// 判断用户名
if("admin".equals(username) && "abc123".equals(password)){
filterChain.doFilter(request, response);
}else{
// 输出提示信息并设置定时刷新到登录页面
response.getWriter().write("您还未登录,请登录后再试。(2s后为您跳转到登录页面)");
response.setHeader("Refresh","2:URL=/login.jsp");
}
}
}
优化JSP页面
MYSQL
JDBC
Mybatis
Javascript
jQuery
AJAX
Vue + Element
Redis
Maven基础
Web项目实战-黑马页面



