javawed基础
javaweb
- junit单元测试
- 反射
- 注解
测试:
- 黑盒测试:运行看不见,不需要写代码,看程序是否输出期望值
- 白盒测试:需要写代码。关注具体流程。看的见
junit测试:白盒测试
步骤:
-
定义一个测试类
测试类名:被此时的类名Test, CalculatorTest
包名:xxx.xxx.xx.test cn.it.test
-
测试方法:可以独立运行
方法名:test测试的方法名 testAdd()
返回值:void
参数列表:空参
-
给方法加注解@Test
-
导入包依赖环境
一般使用断言来处理结果
Assert.assertEquals(expect(期望的),actual(实际的));
两个注解:
-
@Before:修饰的方法会在测试方法之前被自动执行
- public void init(){}
-
@After:修饰的方法会在测试方法之后自动执行
- public void close(){}
-
@Test:不需要main方法就能使用
反射
框架设计的灵魂
- 框架:半成品软件。科一在框架的基础上进行一些软件开发,简化编码
- 反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处:
- 可以在程序有运行中操作这些对象
- 可以解藕,提高程序的可操作性
获取class方式
- Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类(字符串)
- 类名.class:通过类名的属性获取
- 多用于参数的传递
- 对象.getClass():getClass()方法在Object类中定义
- 多用于对象的获取字节码方式
- 结论:同一个字节码文件在一次运行国政中,只会被加载一次,不论通过哪一种方式
使用class
- 获取成员变量
- Field[] getFields()
- Field getField(String name)
- Field[] getDeclaredFields()
- Field getDeclaredField(String name)
- 获取构造方法
- Constructor<?>[] getConstructors()
- Constructor< > getConstructors(类<?>...parameterTypes)
- 获取成员方法
- 获取类名
Field:成员变量
-
操作
-
设置值
void set(Object obj,Object value) ,obj为类的对象,value为修改值
-
获取值
get(Object obj) ,obj为类的对象
-
忽略访问权限修饰符的安全检查
srtAccessible(true):暴力反射
-
Constructor:构造方法
- 创建对象:
- T newInstance(Object...initargs)初始化
- 用空参创建对象Class对象的newInstance方法
Method :执行方法
-
执行方法:
- invoke
-
获取方法名,类名
String getName:获取方法名
类名从Class中获取
案例
需求:写一个“框架”,在不改变代码的情况下,创还能任意类的对象,并能执行任意方法
-
实现:
- 配置文件
- 反射
-
步骤:
- 将需要创建的对象的全类名和执行方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术带加载类文件进内存
- 创建对象
- 执行方法
注解
分类
- 编写文档:通过代码里的标识的注解生成文档【生成文档doc文档】
- 代码分析:通过代码里的标识的注解对代码进行分析【使用反射】
- 编译检查:通过代码里的标识的注解让编译器实现基本的编译检查【@Override】
使用注解@注解名称
- JDK中预定义的一些注解
- @Override:检测是重写的方法
- @Deprecated:表明已过时
- @SuppressWarning:压制警告
自定义注解
-
格式:
元注解
public @interface 注解名称{}
-
本质:注解本质上就是一个接口,该接口默认继承Annotation接口
- public interface MyAnno extends java.lang.annotation.Annotation{}
-
属性:接口中可以定义的成员方法
要求:
-
属性的返回值类型:基本数据类型,String 枚举,注解和以上类型的数组
-
定义了属性,在使用时需要给属性赋值:
在定义属性时,使用default关键字修饰不用赋值
若只有一个属性则可以省略名称
-
-
元注解:用于描述注解的注解
@Target:用于描述注解能够作用的位置
-
ElementType的值:
TYPE:作用与类上
METHOD:作用于方法
FIELD:作用与成员变量
@Retrntion:描述注解被保留的阶段
- @Retention(RetentonPolicy.RUNTIME ):当前被描述的注解,会保留到class字节码文件中,并为JVM读取
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承
-
在程序中使用注解:获取注解中定义的属性值
-
获取注解定义的位置的对象(Class,Method,Field)
-
获取指定的注解
getAnnotation(Class)
-
调用注解中的抽象方法获取配置的属性值
简单的测试框架:
当主方法执行,会自动检查所有方法,并判断是否有异常,记录到文件中
- 获取注解中定义的属性值,测试类地址
- 创建测试类的对象
- 获取字节码文件对象
- 获取所有方法
- 判断方法是否有Ckeck注解,有就执行 if(method.isAnnotationPresent(Check.class))
- 捕获异常
小结:
- 会使用注解不定义
- 给编译器用,给解析程序用
- 注解不是程序,是程序的一个标签
web基础知识
web是互联网项目,使用java语言开发网站
数据库(5),网页前端(5),web核心技术(15),旅游管理系统(5)
数据库
基本概念,MySQL软件,SQL的使用
基本概念:DataBase,简称DB
- 用于存储和管理数据的仓库
特点:
- 持久化存储数据的,数据库就是一个文件系统
- 方便存储和管理数据
- 使用了统一的方式操作数据库--SQL
常见数据库软件:
- MySQL
- Or
MySQL
-
安装
-
卸载
去mysqld 安装目录下找到my.ini文件,复制daradir="c/programDate/Mysql/Mtsql Server 9/Data/"
卸载
删除c/programData/MySQL
-
配置
要配置环境
服务启动:
-
手动
-
cmd-->services.msc打开服务的窗口
-
使用管理员打开cmd
net start mysql:启动mysql服务
net stop mysql:关闭mysql服务
-
-
mySQL登录
mysql -uroot -p
mysql -hip -uroot -p
mysql --host=ip --user=root --password=
-
退出
exit
quit
MySQL的目录:
MySQL的安装目录
MySQL的数据目录
配置文件 my.ini
数据库:文件夹
表:文件
数据:数据
SQL
Structured Query Language:结构化查询语言
就是定义了操作所有关系型数据库的规则,每一种数据库的操作方式存在不一样的地方,称为方言
通用语法
-
SQL语句可以单行或多行书写,以分号结尾
-
使用空格和缩进
-
数据库不区分大小写,但关键字建议使用大写
-
3种注释
单行注释:-- 注释内容(有一个空格)或# 注释内容(mysql特有的)
多行注释:/* 注释 */
书写语句
- DDL:操作数据库和表的
- DML:增删改表中的数据
- DQL:查询表中的数据
- DCL:授权
DDL操作库和表
操作数据库和表的
1操作数据库:CRUD
-
C(Create):创建
创建数据库:create database 数据库名称;
创建数据库判断是否存在:create database if not exists 数据库名称;
创建db4数据库,并判断是否存在,并指定字符集为gbk:
create database if not exists bd4 character set gbk;
-
R(Retrieve):查询
查询所有的数据库:show databases;
查询某个数据库的创建语句:show create database 数据库名称;
-
U(Update):修改
修改数据库的字符集:alter database db3(数据库) character set 字符集名称
-
D(Delete):删除
删除数据库:drop database db3(数据库);
判断数据库存在:drop database if exists dbs(数据库名称)
-
使用数据库
查询当前正在使用的数据库:select database();
使用数据库:use db1(数据库名称)
操作表
-
C(Create):创建
创建表:create table 表名(
列名1 数据类型1,
列名2 数据类型2,
列名n 数据类型n
);
复制表:create table 新的表名 like 表名(被复制的表)
-
R(Retrieve):查询
查询所有数据库中的所有的表名称:show tables;
查询表达结构:desc 表名;
-
U(Update):修改
修改表名:alter table 表名 remane to 新的表名
修改表字符集:alter table 表名 character set 字符集名称
添加一列:alter table 表名 add 列名 数据类型
修改列名:alter table 表名 change 列名 新列名 新数据类型
alter table 表名 modify 列名 新数据类型;
删除列:alter table 表名 drop 列名
-
D(Delete):删除
使用数据库
删除表:drop table if exists 表名
数据类型:
-
int:整数类型 , age int,
-
double:小数类型 , score double(5(几位),2(小数点后几位))
-
date:日期,包含年月日 , yyyy-MM-dd
-
datetimr:日期,包含年月日时分秒 , yyyy-MM-dd,HH:mm:ss
-
timestamp:时间错,包含年月日时分秒 , yyyy-MM-dd,HH:mm:ss
若不赋值或赋值为null,则默认使用当前的时间自动赋值
-
varchar:字符串
name varchar(20):姓名最大20个字符
zhangsan 8个字符 张三 2个字符
创建表:
create table student(
id int ,
name varchar(32),
age int,
score double(4,1),
birthday date,
insert_time timestamp
);
DML:添改删数据
1.添加数据:
insert into 表名(列名1,列名2,...列名n) values(值1,值2,值3,...值n)
insert into student(id,name,age) values(1,'张三丰',77);
- 注意:
-
- 列名一一对应
-
- 若给所有列添加就不用写列名
-
删除数据:
语法:
- delete from 表名 [where 条件]
注意:
-
如果不加条件,就会删除表中的所有记录
-
若要删除所有记录
delete from 表名 ;有多少条记录就会执行多少次,效率低
truncate table 表名;显删除表再创建一张一摸一样的表
-
修改数据:
语法:
- update 表名 set 列名1 = 修改的数值1,列名2 = 修改的数值2 ... where(条件)
注意
- 不加条件就会全部修改
DQL:查询表中的记录
- select * from 表名;
查询语句
-
语法:
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
order by
排序
limit
分页限定 -
基础查询
-
多个字段的查询
select 字段名... from 表名
查询所有可以用*代替select name,age from stu;
select * from stu;
-
去除重复
distinctselect distinct * from stu;
-
计算列
一般可以使用四则运算计算一些列的值,直接加(一般只进行数值的计算 )select math,english,math+ifnull(english,0) from student
ifnull(表达式1,表达式2):null参与的计算都为null
表达式1:那个字段可能出现null
表达式2:若出现null后的替换值 -
起别名
在要起别名的列名后加as或空字符
select math,english,math+ifnull(english,0) as 总分 from student
-
-
条件查询
-
where字句后跟条件
-
运算符
<, > ,<=, >=,=,< >(=是等于没有赋值)
between ...and
in(集合)(in(18,22,34,33))
like
占位符:
_:表示了单个任意字符
%:多个任意字符
select *from stu where name like '马%';(姓马,马任意)
select *from stu where name like '_马%';第二个字为马
is null(null 不能使用=)(math is null)
and 或 &&
or 或 ||
not 或!
-
排序查询
- 语法:order by 字句
order by 排序字段1 排序方式1,排序字段2 排序方式2,...
排序方式:- ASC升序
- DESC降序
select * from student order by math desc,english asc;(若有一样的就会按english的方式排序)
聚合函数
将一列数据作为一个整体,进行纵向计算
-
count:计算个数
一般选择非空的列:主键
count(*)(只要有一个不为空就算) -
max:计算最大值
max(math) -
min:计算最小值
min(math) -
avg:计算平均值
avg(math)
聚合函数排除了nullselect count(name) from stu;
分组查询
- 语法:group by 分组字段
- 注意
分组之后查询的字段:分组字段,聚合函数
select sex,avg(math),count(id) from where math>70 student group by sex having count(id)>2;
where和having的区别
where:在分组之前对条件限制,不参与分组。后不能跟聚合函数
having:在分组之后对条件限制,不被查询出来。能跟聚合函数
分页查询
- 语法:limit开始的索引,每页查询的条数;
select * from student limit 0,3;
开始的索引=(当前的页码-1)*每页的条数
limit是mysql的方言
约束
- 是对表中的数据进行限定,保证数据的正确性,有效性和完整性
- 分类:
- 主键约束:primary key
- 非空约束:not null
- 唯一约束:unique
- 外键约束:foreign key
非空约束:not null
某一列的值不能为null
- 创建表时加约束
create table test(id int,name varchar(20) not null); - 创建表后添加非空约束
alter table stu modify name varchar(20) not null; - 删除非空约束
alter table stu modify name varchar(20);
唯一约束:unique
某一列的值不能重复
注意:
唯一约束可以有null值,但只能有一个
- 创建表时添加唯一约束:
create table stu (id int phone_number varchar(20) unique) - 创建表后添加非空约束
alter table stu modify phone_number varchar(20) unique; - 删除唯一约束
alter table stu drop index phone_number;
主键约束:primary key
- 注意:
- 含义:非空且唯一
- 一张表就能有一个字段为主键
- 主键就是表中记录的唯一标识
- 在创建表时添加主键约束
create table stu(id int primary key,
name varchar(20)); - 添加主键
alter table stu modify id primary key; - 删除主键
alter table stu drop primary key; - 自动增长
- 概念:如果某一列是数值类型的,使用auto_increment 可以完成自动增长
- 在创建表时,添加主键约束,并且完成自动增长
create table stu(id int primary key auto_increment,phone_number varchar(20));
insert into stu values(10,'ccc');
insert into stu values(null,'ccc');(null的位置会是11); - 删除自动增长
alter table stu modify id int;(主键删除不了就只能删除自动增长) - ALTER TABLE phone MODIFY id INT
外键约束:foreign key
- 在创建表时可以添加外键
- 语法:
create table 表名(
...
外键列,
constraint 外键名称 foreign key (外键列的名称) references 主表名称(主列表名称));
- 语法:
- 删除外键:
- alter table stu drop foreign ket 外键的名称;
- 添加外键:
- alter table stu add constraint 外键的名称 foreign key refercences 主表名称(主表列名称);
- 级联:
- 再添加外键的时候,在最后加上级联更新,级联删除
alter table stu add constraint 外键的名称 foreign key refercences 主表名称(主表列名称) on update cascade on delete cascade; - 级联更新:on update cascade
- 级联删除:on delete cascade
- 再添加外键的时候,在最后加上级联更新,级联删除
数据库的设计
- 多表之间的关系
- 数据库设计的范式
多表之间的关系
- 分类:
- 一对一:
- 如:身份证对人
- 一对多(多对一)
- 部门和员工:一个部门有多个员工,一个员工只能对应一个部门
- 多对多
- 学生和课程:一个学生可以选许多课程,一个课程也有许多学生
- 实现关系:
- 一对多(多对一)
- 在多的一方建立外键,来指向一的一方
- 多对多
- 多对多的关系实现需要借助第三张中间表,中间表至少包含两个字段作为第三张表的外键,分别指向两张表主键
- 一对一
- 可以在任意一方添加唯一外键指向另一方的主键
案例
旅游线路分类,旅游线路,用户
create table tap_categroy(
id int primary key auto_increment
,cate varchar(20) no null);
//线路分类表
create table tap_route(
id int primary key auto_increment,
name varchar(20) no null,
cate_id int,
foreign key (cate_id) references tap_categroy(id) on update cascade);
//线路表
create table user(
id int primary key auto_increment,
name varchar(20) no null,
phone int no null unique);
//用户表
create table t_user_route(
user_id int,
route_id int,
primary key(user_id,route_id),
foreign key (user_id) references user(id),
foreign key (route_id) references tap_route(id));
//联合表
设计数据库的范式
- 分类:
- 第一范式(1NF):每一列都是不可分割的原子数据项
- 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
- 函数依赖:A-->B,通过A属性的值,可以确定唯一B属性的值,则称B依赖A
例如:学号-->学生,(学号,课程)-->成绩 - 完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定依赖于A组所有的属性值
例如:(学号,课程)-->成绩 - 部分函数依赖:A-->B,A是一个属性组,B的确定需要A组的部分属性值来确定即可
例如:(学号,课程)-->姓名 - 传递函数依赖:A-->B,B-->C,通过A确定唯一B,在通过B确定唯一C,则C传递函数依赖于A
- 码:如果一个属性或一个属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
例如:通过(学号,课程)能确定所有的其他属性,故(学号,课程)为该表的码- 主属性:码属性组中的所有属性
- 非主属性:其他属性组的属性
- 函数依赖:A-->B,通过A属性的值,可以确定唯一B属性的值,则称B依赖A
- 第三范式(3NF):在2NF的基础上,任何非主属性不依赖于其他非主属性(2NF的记住上消除传递依赖)
数据库的备份和还原
- 命令行:
- 语法:mysqldump -u用户名 -p密码 数据库名称>保存路径
- 还原:
- 登录,创建,使用
- 执行文件。source 文件路径
注意编码要一致
- 使用Navicat Premium手动备份
多表查询
- 查询语法:
select
列名列表
from
表名列表
where... - 多表查询的分类
- 笛卡尔积:
- 有两个集合A,B,取两个集合的所有情况组合
- 要完成多表查询,就要消除无用的情况
- 分类:
- 内连接查询:
- 隐式的内连接:使用where条件消除无用的信息
select
t1.name,t2.name
from
t1,t2
where t1.'id'=t2.'id'; - 显式的内连接:
语法:select 字段列表 from 表名1 【inner】 join 表名2 on 条件
select * from
emp join dept
on emp.'id'=dept.'id'; - 内连接查询:
从哪些表中查询数据
条件是什么
查询哪些字段
- 隐式的内连接:使用where条件消除无用的信息
- 外连接查询:
- 左外连接:
语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
查询的是左表所有数据以及其交集 - 右外连接:select 字段列表 from 表1 right [outer] join 表2 on 条件;
查询的是右表所有数据以及其交集
- 左外连接:
- 子查询:
- 嵌套的查询就是子查询
- select * from emp where emp.'salary' =(select MAX(salary) from emp);
- 子查询的情况:
- 子查询的结果是单行单列的:
子查询可以作为条件,使用运算符去判断 <,>,<=等 - 子查询的结果是多行单列的:
子查询可以作为条件:使用in来判断 - 子查询的结果是多行多列的:
子查询可以作为一张虚拟表参与查询
select * from t1,(select id from t2 where id in(2,3)) t3 where t3.'id'=t1.'id'
- 子查询的结果是单行单列的:
- 内连接查询:
多表练习
- 查询所有员工信息。查询员工编号,姓名,工资,职务名称,职务描述
- 查询员工编号,姓名,工资,职务名称,职务描述,部门位置
- 查询员工姓名,工资,工资等级
- 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工作等级
- 查询出部门编号,部门名称,部门位置,部门人数
- 查询出所有员工的姓名及其直接上级的姓名,没有领导的员工也要查询
4
select
employee.emname,
employee.salary,
job.jobname,
job.description,
department.demane,
department.address,
salary_grade.id
from
employee,
job,department,salary_grade
WHERE
employee.job_id=job.id AND
employee.depart_id=department.id AND
employee.salary
between
salary_grade.losalary
and
salary_grade.hisalary;
6
select
t1.emname,
t1.MGR,
t2.emname
FROM
employee t1
left JOIN
employee t2
ON
t1.MGR=t2.id
事务
事务的基本介绍
- 概念:
如果一个包含多个步骤的业务操作,被事务管理,要么同时成功,要么同时失败 - 操作;
-
开启事务:start transcartion
-
回滚:rollback
-
提交事务:commit
start transaction;
commit;
rollback; -
Mysql数据库中的事务默认自动提交
事务提交的两种方式:- 自动提交:一条DML(增删改)语句会自动提交一次事务
- 手动提交:需要先开启事务,在手动提交
修改事务的默认提交方式:
- 查看事务的默认提交方式:select @@autocommit;1--代表自动提交
- 修改事务的默认提交方式:set @@autocommit=0;0--代表手动提交 oracle数据库默认手动提交
-
事务的四大基本特征
- 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性:事务结束后,数据库会持久的保存数据
- 隔离性:多个事务之间,相互独立
- 一致性:事务操作前后,数据总量不变
事务的隔离级别
-
概念:多个事务之间操作同一批事务,则会引发一些问题,设置不同的隔离级别就能解决问题
-
问题:
- 脏读:一个事务没有提交的数据
- 不可重复读(虚读):在同一个事务中两次读取的数据不一样
- 幻读:一个事务操作数据表中的所有记录,另一个添加数据,则第一个事务查询不到自己的修改
-
隔离级别:
- read uncommmitted:读未提交的
产生的问题:脏读,不可重复读,幻读 - read committed:读已提交的(Oracle默认的)
产生的问题:不可重复读,幻读 - repeatable read:可重复的(Myqsl默认的)
产生的问题:幻读 - serializable:串行化(上锁)
可解决所有问题
隔离级别从小到大安全性越高,效率越低
数据库查询隔离级别:
select @@tx_isolation;
数据库设置隔离级别:
set global transaction isolation level 级别字符串 - read uncommmitted:读未提交的
演示
DCL
管理用户,授权
管理用户
- 添加用户:create user '用户名'@'主机名' identified by '密码';
- 删除用户:drop user '用户名'@'主机名'
- 修改用户密码
- update user set password =password('新密码') where user ='用户名'
- set password for '用户名'@'主机名'=password('新密码');
- 查询用户:
切换到mysql:use mysql;
查询user表:select * from user;- 通配符:%表示任意用户登录(主机名)
忘记了密码
- 通配符:%表示任意用户登录(主机名)
- cmd-->net stop mysql停止服务
- 使用无验证启动mysql服务:mysqld --skip-grant-tables
- 打开新的cmd窗口,直接输入mysql命令,就能登录
- use mysql;update user set password = password('新的密码') where user ='root';
- 关闭那两个窗口,打开任务管理器,手动结束mysql,exe服务
- 启动mysql服务
- 使用新密码登录
权限管理
- 查询权限:show grants for '用户名'@'主机名';
- 授予权限:grand 权限列表 on 数据库名,表名 to '用户名'@'主机名'
grand select on db1.stu to 'root'@'%';
grand all on . to 'root'@'%'; - 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名'
JDBC
-
- 概念:java database connectivity java数据库连接,java语言操作数据库
- 本质:官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这接口编程,真正执行这套代码的是驱动jar包的实现类
2. 快速入门:
步骤:
- 导入驱动jar包
复制到某个目录下:mysql-connector-j-8.4.0.jar
右键--->add as library - 注册驱动
Class.forName("com.mtsql.jdbc.Driver"); - 获取数据库连接对象Connection
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","ROOT"); - 定义sql
String sql="update stu set name="王五" where id=1"; - 获取执行sql语句的对象Statement
Statement stmt=conn.createStatement(); - 执行sql,接受返回结果
int count = stmt(sql); - 处理结果
System.out.println(count); - 释放资源
stat.close();
conn.close();
3.详解各个对象
DriverManager:驱动管理对象
功能:
-
注册驱动:告诉程序要用什么接口
- state void registerDriver(Driver driver):注册与给定的驱动程序DriverManager
- 写Class.forName("com.mysql.jdbc.Driver");有静态代码块帮助其注册
- 注意:jar有注册驱动的,可不写
-
获取数据库的连接:
- 方法:state Connection getConnection(String url,String user,String password)
- 参数:指定链接线
- jdbc:mysql://ip地址(域名):端口号/数据库名称
- jdbc:mysql://localhost:3306/db2
- 若是本机可简写:jdbc:mysql:///数据库名称
- user:用户名
- password:密码
Connection:数据库连接对象
功能:
- 获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql) - 管理事务:
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
提交事务:commit()
回滚事务:rollback()
Statement:执行sql的对象
- 用于执行静态sql
- booolean execute(String sql)
- int executeUpdate(String sql):执行DML语句(insert Update,delete)语句,DDL语句(create,alter,drop)语句
返回值:影响的行数,可以判断DML语句是否执行成功,DDL语句无返回值 - ResultSet executeQuery(String sql):执行DQL(select)语句
ResultSet:结果集对象
- next():游标向下移动一行,判断当前行是否是最后一行,返回false,则是最后一行
- getxxx(参数):获取数据
xxx代表数据类型 如int i=c.getint();
参数- int:列的编号,从1开始。getString(1);
- String:代表列的名称。getString("name");
- 注意:
- 游标向下移动一行
- 判断是否有数据
- 获取数据
练习
- 定义一个Emp类
- 定义方法
public List<Emp> findAll(){} - 实现方法 select * from emp;
练习2
需求:
-
通过键盘录入用户名和方法
-
判断是否登录成功
select * from user where username=""and password"";
若sql的查询有结果,则成功
步骤:
- 创建数据库表user
PreparedStatement:执行sql的对象
SQL注入问题:在拼接sql时,有一些特殊的关键字参与字符串的拼接,会造成安全性问题
- 用户名随便,密码:a' or 'a'='a'
- sql: select * from user where username='www' and password = 'a' or 'a'='a'
-
使用preparedStatement对象来解决问题
-
预编译的sql:参数使用?作为占位符
-
PreparedStatement pre=Connection.PrepareStatement(stl);
-
给?赋值:
setXxx(参数1,参数2)
参数1:?的位置编号
参数2:?的值
执行时就不用赋值了
pstmt.setString(1,username)
pstmt.setString(2,password)
最终步骤:
-
导入驱动jar包
-
注册驱动
-
获取数据库连接对象Connection
-
定义sql
注意:select * from user where username=? and password =?
-
获取执行sql语句的对象,PreparedStatement stmt=conn.PrepareStatement(sql);
-
给?赋值
prep.setString(1,username)prep.setString(2,password)
-
执行sql不再传sql语句
-
处理结果
-
释放资源
抽取JDBC工具类:JDBCUtils
- 注册驱动也抽取
- 抽取方法获取连接对象
public static Connection getConnection(){}
public static void close(Statement stmt,Connection conn){}
JDBC控制事务
使用Connection对象来管理事务
- 开始事务:setAutoCommetion(boolean aUtoCommit):调用方法设置参数为false 即开启事务
- 在sql执行之前开启事务
- 回滚:rollback()
- 在异常中回滚事务
- 提交事务:commit()
- 当所有sql执行完后提交事务
数据库连接池
概念:是一个容器(集合),存放数据库连接的容器
当系统初始化好后,容器会申请一些连接对象,当用户来访问数据库时,从容器中链接对象,用户访问完成之后,会将连接对象归还给容器
好处:节约资源,用户访问高效
实现:
- 标准接口:DateSource javax.sql包下的
方法:- 获取连接:getConnection()
- 归还连接:如果链接对象是从连接池中获取的,那么connection.close()方法则不会关闭连接,而是归还
- 一般我们不去实现它,有数据厂商去实现
- C3P0:数据库连接池技术
- Druid:数据库连接池实现技术,阿里巴巴提供
C3P0连接池技术
- 导入jar包两个:c3p0-0.9.5.5.jar和mchange-commons-java-0.2.19.jar
- 定义配置文件
- 名称:c3p0.properties或c3p0-config.xml
- 路径:直接将文件放在src目录下
3.创建核心对象:数据库连接池对象ComboPooledDataSource
4.获取连接:getConnection
druid连接池技术
步骤:
1.导入jar包druid.jar
2.定义配置文件:
是properties的形式
可以叫任意名称,放在任意目录下
-
获取数据库连接池对象:通过工厂来获
DruidDataSourceFactory
DataSource ds=DruidDataSourceFactory.createDataSource(pro) -
获取连接:getConnection()
定义一个工具类 -
定义一个类 JDBCUtils
-
提供静态代码块加载配置文件,初始化连接池对象
-
提供方法
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
Spring JDBC:JDBC Template
- Spring框架对JDBC的简单封装,提供了一个JDBCTemplated对象简化JDBC的开发
- 步骤:
- 导入jar包
- 创建jdbcTemplate对象,依赖于数据源DataSource
JdbcTemplate template=new JdbcTemplate(DataSource ds) - 调用JdbcTemplate的方法来实现CRUD的操作
- update():执行DML语句。增删改
- queryForMap():查询结果将结果集封装为map集合
- queryForList():查询结果将结果封装为List集合
- query():查询结果,将结果封装为JavaBean对象
- queryForObject(sql,Object):查询结果,将结果封装为对象
练习:
需求
- 添加一号数据的salary 为10000
- 添加一条记录
- 删除刚才的记录
- 查询di为1的记录,将其封装为Map集合
- 查询所有记录,将其封装为List集合
- 查询所有记录将其封装为Emp对象的List集合
- 查询总记录数
Web概念概述
- javaweb
- 软件架构:
1.c/s架构:Client/Server 客户端/服务器端- 在用户本地有一个客户端,在远程有一个服务器端程序
- 如qq...
- 优点:用户体验好
- 缺点:开发,安装,部署,维护麻烦
- B/S:Browser/Server 浏览器/服务器端
- 只需要一个浏览器,用户就可以访问不同的网址
- 优点:开发,安装,部署,维护简单
- 缺点:应用过大,用户体验可能受到影响,对硬件要求过高
B/S架构详解
- 资源分类:
1.静态资源
使用静态资源开发的网页
特点:- 所有用户访问的结果一样
- 如:文本,图片,HTML,CSS,JavaScript
- 如果用户请求静态资源服务器会直接将静态资源发送给浏览器。浏览器内置了解析引擎,可以展示静态资源
- 动态资源
使用动态网页及时发布的资源
特点:
- 所有用户访问的结果可能不一样
- 如:jsp/servlet,php,asp...
- 如果用户请求的是动态资源,那么服务器会执行动态资源,再转换成静态资源,发送给浏览器
- 静态资源:
- HTML:用于搭建基础网页,展示页面的内容
- CSS:用于美化页面,布局页面
- JavaScript:控制页面的元素,额那个页面有一些动态的效果
HTML
概念:
是最基础的网页编程语言
- Hyper Text Markup Language 超文本标记语言
超文本:使用超链接的方法来,将不同空间的文字信息组织到一起的网状文本
标记语言:由标签构成的语言。<标签名称>如html,xml
标记语言不是编程语言
*** 快速入门
语法
- html文档后缀名.html或.htm
- 标签分为:
* 围堵标签:有开始和结束标签。如<html></html>
* 自闭和标签:开始标签和结束标签在一起。如<br/>
- 标签可以嵌套:
* 需要正确的嵌套,不能你中有我,我中有你
* 错误:<a><b></a></b>
* 正确:<a><b></b></a>
4. 在开始标签中可以自定义属性。属性有键值对构成,只需要用引号(单双都可以)引起来
5. 在html中不区别大小写,但建议小写
- 标签学习
文件标签
* html:html文档的根标签
* head:头标签。用于指定hrml文档的一些属性。引入外部类
* title:标题标签
* body:体标签
* <!DOCTYPE>?
文本标签
* 注释:<!-- 内容-->
* <h1> to <h6>:标题标签 h1字体最大
* <br>:换行
* <p>:段落标签
* <hr>:显示一条水平线
* <hr color="red",width(宽度)="200",size(高度)="10",align(对齐方式)="center(居中)">
* <b>:字体加粗
* <i>:字体斜体
* <font>:字体标签
属性:
* color:颜色
* size:大小
* face:字体
属性定义:
* color:
英文单词:red,green,blue
三原色(红绿蓝)rgb*(值1,值2,值3):0~255,rgb(1,1,232)
#值1值2值3:00~FF,如#00FFFF
* width:
1. 数值:width='20',数值的单位默认是px(像素)
2. 数值%:占比父元素的比例
图片标签:
* img标签
src:指定图片的位置
相对路径
* 以.开头
* ./:代表当前目录
* ../:代表退一个目录
列表标签
* 有序列表:
ol:定义有序列表
li:项
* 无序列表:
ul:定义无序列表
li:项
*定义列表
<dl>:自定义列表
<dd>:项
链接标签
a:定义一个超链接
* 属性:
href:能指定访问资源的URL(统一资源定位符)
target:制定打开资源的方式
1. _self:在本页面内打开
2. —blank:在空白页面打开
div和span
div:会换行,每一个div占满一整行,块级标签
span:文本信息在一行展示,行内标签 内联标签
语义化标签
- header2. footer
表格标签
<table>:定义表格
属性:
borde:边框
width:宽度
cellpadding:定义内容和单元格之间的距离
cellspacing:定义单元格之间的距离,若为0则单元格的线会合为一条
bgcolor:背景色
align:对齐方式
<tr>:定义行
* bgcolor
* align:所有文本的对其方式
<td>:定义单元格
* colspan:合并列
* rowspan:合并行
<th>:定义表头单元格
<caption>:表格标题
<thead>:表示表格的头
<tbody>表示表格的体
<tfoot>:表示表格的脚
表单标签
概念:用于采集用户输入的数据的用于和服务器用于交互
使用的标签:
* form:用于定义表单的。可以定义一个范围,范围代表采集用户数据的范围
* 属性:
* action:指定提交数据的URL
* method:指定提交方式
get:
1. 请求参数会在地址栏中显示
2. 请求参数的大小有限制
3. 不太安全
post:
1. 请求参数不会再地址栏中显示,会封装在请求体中(HTTP)协议中
2. 请求参数大小没有限制
3. 安全
表单项中的数据要想被提交,要指定其name属性
表单项:
* input:可以通过type的属性值,来改变元素样式
label:指定输入项的文字描述信息
* type:
* for属性一般会会和input的ID对应,则点击lable会让input输入框获取焦点
text:文本输入框,默认值
* placeholder:指定输入框的内容,当输入框发生变化会自动清空提示信息
password:密码输入框
radio:单选框
* 注意:要想让多个单选框实现单选的效果,则多个单选框的name属性值要一样
* 一般会给每一个单选框一个value值,来提交
checkbox:复选框
* checked:可以指定默认值
* 一般会给每一个多选框一个value值,来提交
file:文件选择框
hidden:隐藏域,用于提交一些信息
submit:按钮,可以提交表单
button:按钮普通
image:图片提交按钮
* src可以指定图片
date:日期
emlie:电子邮件
number:数字
* select:下拉列表
option:指定列表项
* textarea:文本域
cols:每行的字符,列数
rows:几行,行数
<form action="#" method="post">
<table border="1" align="center" width="500">
<tr>
<td><label for="1" >用户名: </label></td>
<td><input type="text" name="username" id="1"></td>
</tr>
<tr>
<td>
<label for="password">密码:</label>
</td>
<td>
<input type="text" name="password" id="password">
</td>
</tr>
<tr>
<td> <label>性别</label> </td>
<td> <input type="radio" name="gender" value="male">男
<input type="radio" name="gender" value="female">女</td>
</tr>
<tr>
<td> <label for="date"> 日期</label> </td>
<td> <input type="date" name="date" id="date"> </td>
</tr>
<tr>
<td>
<label for="checkword">验证码:</label>
</td>
<td>
<input type="text" name="checkword" id="checkword">
<img src="../../public/priture/QQ图片20231009195134.jpg" width="50">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="注册">
</td>
</tr>
</table>
</form>
旅游网站的首页
- 确定布局,table
- 如果某一行只有一个单元格,则使用
<td><tr></td></tr> - 如果某一行有多个单元格,则使用表格嵌套
<tr><td> <table></table><tr><td>
css
页面美化和布局控制
-
概念:cascadiong style sheets 层叠样式表
层叠:多个样式可以作用在同一个html上,同时生效 -
好处:
功能强大,将内容的展示和样式控制分离
降低耦合度,可以提高工作效率,可以协调分工 -
css的使用:css与 html的结合
内联样式: 在标签内使用style属性指定css代码
内部样式:在head标签内定义style标签,style的标签体内容就是css代码
如:
<style> div{ color:blue}<style><div>hellow css<div>外部样式:
定义css资源标签
在head标签内定义link标签,引入外部的资源文件
a.css文件:div{color:green;} <link rel="stylesheet" href="css/a.css" div hellow<div> style>@import "css/a.css";<style> //注意:1,2,3种方式作用范围越来越大
语法:
格式:选择器{
属性名1:属性值1;
...
}
选择器:筛选具有相似特征的元素
注意
* 每一对属性需要使用;隔开最后一对属性可以不加;
选择器
-
分类:
基本选择器:
1. ID选择器:选择器具体的ID属性值的元素:建议 在一个html中的id是唯一的
语法:#id属性值{}<div id="div1"></div><div>hellow</div>#unique-paragraph { font-size: 20px; }通过元素的
id属性来选择元素。ID 名前要加一个井号(#)。ID 在 HTML 文档中必须是唯一的。2. 元素选择器:选择具有相同名称的元素 标签名称{} 注意:id选择器比元素选择器级别更高p { color: blue; }2. 类选择器 语法: .class属性值{} 注意:类选择器的优先级比元素选择器高.red-text { color: red; } -
扩展选择器:
1. 选择所有元素 : *{}
2. 并集选择器:选择器1,选择器2{}
3. 子选择器:选择器1 选择器2。筛选1下的2
4. 父选择器:选择器1>选择器2 筛选2的父选择器1
5. 属性选择器:选择元素名称,属性名=属性值的元素
元素名称[属性名=“属性值”]{}
6. 伪类选择器:选择元素的状态
元素:状态
如:<a>
状态:
link:初始状态
hover:鼠标悬浮
active:正在访问
visited:被访问过了 -
属性
- 文本,字体
font-size:字体大小
color:文本颜色
text-align:对齐方式
line-height:行高 - 背景
background:url color no-repeat center
3. 边框
border:
4. 尺寸
width:宽度
height:高度
5. 盒子模型:控制布局
margin:外边距
padding:内边距
默认情况下内边距会影响盒子的大小
box-sizing:border-box;设置盒子的属性,让width和height就是盒子的最终的大小
float:浮动
left
right
- 文本,字体
案例注册页面
JavaScript
概念:一门客户端脚本语言
- 运行在客户端浏览器中,每一个浏览器都有JavaScript的解析引擎
- 脚本语言:不需要编译,直接就可以被浏览器解析执行了
功能:
- 可以来增强用户和html页面的交互过程,可以来控制元素,让页面有一些动态的效果,增强用户的体验
javaScript发展史:
- 1992年,Nombase公司,开发出第一门客户端脚本语言,专门用于表单的校验,为c--,更名为ScriptEase
- 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LiveScript.后来请sun公司的人来开发为JavaScript
- 1996年,微软抄袭JavaScript开发出JScript语言
- 1997年,ECMA(欧洲计算机制造商协会),ECMAScript,就是所有客户端脚本语言的标准
JavaScript=ECMAScript+javaScript自己特有的东西(BOM+DOM)
ECMASricpt:
客户端脚本语言标准
1基本语法:
与html的结合方式
-
内部JS:
<script>script语句的代码《script》 -
外部JS:dingyiscript标签通过src引入外部的js文件
注意《script》可一定要在任何的地方,但是定义的位置会影响执行顺序
《script》可以定义多个
注释
- 单行注释://
- 多行注释:/* */
数据类型
-
原始数据类型(基本数据类型):
numder:数字。整数/小数/NaN(not a number 不是一个数字的数字类型)
string:字符串。"abc"
boolean:true false
null:对象为空
undefined:未定义。若未有初始化,则默认赋值为undefined
-
引用数据类型:对象
变量
-
变量:一小块存储数据的内存空间
-
java是强类型的语言,javaScritp是弱类型的语言
在开辟变量存储空间时定不定义数据类型,不定义可存储任意类型的数据
-
var 变量名=值(定义变量都是用这个)
-
typeof()查看数据类型
-
document.write():在页面内输出
-
alert(a):在页面弹出
<script>
function ad(a,b){
return a+b;
} var b=ad("asd",44);
alert(b);
function fid(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum=sum+arguments[i];}return sum;}
var a=fid(22,34,231,"333","saa");
document.write(fid(22,34,543,453,"fas"));
alert(a);
var a=+"12asdf";
document.write(a+1);
document.write("</br> <hr>")
var b=222+"2asd";
document.write(b); document.write("</br> <hr>")
var c=typeof(b)
document.write(c);
var fal=+true;
alert(fal);
</script>
运算符
-
一元运算符:
++,--,+(正号)
在js中运算数不是运算符所要求的,js引擎会自动进行类型转换
其他类转number:
- string转number:按照字面值转换,字面值不是数字会转成NaN
- boolean转number:true为1,false为0
-
算术运算符
+,-,*,/,%
-
赋值运算符
=,+= -=
-
比较运算符
< > >= <= == ===(全等)
类型相同:直接比较
字符串:按照字典顺序比较,按位逐一比较,直到得出大小为止
类型不同:先进行类型转换,再比较
===全等。在比较之前先判断类型,若不一样则直接放回false
-
逻辑运算符
&& || !
其他类型转boolean:
- number:0或NaN为假,其他为真
- string:除了空字符串(" "),其他都为true
- null&undefined:都是false
- 对象:都是true
-
三元运算符
? :表达式 a=b>c?b:c
流程控制语句:
-
if...else
-
switch:
在java中可以接收的数据类型:byte,int,shor,char
在JS中什么都可以接受
-
while
-
do...while
-
for
JS特殊语法:
-
语句以;结尾,如果一行只有一条语句;可以省略(不建议)
-
变量定义使用var关键字,也可以不一样
使用:定义的是局部变量
不用:定义的是全局变量(不建议)
2对象
基本对象:
Function:函数(方法)对象
-
创建:
var fun = new Function(形参,方法体);
function 方法名称(形参列表){}
var 方法名 = function(形参){}
-
方法
-
属性:
length:长度
-
特点:
方法定义时类型不用写
方法是一个对象,会覆盖
在JS中方法的调用只与方法名称有关,和参数无关
在方法声明中,会有一个内置对象(数组),argument,封装所有的实际参数
-
调用:
方法名称(实际参数列表)
Array:数组对象
-
创建:
var arr=new Array(元素列表);
var arr =new Array(默认长度);
var arr = [元素列表];
-
方法
join(拼接的参数,(如,-等)):将数组中的元素拼接成字符串
push(参数):向数组尾部添加元素并返回新的长度
-
属性
length:长度
-
特点
- JS中元素类型可变
- JS中数组的长度是可变的
Boolean:基本数据类型的包装类
Date:日期对象
-
创建
var date=new Date();
-
方法
toLocaleString():返回当前date对象对应的时间本地字符串格式
getTime():获取毫秒值。返回当前对象描述的时间到1970年1月1日0点的毫秒差
Math:数学对象
-
创建
- 特点:Math不用创建,直接使用 Math.方法名()
-
方法
random():返回0~1的随机数,含0不含1
ceil(x):对数进行上舍入
floor(x):对数进行下舍入
round(x):把数四舍五入为最接近的整数
-
属性
- PI:圆周率
-
例:var number=Math.floor((Math.random()*100))+1
Number
String
RegExp:正则表达式对象
-
正则表达式:定义字符串的组成规则的
单个字符:[ ] [a] [ab] (a或b) [a-z] (a到z)
- 特殊符号代表特殊含义的单个字符
- \d:单个字符[0-9]
- \w:单个单词字符[a-zA-Z0-9_]
量词符号:\w{8,18}
-
?:表示出现0次或1次
-
*:出现0次或多次
-
+:出现1次或多次
-
{m,n}:表示m<=数量<=n
m如果缺省:{,n}:最多n次
n如果缺省:{m,}:最少m次
-
创建:
var reg=new RegExp("正则表达式");
var reg = /正则表达式/;
var reg= /^\w{5-56}$/
开始结束符号:^开始$结束
-
方法:
test(参数):验证指定字符串是否符合规则
Global
-
特点:全局对象,不需要对象就可以直接调用
方法名()
-
方法:
encodeUPI():url编码
decodeUPI():url解码
encodeUPIComponent():url编码,编码的字符更多
decodeUPIComponent():url解码,编码的字符更多
eval():将JS的字符串作为脚本代码去实现
isNaN():判断是否是NaN
- NaN六亲不认,NaN参与的==比较都为false
parsdeInt():将字符串转为数字
- 逐一判断每一个字符是不是数字,直到不是数字停止,将前面的数字转为number
BOM
- 概念:Borwser Object Model 浏览器对象模型
- 将浏览器的各个组成部分封装成各个对象
- 组成:
-
Navigator:浏览器对象
-
window:窗口对象
-
创建:
-
方法:
与弹出框有关
-
alert():显示带有一段消息和一个确认按钮的警告框
-
confirm():显示带有一段消息以及确定和取消按钮的对话框
点击确认按钮,返回true
点击取消按钮,返回false
-
prompt("可写提示的内容"):显示可提示的输入框
返回值:获取用户输入的值
与打开关闭有关
-
open("网址"):打开一个新窗口
-
close():关闭窗口
关闭调用的窗口,让open("")赋值给一个对象,用它调用close,关闭那个窗口
与定时器有关的方法:
-
setTimeout():指定一个时间后执行一个函数,一次性的
参数:
第一个为方法或js代码,
第二个为时间,毫秒值1s=1000毫秒
返回值:唯一标识,用于取消定时器
-
clearTimeout():取消由setTimeout设定的定时器
-
setInterval():循环定时器
-
clearInterval():取消定时器
-
案例:var r=setTimeout("alert("aq")",2000);clearTimeout(r);
-
-
属性:
获取其他BOM对象
- history
- screen
- location
- Navigator
获取DOM对象 document.write()
-
特点:
window对象不用创建直接使用,window.方法名()
window可以不用引用
-
-
Screen:显示器屏幕对象
-
History:历史记录对象
-
创建:
window.history
history
-
方法
back():加载history列表中的前一个URL
forward():加载history列表中的下一个URL
go(参数):加载history列表中的某个具体的页面
参数:
- 正数:前进多少个历史记录
- 负数:后退多少个历史记录
-
属性
- lebgth:返回当前窗口的历史浏览记录,中的URL个数
-
-
Location:地址栏
-
创建:
window.location
location
-
方法
relaod():重新加载,刷新
-
属性
href:获取当前的地址
var href=location.href;
location.href="https://www.baidu.com"
-
轮播图
分析:
- 在页面上使用img展示图片
- 定义一个方法修改图片的src属性
- 定义一个定时器,每个三秒调用一次方法
自动跳转首页
分析:
- 显示页面效果
<p> - 定义一个方法修改时间
- 倒计时读秒,使用定时器
DOM
概念:文档对象模型
- 将标记文档封装为各个对象
W3C DO标准 - 分为3部分
-
核心DOM针对任何结构化文档的标准模型
- Document:文档对象
- Element:元素对象
- Attribute:属性对象
- Text:文本对象
- Comment:注释对象
- Node:节点对象,其他5个父类对象
-
XML DOM- 针对XML文档的标准模型
-
HTML DOM--针对HTML文档的标准模型
核心DOM模型:
-
Document:文档对象
创建:在html中可以使用window对象来获取
- window.document
- document
方法:
-
获取Element对象
getElementsById():根据id属性获取元素对象
getElementsByTagName():根据(标签名称)元素名称获取元素对象,返回值是一个数组
getElementsByClassName():格局Class属性获取元素对象。返回值是一个数组
getElementsByName():根据name属性获取元素对象们
-
创建其他DOM对象:
createAttribute(name):属性
createComment():注释
crteateElement():元素
createTextNode():文本
-
Element:元素对象
获取
- 通过document来获取和创建
方法
- removeAttribute():删除属性
- setAttribute(属性,属性值):设置属性
-
Node:节点对象,其他5个父类对象
特点:所有dom对象都可以作为节点
方法
CRUD dom树
- appendChild(节点):向节点的子节点添加新的子节点
- removeChild(节点):删除当前节点的子节点 div1.removeChild(div2)
- replaceChild():用新节点替换子节点
属性:
parentNode:返回父类节点
案例
动态表格
分析:
-
给添加按钮绑定单击事件
-
获取文本框的内容
-
创建td,设置td的文本为文本框的内容
-
创建tr
-
将td添加到tr中
-
获取table
<a href="javascript:void(0)">
删除:
-
确定是哪个超连接
a href="javascript:void(0);"onclick = "delete(this);"
-
删除:removeChild();通过父标签parentNode
HTML DOM模型
-
标签体的设置和获取:innerHTML
-
使用html元素对象的属性
-
设置样式
使用元素的style属性来设置
- div1.style.border="1px solic red"
提前定义好类选择器的样式,通过元素的className属性来实现设置器的class的属性值
- div1.classNate="d1";
功能:控制html文档的内容
代码:获取页面标签(元素)对象Element
- document.getElementByd("id"):通过元素的id获取元素的对象
操作Elment对象
- 修改属性 .属性
- 修改标签体的内容 .innerHTML
事件
事件的监听机制
事件:某些操作,单击,双击
事件源:组件,按钮 文本输入框
监听器:代码
注册监听:将事件,事件源,监听器集合在一起。当事件源上发生了某个事件,则会触发执行某个监听器代码
功能:某些组件被执行某些操作或,就会出发一些代码的执行
如何绑定事件:
-
直接在html标签上,指定某些事件的属性(操作),属性值就是JS代码
事件:
点击事件:
- onclick---单击事件
- ondbclivk--双击事件
焦点事件:
-
onblur:失去焦点
一般用于表单校验
-
onfocus:元素获得焦点
加载事件
-
onload:一张页面或一副图像完成加载
window.onload=function(){}
鼠标事件
-
onmousedown:鼠标按钮被按下
定义一个方法时,定义一个形参,event对象
event对象的button属性可以可以获取鼠标按钮被点击了
-
onmouseup:鼠标按钮被松开
-
onmousemove:鼠标被移动
-
onmouseover:鼠标移动到某个元素
-
onmouseout:鼠标从某元素移开
键盘事件
- onkeydown:某个键盘按键被按下
- onkeyup:某个键盘按键被松开
- onkeypress:某个键盘按键被 按下并松开
选择和改变
- onchange:域的内容被选中
- onselect:文本被选中
表单事件
-
onsumbit:确认按钮被点击
可以阻止表单被提交
- 方法返回false则表单被阻止提交
-
onreset:重置按钮被点击
-
通过js获取属性,指定事件属性,设置一个函数
练习:
-
获取图片对象
-
绑定一个单机事件
-
每次点击切换图片
表格练习
- 表格
- 在页面加载完后绑定事件
- 给全选绑定单击事件
- 获取所有checkbox
- 遍历cb,设置每一个cb的状态为选中 cbs.checked=true;
- 反选:本身为非。第一个cb点击:获取所有的cb设置所有的cb的状态都和第一个一样
- 给所有tr绑定鼠标移到元素之上和移除的事件:换颜色
表单校验
-
给表单绑定onsubmit事件。监听器中判断每一个方法校验的结果
若都为true,则返回true
若都为false,则返回false
-
定义一些方法分别校验各个表单项
获取用户名的值,定义正则表达式
判断值是否符合规范,提示信息
-
给各个表单项绑定onblure事件
Bootstrap:前端开发的框架
框架:一个半成品软件,开发人员可以在此基础上进行开发
好处:开发简洁
-
定义了很多的css样式和js插件
-
响应式布局
可以兼容不同的分辨率尺的
入门:
下载bootstrap
在项目中将这两份文件夹复制过来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css">
<title>Hello World with Bootstrap</title>
<script src="js/jquery-3.6.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1 class="mt-5">Hello World!</h1>
<p class="lead">This is a simple example using Bootstrap.</p>
</div>
</body>
</html>
响应式布局
同一套页面可以兼容不同分辨率的设备
实现:依赖于栅格系统:将一行平均分成12个格子,可以指定元素占几个格子
步骤:
-
定义容器:相当于之前的table
容器分类:
- container:固定宽度,有留白
- container-fluid:每一种设备都是100%宽度
-
定义行,相当于之前的tr 样式:row
-
定义元素,指定该元素在不同设备上所占的格子数目。 样式:col-设备代号-格子数目
设备代号:
- xs:超小屏幕 手机(<768px):col-xs-12
- sm:小屏幕 平板(>768px)
- md:中等屏幕 桌面显示器(>=992px)
- lg:大屏幕 大桌面显示器(>12000px)
div calss="col-lg-1 col-sm-2"
注意:
一行中如果格子数目超过12,则超出部分自动换行
栅格类属性可以向上兼容,栅格类适用于屏幕宽度大于或等于的设备
如果正式设备宽度小于了设置栅格类属性的设备代码的最小值,会一个元素占满一整行
css和js的插件
全局css样式:
-
按钮:class="btn btn-default"
-
图片:
class="img-fluid":图片在任意尺寸都占100%
图片形状:
- img src="..." alt="..." class="rounded":方的
- img src="..." alt="..." class="rounded-circle":圆的
- img src="..." alt="..." class="img-thumbnail":相框
-
表格
table
table-bordered
table-hover
-
表单
给表单添加项:class="from=control"
组件:
- 导航条
- 分页条
插件:
- 轮播图
案例:黑马旅游网
XML
概念
概念
可扩展标记语言
- 可扩张:标签都是自定义的《user》
功能
存储数据
- 配置文件
- 在网络中传输
xml与html的区别
w3c:万维网联盟
- xml标签都是自定义的,html标签都是预定义
- xml的语法严格,hrml语法松散
- xml是存储数据的,html是展示数据
语法
基本语法
- xml文档的后缀名 .xml
- xml第一行必须定义为文档声明
- xml文档中有且仅有一个根标签
- 属性值必须使用引号单双都可以
- 标签必须正确关闭
- xml标签名称区分大小写
快速入门
<?xml version='1.0'?>
<users>
<user id='1'>
<name>zhansan</name>
<age>22</age>
<gender>male</gender>
</user>
</users>
组成部分
-
文档声明
-
格式:
<?xml 列表属性 ?> -
属性列表
-
version:版本号,必须的属性
-
encoding:编码方式。告知解析引擎 当前文档使用的字符集,默认值:ISO-8859-1
-
standalone:是否独立
取值:
- yes:不依赖其他文件
- no:依赖其他文件
-
-
-
指令(了解):结合css的
<?xml-stylesheet type="text/css" href="a.css"?>
-
标签:自定义的
规则:
- 名称可以包含字母数字及其他字符
- 名称不可以以数字或标点符号开始
- 名称不能以字母xml (或XML Xml等)开始
- 名称不能有空格
-
属性
id属性值唯一
-
文本
- CDATA区:在该区中的水会被原样展示
- 格式:
<![CDATA[数据]]>
谁编写xml?-用户,软件使用者
谁解析xml?-软件
约束:
规定xml文档的书写规则
作为框架的使用者(程序员):
- 能够在xml中引入约束文档
- 能够简单的读懂约束文档
分类:
- DTD:简单的约束技术
- Schema:复杂的约束技术
DTD
-
引入dtd文档到xml文档中
内部dtd:将看看约束规则定义在xml文档中
外部dtd:将约束的规则定义在外部的dtd文档中
- 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置"
- 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名" "dtd文件的位置URL"
Schema
引入:
- 填写xml文档的根元素
- 引入xsi前缀。xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 引入xsd文件命名空间.xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
- 为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itcast.cn/xml"
<students xmlns:sxi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml"
xsi:schemaLocation="http://www.itcast.cn/xml student.xsd" >
解析
操作xml文档,将文档中的数据读取得到内存中
操作xml文档
- 解析(读取):将文档中的数据读取到内存中
- 写入:将内存中的数据保存到xml文档中,持久化保存
解析xml的方式
-
DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树
- 优点:操作方便,可以对文档进行CRUD的所有操作
- 缺点:占内存
-
SAX:逐行读取,基于事件驱动的
- 优点:不占内存
- 缺点:只能读取,不能增删改
xml常见的解析器
- JAXP:sun公司提供的解析器,支持dom和sax两种思想
- DOM4J:一款非常优秀的解析器
- jsoup:是java的解析HTML的解析器,可解析xml
- PULL:android(安卓)操作系统内置的解析器,sax方式的
JSOUP
jsoup是一款java的html的解析器,可直接解析URL地址,html文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似与jQuery的操作方法来取出和操作数
快速入门
步骤:
- 导入jar包
- 获取Document的对象
- 获取对应的标签Element对象
- 获取数据
代码:
-
获取student.xml的path(地址)
-
解析xml文档,加载文档进内存,获取dom树--->Document
Document document = Jsouip.parse(new File(path),"utf-8");
-
获取元素对象Element
Elements elements=document.getElementsByTag("name");
Syste.out.println(element.size());
-
获取第一个name的Element对象
Element element=element.get(0);
-
获取数据
string name=element.text();
System.oput.println(name);
对象的使用
Jsoup
:工具类,可以解析html或xml文档,返回Document
- pares:解析html或xml文档,返回Document
- parse(File in,String charsetName):解析xml或html文件的
- parse(String html):解析xml或html字符串的
- parse(URL url,int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
Document
:文档对象,代表内存中的dom树
获取Element对象
- getElementById(String id):根据id属性中获取唯一的element对象
- getElementByTag(String tagName):根据标签名获取element对象集合
- getElementByAttribute(String key):根据属性名获取的element对象集合
- getElementByAttributeValue(String key,String value):根据对应的属性名和属性值获取element对象
Elements
:元素Element对象的集合,可以当做ArrayList<Element>来使用
Elements
:元素对象
获取子元素对象
-
getElementById(String id):根据id属性中获取唯一的element对象
- getElementByTag(String tagName):根据标签名获取element对象集合
- getElementByAttribute(String key):根据属性名获取的element对象集合
- getElementByAttributeValue(String key,String value):根据对应的属性名和属性值获取element对象
获取属性值
- String attr(String key):根据属性名获取属性值
获取文本内容
- String text():获取所有子标签的纯文本内容
- String html():获取标签体的所有内容(包括子标签的字符串内容)
Node
:节点对象
- 是Document和Element的父类
快速查询
-
selector:选择器
使用方法:Elements select(String cssQuery)
- 语法参考Selector类中定义的语法
Elements elements=document.select("student[number='hema001']");
-
XPath:
即xml路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言
- 使用Jsoup的XPath需要额外导入jar包
- 查询w3cshool参考手册,使用xpath的语法完成查询
- List
<JXNode>jxNodes2=jxDocument.selN("//student/name[@id='ithema']")
web知识回顾
软件架构
- C/S:客户端/服务器端
- B/S:浏览器/服务器端
资源分类:
-
静态资源:所有用户访问或,得到的结果是一样,称为静态资源.可以直接被浏览器解析
如:html,css,javaScript
-
动态资源:每个用户访问相同的资源后,得到的结果可能不同,称为动态资源。动态资源被访问后要先转换成静态资源,再返回给浏览器
如:servlet/jsp,php,asp...
网络通信三要素:
-
ip:电子设备在网络中的唯一标识
-
端口:应用程序在计算机中的唯一标识。0~65536
-
传输协议:规定了数据传输的规则
基础协议:
- tcp:安全协议,三次握手。速度稍慢
- udp:不安全协议,速度快
web服务器软件:Tomcat
服务器
安装了服务器软件的计算机
服务器软件:接收用户的请求,处理请求,做出回响
web服务器软件:接收用户的请求,处理请求,做出回应
- 在web服务软件中,可以部署web项目,让用户通过浏览器那访问这些项目
- web容器
常见的java相关的web服务器软件
- webLoic:oracle公司,大型的javaEE服务器,支持所有的javaEE规范,收费的
- webSphere:IBM公司的,大型的javaEE服务器,支持所有的javaEE,收费的
- JBOSS:JBOSS公司的,大型的javaEE服务器,支持所有的javaEE规范,收费的
- Tomcat:Apache基金组织的,中小型的javaEE服务器,仅仅支持少量的javaEE规范servlet/jsp.开源的,免费的
javaEE:java语言在企业级开发中使用的技术规范的总和,一共规定了13大的规范
Tomact:web服务器软件
-
安装
-
卸载
-
启动:bin/startup.bat,运行
访问:在浏览器输入:http://loaclhost:8080 回车访问自己,http://别人的id:8080 回车访问别人
可能遇到的问题:
-
黑窗口:没有正确配置JAVA_HOME环境变量
-
启动报错:端口号被占用在.cdm终端中输入netstat -ano找到端口号用任务管理器来结束进程
修改自身端口号:
conf/server.xml
<Connect port="8888"
一般默认将tomcat的默认端口修改为80.80是http协议的默认端口
-
-
关闭:
-
正常关闭:
bin/.shutdown.bat
ctrl+c
-
强制关闭:关闭启动窗口
-
-
配置:
部署项目的方式:
-
直接将目录放到webapps中
/hellow:项目的访问路径-->虚拟目录
简化部署:将项目打成一个war包,再将war部署到
-
配置conf/server.xml文件
在
<HOST>标签体中配置<Context docBase="D:\hellow" path="/hehe"/>docBase:项目存放的目录
path:虚拟目录
-
在conf\Catalina\locahost创建任意名称的xml文件,在文件中编写
<Context docBase="D:\hellow"/>虚拟目录:xml文件的名称
-
bin:可执行文件
conf:配置文件
lib:依赖jar包
logs:日志文件
temp:临时文件
webapps:存放web项目
work:存放运行时的数据
静态项目和动态项目
-
目录结构
java动态项目的目录结构
-
项目目录
WEB-INF
- web.xml:该目录的核心配置文件
- Classes目录:放置字节码文件
- lib目录:放置项目依赖的jar包
-
将Tomcat集成到idea
Servlet:
运行在浏览器中的小程序
概念
servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则
将来我们定义一个类,实现Servlet接口,复写方法
快速入门
-
创建javaEE的项目
-
定义一个类,实现Servlet接口
public class ServletDemo1 implements Servlet
-
实现接口中的抽象方法
-
配置Servlet
在web.xml中配置:
<servlet> <servlet-name>demo1</servlet-name> <servlet-class>cn.itcast.web.servlet.ServletDemo1(路径名)</servlet-class> </servlet> <servlet> <servlet-name>demo1</servlet-name> <url-pattern>/demo1</url-pattern> </servlet>

### Servlet中的生命周期:
1. 被创建:执行init方法,只执行一次
Servlet什么时候被创建,默认情况只在第一次访问被创建
* 可以配置执行Servlet的创建时机
* 在``<servlet>``标签下配置
* 第一次被访问时创建:``<load-on-startup>``的值为负数
* 在服务器启动时创建:``<load-on-startup>``的值为0或为正整数
Servlet的方法,只执行一次说明一个Servlet在内存中值存在一个对象,Servlet是单例的
* 多个用户同时访问时,可能存在线程安全问题
* 解决:尽量不要在Servlet中定义成员变量,及时定义了也要对其值进行修改
2. 提供服务:执行servlet方法,执行多次
每次访问Servlet时,Servlet方法都会执行一次
3. 被销毁:执行destroy方法,值执行一次
Servlet被销毁前执行,服务器关闭前执行
只有服务器正常关闭,才会执行destory方法
### Servlat3.0:
好处:支持注解配置,可以不需要web.xml了
步骤:
1. 创建javaEE项目,选择servlet的版本3.0以上,不创建web.xml
2. 定义一个类,实现Servlet接口
3. 复写方法
4. 在类上使用@webServlet注解,进行配置
@webServlet("资源路径")
#### 在idea上创建javaEE
#### idea与Tomcat的配置
idea会为每一个项目单独建立一份配置文件
* 查看控制台的log:Using CATALINA_BASE:"\Users\xiaoxin\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\8f4ca39d-150c-4247-858d-4451ff19700b"
工作空间项目 和 tomcat部署的web项目
* tomcat真正访问的是“tomcat部署的web项目”,"tomcat部署的web项目"对应这"工作空间项目"的web目录下的所有资源
* WEB-INF目录下的资源不能被浏览器直接访问
* 断点调试:使用小虫子启动dubug启动
## 体系结构
Servlaet ---接口
|
GenericServlet --- 抽象类
|
HttpServlet ---- 抽象类
GenericServlet:将Servlet接口中的其他方法作了默认空处理,只剩Servlet()方法作为抽象方法
* 将来定义Servlet类时,可以继承GenericServlet,实现servlet()方法即可
HttpServlet:对http协议的一种封装,简化操作
1. 定义类继承HttpServlet
2. 复写doGet和doPost方法
3. 可以在from中定义action=资源路径,method="get"或"post"
#### Servlet相关配置
1. urlpartten:Servlet访问路径
一个Servlet可以定义多个访问路径:@webServlet({"/d4","/dd4","/ddd4"})
路径定义规则:
1. /xxx
2. /xxx/xxx:多层路径,目录结构
3. *.do: *是任意字符优先度较低
## HTTP
### 概念
超文本传输协议
传输协议:定义了,客户端和服务器端通信时发送数据的格式
特点:
1. 基于TCP/IP的高级协议
2. 默认端口:80
3. 基于请求/响应模型的:一次请求一次响应
4. 无状态的:每次请求之间相互独立,不能交互数据
历史版本:
* 1.0:每一次请求响应都会建立新的连接
* 1.1:复用连接,等一会若还有数据传输,就会仍使用这个连接
### 请求消息数据格式
1. 请求行
请求方式 请求url 请求协议/版本
GET /topost和toget.html(资源路径) HTTP/1.1
请求方式:HTTP协议有7种方式,常用的有两种
* GET:
1. 请求参数在请求行中,在uil后
2. 请求的uil长度有限制的
3. 不太安全
* POST:
1. 请求参数在请求体中
2. 请求的uil长度没有限制
3. 相对安全
2. 请求头:客户端告诉浏览器一些信息
请求头名称:请求头值
常见的请求头:
1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
可以服务器端获取该头的信息,解决浏览器兼容性的问题
2. Referer:http://localhost/login.html
告诉服务器,我(当前请求)从哪里来?
* 作用
防盗链:放置被盗去超链接
统计工作:统计从各处请求来这的个数
3. 请求空行
空行,就是用来分割POST请求头和请求体的
4. 请求体(正文)
* 用来封装POST请求消息的请求参数的
* get没有请求体
## Request

#### Request对象和Response对象的原理
1. request和response对象是由服务器创建的,我们只是使用它
2. request对象是来获取请求消息的,response对象是来设置响应消息的
#### resquest对象继承体系结构
ServletRequest --- 接口
| 继承
HttpServletRequest --- 接口
| 实现
org.apache.catalina.connector.ResquestFacade 类(tomcat 创建这个类的对象来传递给它)
#### request功能
1. ##### 获取请求消息数据
获取数据请求行数据
GET /day14/demo1?name=zhangsan HTTP/1.1
方法:
1. 获取请求方式:GET
String getMethod()
2. (*)**获取虚拟目录**:/day14
String getContextPath()
动态获取虚拟目录
3. 获取Servlet路径:/demo1
String getServletPath()
4. 获取get方式的参数:name=zhangsan
String getQueryString()
5. (*)**获取请求URI:/day14/demo1**
String getRequestURI():/day14/demo1
URL:统一资源定位符:http://loaclhost/day14/demo1 (中华人民共和国)
String getRequestURL():hppt:/localhost/day14/demo1
URI:统一资源标识符:/day14/demo1 (共和国)
6. 获取协议及版本:HTTP/1.1
String getProtocol()
7. 获取客户机的IP地址
String getRemoteAddr()
2. ##### 获取请求头数据
方法:
* (*)String getheader(String name):通过请求头的名称获取请求头的值
* Eumeration``<String> ``getHeaderNames():获取所有的请求头名称
3. ##### 获取请求体数据:
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
1. 获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据
ServletInputStream getInputStream():获取字节输入流,可操作所有数据
2. 在从流中拿数据
while((reader=br.readline())!=null){
System.out.println(reader);}
#### 其他功能
##### 获取请求参数通用方式
不论get还是post方式,都能使用
this.dopost(request,response)
1. String getParamater(String name): 根据参数名称获取参数值 username=zs&password=123
2. String[] getParameterValues(String name):根据参数名称获取参数值数组 hobby=xx&hobby=game
3. Enumeration``<String>`` getParameterNames():获取所有的请求的参数名称
4. Map<String,String[]> getParameterMap():获取所有参数的map集合
5. 中文乱码问题
get方式:tomcat 8 已经将乱码解决了
post方式:解决:在获取参数前,设置request.setCharacterEncoding("utf-8");
##### 请求转发
一种在服务器内部的资源跳转的方式
步骤:
1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
2. 使用RequestDispatcher 对象进行转发:forward(ServletRequest request,SrevletRespone response)
3. req.getRequestDispatcher (/test1_6).forward(req,res);
特点:
1. 浏览器地址栏路径不会发生改变
2. 只能转到当前服务器内部资源
3. 转发是一次请求
##### 共享数据
域对象:一个有范围的对象,可以在范围内共享数据
request域:代表一次请求,一般用于请求转发的多个资源中共享数据
方法:
1. void setAttribute(String name,Object obj):存储数据
2. Object getAttitude(String name):通过键获取值
3. void removeAttribute(String name):通过键移除键值对
##### 获取ServletContext
ServletContext getServletContext()
###### 用户登录
需求:
1. 编写login.html登录页面
username&password 两个输入框
2. 使用Druid数据库连接池技术,操作mysql,day14数据库中的user表
3. 使用JDBCTemplate技术封装JDBC
4. 登录成功跳转到SuccessServlet展示:登录成功!用户名欢迎你
5. 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
分析:

开发步骤:
1. 创建项目,导入html页面,配置文件,jar包
1. 创建数据库环境
1. 创建包cn.itcast,domain,创建User类
1. 创建UserDao,提供login方法,操作User表的类
BeanUtils工具类,简化数据封装
用于封装JavaBean的
1. javaBean:标准的java类
要求:
1. 类必须被public修饰
2. 必须提供空参的架构器
3. 成员变量必须使用private修饰
4. 提供公共setter和getter方法
功能:封装数据
2. 概念:
成员变量:
属性:setter和getter方法截取或的产物
例如:getUsername() --->Username ----->username
3. 方法:
1. setProperty()
2. getProperty()
3. populate(Object obj,Map map):将map集合的键值对信息,封装到对应的jacaBean对象中
## HTTP协议
### 请求消息
客户端发送给服务器端的数据
数据格式:
1. 请求行
2. 请求头
3. 请求空行
4. 请求体
### 响应消息:
服务器端发送给客户端的数据
#### 数据格式
##### 响应行
组成:协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端浏览器本次请求和回响的一个状态
1. 状态码都是3位数
2. 分类:
1. 1xx:服务器接收到客户端消息,但还没有接收完成,等待一段时间后,发送1xx多的状态码
2. 2xx:成功,代表:200
3. 3xx:重定向。代表302(重定向(跳转)),304(访问缓存(本地缓存))
4. 4xx:客户端错误
代表:
404(请求路径没有对应的资源)
405:请求方式没有
5. 5xx:服务器端错误。代表500(服务器出现异常)
##### 响应头
1. 格式:头名称:值
2. 常见的响应头:
1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
* 值:
* in-line:默认值,在当前页面内打开
* attachment;filename=xxx:以附件形式打开响应体。常用于文件下载
##### 响应空行
##### 响应体
页面代码
响应字符串格式
HTTP/2.0 200 OK
Content-type:text/html;charser=UTF-8
## response对象
功能:设置响应消息
1. 设置响应行
1. 格式:HTTP/1.1 200 ok
2. 设置状态码:setStatus(int sc)
2. 设置响应头:setHeader(String name,String value)
setContentType("text/hrml;charset=utf-8")
3. 设置响应体:
使用步骤:
1. 获取输出流
字符输出流:PrintWriter()
字节输出流:ServletOutputStream getOutputStream()
2. 使用输出流,将数据输出到客户端浏览器
案例:
1. 完成重定义
资源跳转的一种方式
代码实现:
* response.setStatus(302);设置状态码
* response.setHeader("location","/day18/response2")设置响应头location
* response.sendRedirect("/day18/response2");//简单的重定义
重定向的特点:redirect
1. 地址栏发生变化
2. 重定向可以访问其他站点(服务器)的资源
3. 重定向是两次请求,不能使用request对象共享数据
转发的特点:forward
1. 转发地址栏不变
2. 转发只能访问当前服务器下的资源
3. 转发只是一次请求,可以使用request对象共享数据
路径写法:
1. 路径分类:
相对路径:通过相对路径不可以确定唯一资源
* 如:./index.html
* 不以/开头,以.开头路径
* 规则:找到当前资源和目标资源之间的相对位置关系
* ./:表示当前目录
* ../:后退一级目录
绝对路径:通过绝对路径可以确定唯一资源
* 如:http://location/day18/responseDemo2 /day18/respoonseDemo2
* 以/开头的路径
规则:判断定义的路径是给谁用的?判断请求是从哪里发出的
* 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
建议虚拟目录动态获取:request.getContextPath()
``<a>,<form>``,重定向
* 给服务器使用:不需要加虚拟目录
转发路径
2. 服务器输出字符数据到浏览器:文本
获取字符输出流
PrintWriter pw=response.getWriter()
输出数据
pw.write("你好啊 response")
乱码问题:
* PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
* 设置该流的默认编码
* 告诉浏览器响应体使用的编码
都是在获取流之前设置的
response.setContentType("text/html;charset=utf-8")
3. 服务器输出字节数据到浏览器:图片等
获取字节输出流
ServletOutputStream sos=response.getOutputStream();
输出数据
sos.write("你好".getBytes("utf-8"))(中文默认的是GBK)
乱码问题:response.setContentType("text/html;charset=utf-8")
4. 验证码
本质:图片
目的:防止恶意表单注册
创建对象,在内存存图片(验证码图片对象)
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
美化图片
1. 填充背景色
Graphics g=image.getGraphics()//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,0,width,height);
2. 画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width-1,height-1);
3. 写验证码
String str="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
Random ran=new Random();
for(int i=1;i<=4;i++){
int index = ran.nextInt(str.length());//获取随机字符索引
char ch=str.charAt(index);//获取字符
g.drawString(ch+"",width/5*i,height/2);//写验证码}
4. 画干扰线
g.setColor(color.GREEN)
生成随机坐标点
for(int i=0;i<10;i++){
int x1=ran.nextInt(width);
int x2=ran.nextInt(width);
int y1=ran.nextInt(height);
int y2=ran.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
将图片输出到页面
ImageIO.write(image,"jpg",response.getOutputStream())
分析:点击图片或超链接更换
1. 给超链接和图片绑定单击事件
2. 重新设置图片的src属性值
img src="" id=cher
window.onload=function(){
var img=document.getElement("cher");
img.onclick=function(){
var date = new Date().getTime();
img.src="xxxx?"+date;}}
## ServletContext对象
### 概念
代表整个web应用 ,可以和程序的容器(服务器)来通信
### 获取
通过request对象获取
request.getServletContext();
通过HTTPServlet获取
this.getServletContext();
### 功能
#### 获取MIME类型
MIME类型:在互联网通信过程中定义的一种文件数据类型
* 格式:大类型/小类型 text/html image/jpeg
获取:String getMineType(String file)//文件名
#### 域对象
共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
ServletContext对象范围:所有用户所有请求的数据
#### 获取文件的真实(服务器)路径
方法:
String b=context.getRealPath("/b.txt");//web目录下资源访问
String c=context.getRealPath("/WEB-INF/b.txt");//WEB-INF目录下的资源访问
String a=context.getRealPath("/WEB-INF/classes/a.txt")
###### 案例:
文件下载:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
分析:
1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析则弹出下载提示框,不能满足需求
2. 任何资源都必须弹出下载提示框
3. 使用响应头设置资源的打开方式
content-disposition:attachment;filename=xxx
步骤:
1. 定义页面,编辑超链接href属性,指向Servlet,(?)传递资源名称filename
2. 定义Servlet
1. 获取文件名称
2. 使用字节输入流加载文件进内存
3. 指定response的响应头:content-disposition:attachment(以附件的形式打开);filename=xxx
4. 将数据写出到response
问题:
中文文件名问题
* 解决思路:
获取客户端使用的浏览器版本信息
根据不同版本信息,设置filename的编码方式不同
```java
String file=req.getParameter("filename");
ServletContext context = getServletContext();
String path=context.getRealPath("/picture/"+file);
System.out.println(path);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(path));
ServletOutputStream out = resp.getOutputStream();
String mine = context.getMimeType(file);
resp.setHeader("content-Type", mine);
resp.setHeader("Content-disposition", "attachment; filename=\""+file+"\"");
int length=0;
byte[] buffer=new byte[1024];
while((length=bis.read(buffer))!=-1){
out.write(buffer,0,length);
}
bis.close();
}
```
## 会话技术
1. 会话: 一次会话中包含多次请求和响应
* 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
2. 功能:在一次会话的范围内的多次请求间,共享数据
3. 方式:
* 客户端会话技术:Cookie
* 服务器端会话技术:Session
### Cookie
概念:客户端会话技术,将数据保存到客户端
快速入门:
1. 创建Cookie对象,绑定数据
* new Cookie(String name,String value)
2. 发送Cookie对象
* response.addCookie(Cookie cookie)
3. 获取Cookie,拿到数据
* Cokkkie[] request.getCookies()
实现原理:
* 基于响应头set-cookie和请求头cookie实现
cookie的细节
1. 一次可以发送多个Cookie对象,使用response调用多次addCookie方法发送Cookie即可
2. cookie在浏览器中的保存时间
默认情况下,当浏览器关闭或,cookie数据被销毁
持久化存储:
* setMaxAge(int seconds)
1. 正数:将cookie数据写到硬盘的文件中。持久化存储,cookie的存活时间
2. 负数:默认值
3. 零:删除cookie信息
3. cookie能不能存中文
在tomcat8之前cookie中不能直接存储中文数据
* 需要将中文数据转码----一般采用URL编码(%E3)
在tomcat之后,cookie支持中文数据
4. cookie共享问题
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享
* 默认情况不能共享
setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
* 如果要共享,则可以将path设置为"/"
不同的tomcat服务器之间cookie共享
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
* setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
Cookie的特点
1. cookie存储数据在客户端浏览器
2. 浏览器对于单个cookie的大小有限制(4kb)以及对同一个域名下的总cookie数量也有限制(20个)
作用:
1. cookie一般用于储存少量的不太敏感的数据
2. 在不登录的情况下,完成服务器对客户端的身份识别
###### 案例
记住上一次访问时间
需求:
1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
2. 如果不是第一次访问,则提示:欢迎回来,您上次访问的时间为:显示时间字符串
分析:
1. 可以采用cookie来完成
2. 在服务器中的Srevlet判断是否有一个名为lastTime的cookie
1. 有:不是第一次访问
响应数据:欢迎回来,您上次访问的时间为:2018年6月10日8:50:01
写回Cookie:lastTime=2018年6月10日11:50:01
2. 没有:是第一次访问
响应数据:你好,欢迎您首次访问
写回Cookie:lastTime=2018年6月10日11:50:01
### Session
概念:在服务器端会话技术,在一次会话中的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
##### 快速入门
1. 获取HttpSession对象
HttpSession session = request.getSession();
2. 使用HttpSession对象
Object getAttribute(String name)
void setAttribute(String name,Object value)
void removeAttribute(String name)
session.getId()
##### 原理
Session的实现是依赖于Cookie的
会在第一次响应中给响应头一个Session的id,之后会一直在请求头中携带,通过id来找到这个Session
##### 细节
当客户端关闭后,服务器不关闭,两次获取session是否为同一个
* 默认情况下不是
* 如果需要相同,可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie c=new Cookie("JSESSIONID",session.getId())
c.setMaxAge(60*60);
response.addCookie(c)
当客户端不关闭,服务器关闭后,两次获取的session是同一个吗
* 不是同一个,但是要确保数据丢失
* session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
* session的活化:在服务器启动后,将session文件转化为内存中的session对象即可
* tomcat会自动完成这个,但idea不会
session什么时候被销毁
1. 服务器关闭
2. session对象调用invalidate()
3. session默认失效时间 30分钟
选择性配置修改
``<session-config>``
``<session-timeout >30<session-timeout>``
``</session-config>``
##### 特点
1. session用于存储一次会话的多次请求的数据,存在服务器端
2. session可以存储任意类型的没有数据大小限制。Cookie有限制
3. session数据安全,Cookie相对不安全
###### 案例
验证码:
1. 访问带有验证码的登录页面login.jsp
2. 用户输入用户名,密码以及验证码
* 如果用户名和密码有误,跳转登录页面,提示:用户名或密码错误
* 如果验证码输入有误,跳转登录页面,提示验证码错误
* 如果全部输入正确,这跳转到主页success.jsp,显示:用户名,欢迎你

## JSP
#### 概念
java Servlet Pages:java服务器端页面
一个特殊页面,其中既可以指定定义html标签,有可以定义java代码
#### 原理
jsp本质上就是一个servlet
#### JSP的脚本
jsp定义java代码的方式
1. <% 代码 %>:定义的java代码,在sevlet方法中,servlet方法中可以定义什么,脚本中就可以定义什么
2. <%! 代码 %>:定义的java代码,在jsp转换或的java成员位置
3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本就可以定义什么
#### JSP的内置对象
在jsp页面中不需要获取和创建,可以直接使用的对象
jsp一共有9个内置对象
* response
* request
* out:字符输出流对象,可以将数据输出到页面上
#### 指令
用于配置JSP页面,导入资源文件
格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2...%>
分类:
1. page:配置JSP页面的
contentType:等同于response.setContentType()
1. 设置响应体的mine类型以及字符集
2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果是使用低级工具,这需要设置pageEncoding属性设置当前页面的字符集)
import:导包
errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
inErrorPage:标识当前页面是否是错误页面
* true:是,可以使用内置对象exception
* false:否。默认值,不可以使用内置对象exception
2. include:页面包含的,导入页面的资源文件
* <%@include file="toip.jsp"%>
3. taglib:导入资源
* <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
#### 注释
1. html注释:<!-- -->只能注释html代码片段
2. jsp注释:<%-- --%>:可以注释所有,在源码中都不会显现
#### 内置对象
在jsp页面中不需要创建,直接使用的对象
一共有9个:
| 变量名 | 真实类型 | 作用 |
| ----------- | ------------------- | -------------------------------------------- |
| pageContext | PageContext | 当前页面共享数据,还可以获取其他八个内置对象 |
| request | HttpServletRequest | 一次请求访问的多个资源(转发) |
| session | HttpSession | 一次会话的多个请求间 |
| application | ServletContext | 所有用户间共享数据 |
| response | HttpServletResponse | 响应对象 |
| page | Object | 当前页面(Servlet)的对象tjis |
| out | JspWriter | 输出对象,数据输出到页面上 |
| config | ServletConfig | Servlet的配置对象 |
| exception | Throwable | 异常对象 |
# MVC开发模式

## MVC
1. M:Model,模型.JavaBean
* 完成具体的业务操作,如:查询数据库,封装对象
2. V:View,视图.JSP
* 展示数据
3. C:Controller,控制器。Servlet
* 获取用户的输入
* 调用模型
* 将数据交给视图
优缺点:
1. 优点:
1. 耦合性低,方便维护,可以利于分工协作
2. 重用性高
2. 缺点:
1. 使得项目架构复杂,对开发人员要求高
## EL表达式
概念:Expression Language 表达式语言
作用:替换和简化jsp页面中java代码的编写
语法:${表达式}
注意:
* jsp默认支持el表达式的,如果要忽略el表达式
1. 设置jsp中的page指令中:isELIgnored="true"忽略当前jsp页面中的所有el表达式
2. \ ${表达式}:忽略当前这个el表达式
使用:
1. 运算:
* 运算符:
算术运算符:+,-,*,/(div),%(mod)
比较运算符:> < >= <= == !=
逻辑运算符:&&(and) ||(or) !(not)
空运算符:empty
* 功能:用于判断字符串,集合,数组对象是否为null并且长度是否为0
* ${emply list}
2. 获取值
el表达式只能从域对象中获取值
语法:
${域名.键名}:从指定的域中获取指定键的值
* 域名称:
| 名称 | 实际 | 作用 |
| ------------ | :---------- | ------------------------------------------------------------ |
| 名称 | 实际 | 作用 |
| pageScope | pageContext | `PageContext`代表当前 JSP 页面的上下文环境,生命周期与当前 JSP 页面的执行周期一致 |
| requestScope | request | 代表一次 HTTP 请求的范围。在一个请求处理过程中,多个组件(如 Servlet、Filter、JSP)可以通过这个作用域共享数据。这个作用域的生命周期是整个请求处理过程 |
| sessionScope | session | 代表用户的会话范围。在用户与服务器的一次会话期间,多个请求可以共享数据。 |
举例在resquest域中存储了name=张三
获取:${requsetScope.name}
${键名}:表示依次从最小的域中查询是否有该键对应的值,直到找到为止
获取对象:List集合的值。Map集合的值
1. 对象:${域名称.键名.属性名}
* 本质上会去调用对象的getter方法
2. List集合:
* ${域名称.键名[索引]}
3. Map集合
* ${域名称.键名称.ket名称}
* ${域名称.键名称["ket名称"]}
隐式对象:
* el表达式中有11隐式对象
* pageContext:
获取jsp其他八个隐式对象
${pageContext.requset.contextPath}:动态获取虚拟目录
## JSPL
### 概念
jsp标志标签库
### 作用
用于简化和简化jsp页面上的jar包
### 使用步骤
1. 导入jstl相关jar包
2. 引入标签库:tablib指令:<%@ taglib %>
3. 使用标签
### 常见的JSTL标签
#### if
相当于java代码的if语句
##### 属性
test为必须属性,接受boolean表达式
* 如果表达式为true,则显示if标签体内容。如果为false,这不显示标签体内容
* 一般情况下test属性值会结合el表达式一起使用
##### 注意
c:if 标签没有else情况,想要else情况,则可以定义一个c:if 标签
#### choose
相当于java中的Switch语句
1. 使用choose标签声明------------------------相当于Switch
2. 使用when标签声明做判断------------------相当于case
3. 使用otherwise标签做其他情况的声明---相当于default
#### foreach
相当于java中的for语句
1. 完成重复的操作
for(int i=0;i<10;i++){}
属性:
* begin:开始值
* end:结束值
* var:临时变量
* step:步长
* varStatus:循环状态对象
* index:容器中的元素的索引,从0开始
* count:循环次数,从1开始
2. 遍历容器
``List<User> list;``
``for(User user:list){}``
属性:
* items:容器对象
* var:容器中的临时变量
* varStatus:循环状态对象
* index:容器中的元素的索引,从0开始
* count:循环次数,从1开始
## 三层架构:
1. 界面层(表示层):用户看的见的界面,用户可以通过界面上的组件和服务器进行交互
2. 业务逻辑层:处理业务逻辑的
3. 数据访问层:操作数据存储文件的

### 案例
#### 分析
1. 需求:用户信息的查询和修改
2. 设计:
1. 技术选型:Servlet+JSP+Mysql+JDBCTempleat+Duird+BeanUtils+tomact
2. 数据库选型:
3. 开发:
1. 搭建环境
1. 创建数据库环境
2. 创建项目,导入需要的jar包
2. 编码
4. 测试
5. 部署运维
#### 开发
##### UserListServlet
1. 调用service层的findAll().返回List集合。List<User>
2. 将List集合存入requset域中
3. 转发list.jsp页面展示
UserService service = new UserServiceImpl();
list.jsp
foreach标签遍历list集合生成表格table

##### 添加

##### 删除

##### 修改

##### 删除选中

##### 分页查询


多条件组合加查询

## filter
:过滤器
web中的过滤器:当访问服务器的资源的时候,过滤器可以将请求拦截下来,完成一些特殊的功能
### 作用
:一般用于完成一些同样的操作。如:登录验证,统一编码处理,特殊字符过滤等操作
### 快速入门
#### 步骤
1. 定义一个类,实现一个接口Filter
2. 复写方法
3. 配置拦截路径
web.xml
注解
#### 代码
````java
@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
pulic void init (FilterConfig filterConfig) throws ServletExcption{}
public void doFiler(ServletRequest servletRequest,ServleResponse,FilterChain filterChain)
throws IOException,ServletException{
System.out.println("filterDemo1被执行了...");
filterChain.doFilter(servletRequest,servletResponse);}
public void destroy(){}
过滤器细节
web.xml配置
<filter>
<filter-name>daom1<filter-name>
<filter-class>cn.itcast.web.filter.FilterDome1</fiilter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping
过滤器执行流程
执行过滤器
执行放行后的资源
回来执行过滤器放行下的代码
public void doFiler(ServletRequest servletRequest,ServleResponse,FilterChain filterChain) throws IOException,ServletException{
//放行之前就会被执行
System.out.println("filterDemo1被执行了...");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//放行之后被执行
System.out.println("放行了")
}
过滤器生命周期方法
- init:在服务器启动后,会创建Filter对象,然后调用inti方法。只执行一次,用于加载资源
pulic void init (FilterConfig filterConfig) throws ServletExcption{}
- doFilter:每一次请求被拦截资源时会执行,可以执行多次
public void doFiler(ServletRequest servletRequest,ServleResponse,FilterChain filterChain)
throws IOException,ServletException{
System.out.println("filterDemo1被执行了...");
filterChain.doFilter(servletRequest,servletResponse);}
- destroy:在服务器关闭后,Filter对象被销毁。如果服务器时正常关闭,则会执行destroy方法,只执行一次。用于释放资源
public void destroy(){}
过滤器配置详解
拦截资源路径配置:
-
具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器在回被执行
@WebFilter("/index.jsp") -
拦截目录:/user/* 访问/user下的所有资源时过滤器都会被执行
@WebFilter("/user/*") -
后缀名拦截:*.jsp 不要写/ 访问所有后缀名为jsp资源时,过滤器都会执行
@WebFilter("*.jsp") -
拦截所有资源:/* 访问所有资源时,过滤器都会执行
@WebFilter("/*")
拦截方式配置
@WebFilter(urlPatterns="/*",filterName="abc",dispatcherTypes = DispatcherType.REQUEST)
//uripatterns:过滤器拦截的路径
//filterName:过滤器的名称
//dispatcherTypes:过滤器拦截的方式
-
注解配置:设置dispatcherTypes属性
REQUEST:默认值,浏览器直接请求资源
- dispatcherTypes=DispatcherType.REQUEST
FORWAD:转发访问资源
- dispatcherTypes=DispatcherType.FORWAD
INCLUDE:包含访问资源
- dispatcherTypes=DispatcherType.INCLUDE
ERROR:错误跳转资源
- dispatcherTypes=DispatcherType.ERROR
ASYNS:异步访问资源
- dispatcherTypes=DispatcherType.ASYNS
-
web.xml配置
设置
标签即可
过滤器链(配置多个过滤器)
过滤器的先后顺序:
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
- 如:ADDlter和BDDlter,ADDlter就会先执行,再比如Acl3和Acl17,Acl17会先执行1<3
- web.xml配置:
谁定义在上边,谁先执行
执行顺序:如果有两个过滤器:过滤器1和过滤器2:
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
案例
案例1
登录验证:
需求:
- 访问day1_case案例的资源,验证其是否登录
- 如果登录,则直接放行
- 如果没有登录就跳转到登录页面,提示“您还未登录请先登录”。
分析:
- 判断是否登录相关的资源
- 是,直接放行
- 不是,判断是否登录
- 判断当前用户是否登录,判断Session中是否会有User
- 是,已经登录
- 没有,有没登录,跳转到登录页面
代码
public void doFilter(ServletRequest req,Servlet resp,FilterChain chain)throws ServletException{
// 强制转换
HttpServletRequest request = (HttpServletRequest) req;
//获取资源请求路径
String uri = request.getRequestURI();
//判断是否包含登录的相关资源,要注意排查掉css/js/图片/验证码等资源
if(uri.contains("/login.jsp")||uri.contains("/loinServlet")||uri.contains("/css/")||uri.contain("/js/")||uri.contain("/")){
//包含,用户是想登录,放行
chain.doFilter(req,resp);
}else{
//不包含,需要验证用户是否登录
//从session中获取user
Object user = request.getSession().getAttribute("user");
if(user!=null){
chain.doFilter(req,resp);}else{
//没有登录,跳转登录页面
request.setAttribute("login_msg","您尚未登录,请登录");
request.getRequestDispacher("/login.jsp").forward(request,resp);
}
}
}
敏感词汇过滤
要想让req中的数据改变:你是坏蛋-->你是**
方法:
- 对req对象的getParameter方法进行增强产生一个新的request对象
- 放行。将新的request对现场传入
chain.doFilter(req,resp);
增强对象的功能:
设计模式:一些通用的解决固定问题的方式
-
装饰模式
-
代理模式
概念:
- 真实对象:被代理的对象
- 代理对象:
- 代理模式:代理对象代理真是对象,达到增强真实对象的目的
实现方式:
- 静态代理:有一个类文件描述代理模式
- 动态代理:在内存中形成代理类
实现步骤:
- 代理对象和真实对象实现相同的接口
- 代理对象 = Proxy.newProxyInstance();
- 实现代理对象调用方法
- 增强方法
public class ProxyTestP{
//创建真实对象
Lenovo lenovo =new Lenovo();
//动态代理增强lenovo对象
/*
三个参数:
1. 类处理器,真实对象.getClass().getClassLoader()
2. 接口数组,真实对象.getClass(),getInterfaces()
3. 处理器:new InvocationHandle(){}匿名内部类
*/
Proxy.newProxyInstance(lenovo.getClass.getClassLoader(),lenovo.getClass(),getInterfaces(),new InvocationHandle(){
/*
代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法的执行
参数:
1. proxy:代理对象
2. method:代理对象调用的方法,被封装为的对象
*/
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
System.out.println("该方法执行了.....")
return null;
}
});
String computer = lenovo.sale(8000);
System,out.println(computer);
}
监听器
概念
:web的三大组件之一
事件监听机制
- 事件:一件事情
- 事件源:事件发生的地方
- 监听器:将事件,事件源,监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码
监听器对象:
ServletConrtextListener:监听ServletContext对象的创建和销毁
方法:
- void contextDestroyed(ServletContextEvent sce): SerletContext对象被销毁之前会调用该方法
- void ContextInitialized(ServletContextEvent sce):ServletContext对象创建后会调用该方法
步骤:
- 定义一个类,实现ServletContextListener接口
- 复写方法
- 配置
- web.xml
- 注解
先在web.xml配置文件配置键
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<context-param>
//键的名称
<param-name>contextConfigLocation</param-name>
//资源文件的地址在classes下的地址
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
</web-app>
package ContextListent;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class contextListent implements ServletContextListener {
/**
* 监听ServletContext对象创建的。ServletContext对象服务器启动后自动创建
* 在服务器启动后自动调用
* @param sce
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
//加载资源文件
//1. 获取SwevletCOntext对象
ServletContext servletContext = sce.getServletContext();
//2加载资源文件
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//加载进内存
try {
FileInputStream fis = new FileInputStream(realPath);
System.out.println(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("ServletContext被创建。。。");
}
/**
* 在服务器关闭后,ServletContext对象被销毁,服务器正常关闭后该方法被调用
* @param sce
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了。。。");
}
}
JQuery
概念
一个javaScript框架。简化js开发
优化了HTML文档操作,事件处理,动画设计和Ajax交互
快速入门
JQuery对象和JS对象区别与转换
选择器
DOM操作
案例
AJAX
概念:异步的javaScript和xml
异步和同步:客户端和服务器端相互通信的基础上
- 同步:客户端必须等待服务器端的响应不能做其他操作
- 异步:客户端不需要等待服务器端的响应,在服务器处理请求的过程中,客户端可以进行其他的操作
Ajax是一种在无需重新加载整个页面的情况下,能更新部分页面的技术,提升用户体验
JSON
JavaScript对象表示法
在java中的对象表示使用
Person p=new Person();
p.setName("张三");
p.setAge(23);
var p={"name":"张三","age":"23"};
json现在多用于存储和交换文本信息的语法
进行数据的传输
json比xml更小,更快,更易解析。
语法
基本规则
数据在名称/值对中:json数据是由键值对构成的
键用引号引起来,也可以不使用引号
键值对类型:
- 数字(整数或浮点数)
- 字符串:(在双引号中)
- 逻辑值(true或false)
- 数组(在方括号中) {"persons":[{},
- 对象(在花括号中){"address":{"procince":"陕西"....}}
- null
数据由逗号分隔:多个键值对由逗号分隔
花括号保存对象:使用{}定义json格式
方括号保存数组:[]
Redis
概念
redis是一款高性能的NOSQL系列的非关系型数据库
NOSQL泛指非关系型数据库各个数据之间没有关系

浙公网安备 33010602011771号