javawed基础

javaweb

  1. junit单元测试
  2. 反射
  3. 注解

测试:

  • 黑盒测试:运行看不见,不需要写代码,看程序是否输出期望值
  • 白盒测试:需要写代码。关注具体流程。看的见

junit测试:白盒测试

步骤:

  1. 定义一个测试类

    测试类名:被此时的类名Test, CalculatorTest

    包名:xxx.xxx.xx.test cn.it.test

  2. 测试方法:可以独立运行

    方法名:test测试的方法名 testAdd()

    返回值:void

    参数列表:空参

  3. 给方法加注解@Test

  4. 导入包依赖环境

    一般使用断言来处理结果

    Assert.assertEquals(expect(期望的),actual(实际的));

两个注解:

  • @Before:修饰的方法会在测试方法之前被自动执行

    • public void init(){}
  • @After:修饰的方法会在测试方法之后自动执行

    • public void close(){}
  • @Test:不需要main方法就能使用

反射

框架设计的灵魂

  • 框架:半成品软件。科一在框架的基础上进行一些软件开发,简化编码
  • 反射:将类的各个组成部分封装为其他对象,这就是反射机制

好处:

  1. 可以在程序有运行中操作这些对象
  2. 可以解藕,提高程序的可操作性

image-20240724114249906

获取class方式

  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
    • 多用于配置文件,将类名定义在配置文件中。读取文件,加载类(字符串)
  2. 类名.class:通过类名的属性获取
    • 多用于参数的传递
  3. 对象.getClass():getClass()方法在Object类中定义
    • 多用于对象的获取字节码方式
  • 结论:同一个字节码文件在一次运行国政中,只会被加载一次,不论通过哪一种方式

使用class

  1. 获取成员变量
    • Field[] getFields()
    • Field getField(String name)
    • Field[] getDeclaredFields()
    • Field getDeclaredField(String name)
  2. 获取构造方法
    • Constructor<?>[] getConstructors()
    • Constructor< > getConstructors(类<?>...parameterTypes)
  3. 获取成员方法
  4. 获取类名

image-20240724145029430

Field:成员变量
  • 操作

    1. 设置值

      void set(Object obj,Object value) ,obj为类的对象,value为修改值

    2. 获取值

      get(Object obj) ,obj为类的对象

    3. 忽略访问权限修饰符的安全检查

      srtAccessible(true):暴力反射

Constructor:构造方法
  • 创建对象:
    • T newInstance(Object...initargs)初始化
    • 用空参创建对象Class对象的newInstance方法
Method :执行方法
  • 执行方法:

    • invoke
  • 获取方法名,类名

    String getName:获取方法名

    类名从Class中获取

案例

需求:写一个“框架”,在不改变代码的情况下,创还能任意类的对象,并能执行任意方法

  • 实现:

    1. 配置文件
    2. 反射
  • 步骤:

    1. 将需要创建的对象的全类名和执行方法定义在配置文件中
    2. 在程序中加载读取配置文件
    3. 使用反射技术带加载类文件进内存
    4. 创建对象
    5. 执行方法

注解

分类

  • 编写文档:通过代码里的标识的注解生成文档【生成文档doc文档】
  • 代码分析:通过代码里的标识的注解对代码进行分析【使用反射】
  • 编译检查:通过代码里的标识的注解让编译器实现基本的编译检查【@Override】

使用注解@注解名称

  • JDK中预定义的一些注解
    • @Override:检测是重写的方法
    • @Deprecated:表明已过时
    • @SuppressWarning:压制警告

自定义注解

  • 格式:

    元注解

    public @interface 注解名称{}

  • 本质:注解本质上就是一个接口,该接口默认继承Annotation接口

    • public interface MyAnno extends java.lang.annotation.Annotation{}
  • 属性:接口中可以定义的成员方法

    要求:

    1. 属性的返回值类型:基本数据类型,String 枚举,注解和以上类型的数组

    2. 定义了属性,在使用时需要给属性赋值:

      在定义属性时,使用default关键字修饰不用赋值

      若只有一个属性则可以省略名称

  • 元注解:用于描述注解的注解

    @Target:用于描述注解能够作用的位置

    • ElementType的值:

      TYPE:作用与类上

      METHOD:作用于方法

      FIELD:作用与成员变量

    @Retrntion:描述注解被保留的阶段

    • @Retention(RetentonPolicy.RUNTIME ):当前被描述的注解,会保留到class字节码文件中,并为JVM读取

    @Documented:描述注解是否被抽取到api文档中

    @Inherited:描述注解是否被子类继承

在程序中使用注解:获取注解中定义的属性值

  1. 获取注解定义的位置的对象(Class,Method,Field)

  2. 获取指定的注解

    getAnnotation(Class)

  3. 调用注解中的抽象方法获取配置的属性值

简单的测试框架:

当主方法执行,会自动检查所有方法,并判断是否有异常,记录到文件中

  1. 获取注解中定义的属性值,测试类地址
  2. 创建测试类的对象
  3. 获取字节码文件对象
  4. 获取所有方法
  5. 判断方法是否有Ckeck注解,有就执行 if(method.isAnnotationPresent(Check.class))
  6. 捕获异常

小结:

  1. 会使用注解不定义
  2. 给编译器用,给解析程序用
  3. 注解不是程序,是程序的一个标签

web基础知识

web是互联网项目,使用java语言开发网站

数据库(5),网页前端(5),web核心技术(15),旅游管理系统(5)

数据库

基本概念,MySQL软件,SQL的使用

基本概念:DataBase,简称DB

  • 用于存储和管理数据的仓库

特点:

  1. 持久化存储数据的,数据库就是一个文件系统
  2. 方便存储和管理数据
  3. 使用了统一的方式操作数据库--SQL

常见数据库软件:

  • MySQL
  • Or

MySQL

  1. 安装

  2. 卸载

    去mysqld 安装目录下找到my.ini文件,复制daradir="c/programDate/Mysql/Mtsql Server 9/Data/"

    卸载

    删除c/programData/MySQL

  3. 配置

    要配置环境

    服务启动:

    1. 手动

    2. cmd-->services.msc打开服务的窗口

    3. 使用管理员打开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:结构化查询语言

就是定义了操作所有关系型数据库的规则,每一种数据库的操作方式存在不一样的地方,称为方言

通用语法

  1. SQL语句可以单行或多行书写,以分号结尾

  2. 使用空格和缩进

  3. 数据库不区分大小写,但关键字建议使用大写

  4. 3种注释

    单行注释:-- 注释内容(有一个空格)或# 注释内容(mysql特有的)

    多行注释:/* 注释 */

书写语句

  1. DDL:操作数据库和表的
  2. DML:增删改表中的数据
  3. DQL:查询表中的数据
  4. DCL:授权

DDL操作库和表

操作数据库和表的
1操作数据库:CRUD
  1. C(Create):创建

    创建数据库:create database 数据库名称;

    创建数据库判断是否存在:create database if not exists 数据库名称;

    创建db4数据库,并判断是否存在,并指定字符集为gbk:

    create database if not exists bd4 character set gbk;

  2. R(Retrieve):查询

    查询所有的数据库:show databases;

    查询某个数据库的创建语句:show create database 数据库名称;

  3. U(Update):修改

    修改数据库的字符集:alter database db3(数据库) character set 字符集名称

  4. D(Delete):删除

    删除数据库:drop database db3(数据库);

    判断数据库存在:drop database if exists dbs(数据库名称)

  5. 使用数据库

    查询当前正在使用的数据库:select database();

    使用数据库:use db1(数据库名称)

操作表
  1. C(Create):创建

    创建表:create table 表名(

    列名1 数据类型1,

    列名2 数据类型2,

    列名n 数据类型n

    );

    复制表:create table 新的表名 like 表名(被复制的表)

  2. R(Retrieve):查询

    查询所有数据库中的所有的表名称:show tables;

    查询表达结构:desc 表名;

  3. U(Update):修改

    修改表名:alter table 表名 remane to 新的表名

    修改表字符集:alter table 表名 character set 字符集名称

    添加一列:alter table 表名 add 列名 数据类型

    修改列名:alter table 表名 change 列名 新列名 新数据类型

    ​ alter table 表名 modify 列名 新数据类型;

    删除列:alter table 表名 drop 列名

  4. D(Delete):删除

    使用数据库

    删除表:drop table if exists 表名

数据类型:

  1. int:整数类型 , age int,

  2. double:小数类型 , score double(5(几位),2(小数点后几位))

  3. date:日期,包含年月日 , yyyy-MM-dd

  4. datetimr:日期,包含年月日时分秒 , yyyy-MM-dd,HH:mm:ss

  5. timestamp:时间错,包含年月日时分秒 , yyyy-MM-dd,HH:mm:ss

    若不赋值或赋值为null,则默认使用当前的时间自动赋值

  6. 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);

  • 注意:
    1. 列名一一对应
    1. 若给所有列添加就不用写列名
  1. 删除数据:

    语法:

    • delete from 表名 [where 条件]

    注意:

    1. 如果不加条件,就会删除表中的所有记录

    2. 若要删除所有记录

      delete from 表名 ;有多少条记录就会执行多少次,效率低

      truncate table 表名;显删除表再创建一张一摸一样的表

  2. 修改数据:

    语法:

    • update 表名 set 列名1 = 修改的数值1,列名2 = 修改的数值2 ... where(条件)

    注意

    • 不加条件就会全部修改

DQL:查询表中的记录

  • select * from 表名;

查询语句

  1. 语法:

    select
    字段列表
    from
    表名列表
    where
    条件列表
    group by
    分组字段
    order by
    排序
    limit
    分页限定

  2. 基础查询

    1. 多个字段的查询
      select 字段名... from 表名
      查询所有可以用*代替

      select name,age from stu;

      select * from stu;

    2. 去除重复
      distinct

      select distinct * from stu;

    3. 计算列
      一般可以使用四则运算计算一些列的值,直接加(一般只进行数值的计算 )

      select math,english,math+ifnull(english,0) from student

      ifnull(表达式1,表达式2):null参与的计算都为null
      表达式1:那个字段可能出现null
      表达式2:若出现null后的替换值

    4. 起别名

      在要起别名的列名后加as或空字符

      select math,english,math+ifnull(english,0) as 总分 from student

  3. 条件查询

    1. where字句后跟条件

    2. 运算符
      <, > ,<=, >=,=,< >(=是等于没有赋值)
      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,...
    排序方式:
    1. ASC升序
    2. DESC降序
      select * from student order by math desc,english asc;(若有一样的就会按english的方式排序)

聚合函数

将一列数据作为一个整体,进行纵向计算

  1. count:计算个数
    一般选择非空的列:主键
    count(*)(只要有一个不为空就算)

  2. max:计算最大值
    max(math)

  3. min:计算最小值
    min(math)

  4. avg:计算平均值
    avg(math)
    聚合函数排除了null

    select count(name) from stu;

分组查询

  1. 语法:group by 分组字段
  2. 注意
    分组之后查询的字段:分组字段,聚合函数
    select sex,avg(math),count(id) from where math>70 student group by sex having count(id)>2;
    where和having的区别
    where:在分组之前对条件限制,不参与分组。后不能跟聚合函数
    having:在分组之后对条件限制,不被查询出来。能跟聚合函数

分页查询

  1. 语法:limit开始的索引,每页查询的条数;
    select * from student limit 0,3;
    开始的索引=(当前的页码-1)*每页的条数
    limit是mysql的方言

约束

  • 是对表中的数据进行限定,保证数据的正确性,有效性和完整性
  • 分类:
  1. 主键约束:primary key
  2. 非空约束:not null
  3. 唯一约束:unique
  4. 外键约束:foreign key

非空约束:not null

某一列的值不能为null

  1. 创建表时加约束
    create table test(id int,name varchar(20) not null);
  2. 创建表后添加非空约束
    alter table stu modify name varchar(20) not null;
  3. 删除非空约束
    alter table stu modify name varchar(20);

唯一约束:unique

某一列的值不能重复
注意:
唯一约束可以有null值,但只能有一个

  1. 创建表时添加唯一约束:
    create table stu (id int phone_number varchar(20) unique)
  2. 创建表后添加非空约束
    alter table stu modify phone_number varchar(20) unique;
  3. 删除唯一约束
    alter table stu drop index phone_number;

主键约束:primary key

  1. 注意:
    1. 含义:非空且唯一
    2. 一张表就能有一个字段为主键
    3. 主键就是表中记录的唯一标识
  2. 在创建表时添加主键约束
    create table stu(id int primary key,
    name varchar(20));
  3. 添加主键
    alter table stu modify id primary key;
  4. 删除主键
    alter table stu drop primary key;
  5. 自动增长
    1. 概念:如果某一列是数值类型的,使用auto_increment 可以完成自动增长
    2. 在创建表时,添加主键约束,并且完成自动增长
      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);
    3. 删除自动增长
      alter table stu modify id int;(主键删除不了就只能删除自动增长)
    4. ALTER TABLE phone MODIFY id INT

外键约束:foreign key

  1. 在创建表时可以添加外键
    • 语法:
      create table 表名(
      ...
      外键列,
      constraint 外键名称 foreign key (外键列的名称) references 主表名称(主列表名称));
  2. 删除外键:
  • alter table stu drop foreign ket 外键的名称;
  1. 添加外键:
  • alter table stu add constraint 外键的名称 foreign key refercences 主表名称(主表列名称);
  1. 级联:
    • 再添加外键的时候,在最后加上级联更新,级联删除
      alter table stu add constraint 外键的名称 foreign key refercences 主表名称(主表列名称) on update cascade on delete cascade;
    • 级联更新:on update cascade
    • 级联删除:on delete cascade

数据库的设计

  1. 多表之间的关系
  2. 数据库设计的范式

多表之间的关系

  1. 分类:
    1. 一对一:
    • 如:身份证对人
    1. 一对多(多对一)
    • 部门和员工:一个部门有多个员工,一个员工只能对应一个部门
    1. 多对多
    • 学生和课程:一个学生可以选许多课程,一个课程也有许多学生
  2. 实现关系:
  3. 一对多(多对一)
  • 在多的一方建立外键,来指向一的一方
  1. 多对多
  • 多对多的关系实现需要借助第三张中间表,中间表至少包含两个字段作为第三张表的外键,分别指向两张表主键
  1. 一对一
  • 可以在任意一方添加唯一外键指向另一方的主键
案例

旅游线路分类,旅游线路,用户

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));
//联合表

设计数据库的范式

  1. 分类:
  • 第一范式(1NF):每一列都是不可分割的原子数据项
  • 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
    1. 函数依赖:A-->B,通过A属性的值,可以确定唯一B属性的值,则称B依赖A
      例如:学号-->学生,(学号,课程)-->成绩
    2. 完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定依赖于A组所有的属性值
      例如:(学号,课程)-->成绩
    3. 部分函数依赖:A-->B,A是一个属性组,B的确定需要A组的部分属性值来确定即可
      例如:(学号,课程)-->姓名
    4. 传递函数依赖:A-->B,B-->C,通过A确定唯一B,在通过B确定唯一C,则C传递函数依赖于A
    5. 码:如果一个属性或一个属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
      例如:通过(学号,课程)能确定所有的其他属性,故(学号,课程)为该表的码
      • 主属性:码属性组中的所有属性
      • 非主属性:其他属性组的属性
  • 第三范式(3NF):在2NF的基础上,任何非主属性不依赖于其他非主属性(2NF的记住上消除传递依赖)

数据库的备份和还原

  1. 命令行:
    • 语法:mysqldump -u用户名 -p密码 数据库名称>保存路径
    • 还原:
      1. 登录,创建,使用
      2. 执行文件。source 文件路径
注意编码要一致
  1. 使用Navicat Premium手动备份

多表查询

  • 查询语法:
    select
    列名列表
    from
    表名列表
    where...
  • 多表查询的分类
  • 笛卡尔积:
    • 有两个集合A,B,取两个集合的所有情况组合
    • 要完成多表查询,就要消除无用的情况
  • 分类:
    1. 内连接查询:
      1. 隐式的内连接:使用where条件消除无用的信息
        select
        t1.name,t2.name
        from
        t1,t2
        where t1.'id'=t2.'id';
      2. 显式的内连接:
        语法:select 字段列表 from 表名1 【inner】 join 表名2 on 条件
        select * from
        emp join dept
        on emp.'id'=dept.'id';
      3. 内连接查询:
        从哪些表中查询数据
        条件是什么
        查询哪些字段
    2. 外连接查询:
      1. 左外连接:
        语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
        查询的是左表所有数据以及其交集
      2. 右外连接:select 字段列表 from 表1 right [outer] join 表2 on 条件;
        查询的是右表所有数据以及其交集
    3. 子查询:
      • 嵌套的查询就是子查询
      • select * from emp where emp.'salary' =(select MAX(salary) from emp);
      • 子查询的情况:
        1. 子查询的结果是单行单列的:
          子查询可以作为条件,使用运算符去判断 <,>,<=等
        2. 子查询的结果是多行单列的:
          子查询可以作为条件:使用in来判断
        3. 子查询的结果是多行多列的:
          子查询可以作为一张虚拟表参与查询
          select * from t1,(select id from t2 where id in(2,3)) t3 where t3.'id'=t1.'id'
多表练习
  1. 查询所有员工信息。查询员工编号,姓名,工资,职务名称,职务描述
  2. 查询员工编号,姓名,工资,职务名称,职务描述,部门位置
  3. 查询员工姓名,工资,工资等级
  4. 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工作等级
  5. 查询出部门编号,部门名称,部门位置,部门人数
  6. 查询出所有员工的姓名及其直接上级的姓名,没有领导的员工也要查询
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

事务

事务的基本介绍

  1. 概念:
    如果一个包含多个步骤的业务操作,被事务管理,要么同时成功,要么同时失败
  2. 操作;
    1. 开启事务:start transcartion

    2. 回滚:rollback

    3. 提交事务:commit
      start transaction;
      commit;
      rollback;

    4. Mysql数据库中的事务默认自动提交
      事务提交的两种方式:

      • 自动提交:一条DML(增删改)语句会自动提交一次事务
      • 手动提交:需要先开启事务,在手动提交

      修改事务的默认提交方式:

      • 查看事务的默认提交方式:select @@autocommit;1--代表自动提交
      • 修改事务的默认提交方式:set @@autocommit=0;0--代表手动提交 oracle数据库默认手动提交

事务的四大基本特征

  1. 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败
  2. 持久性:事务结束后,数据库会持久的保存数据
  3. 隔离性:多个事务之间,相互独立
  4. 一致性:事务操作前后,数据总量不变

事务的隔离级别

  • 概念:多个事务之间操作同一批事务,则会引发一些问题,设置不同的隔离级别就能解决问题

  • 问题:

    1. 脏读:一个事务没有提交的数据
    2. 不可重复读(虚读):在同一个事务中两次读取的数据不一样
    3. 幻读:一个事务操作数据表中的所有记录,另一个添加数据,则第一个事务查询不到自己的修改
  • 隔离级别:

    1. read uncommmitted:读未提交的
      产生的问题:脏读,不可重复读,幻读
    2. read committed:读已提交的(Oracle默认的)
      产生的问题:不可重复读,幻读
    3. repeatable read:可重复的(Myqsl默认的)
      产生的问题:幻读
    4. serializable:串行化(上锁)
      可解决所有问题

    隔离级别从小到大安全性越高,效率越低
    数据库查询隔离级别:
    select @@tx_isolation;
    数据库设置隔离级别:
    set global transaction isolation level 级别字符串

演示

DCL

管理用户,授权

管理用户

  1. 添加用户:create user '用户名'@'主机名' identified by '密码';
  2. 删除用户:drop user '用户名'@'主机名'
  3. 修改用户密码
    1. update user set password =password('新密码') where user ='用户名'
    2. set password for '用户名'@'主机名'=password('新密码');
  4. 查询用户:
    切换到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服务
  • 使用新密码登录

权限管理

  1. 查询权限:show grants for '用户名'@'主机名';
  2. 授予权限:grand 权限列表 on 数据库名,表名 to '用户名'@'主机名'
    grand select on db1.stu to 'root'@'%';
    grand all on . to 'root'@'%';
  3. 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名'

JDBC

    • 概念:java database connectivity java数据库连接,java语言操作数据库
    • 本质:官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这接口编程,真正执行这套代码的是驱动jar包的实现类

2. 快速入门:

步骤:

  1. 导入驱动jar包
    复制到某个目录下:mysql-connector-j-8.4.0.jar
    右键--->add as library
  2. 注册驱动
    Class.forName("com.mtsql.jdbc.Driver");
  3. 获取数据库连接对象Connection
    Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","ROOT");
  4. 定义sql
    String sql="update stu set name="王五" where id=1";
  5. 获取执行sql语句的对象Statement
    Statement stmt=conn.createStatement();
  6. 执行sql,接受返回结果
    int count = stmt(sql);
  7. 处理结果
    System.out.println(count);
  8. 释放资源
    stat.close();
    conn.close();

3.详解各个对象

DriverManager:驱动管理对象

功能:

  1. 注册驱动:告诉程序要用什么接口

    • state void registerDriver(Driver driver):注册与给定的驱动程序DriverManager
    • 写Class.forName("com.mysql.jdbc.Driver");有静态代码块帮助其注册
    • 注意:jar有注册驱动的,可不写
  2. 获取数据库的连接:

    • 方法:state Connection getConnection(String url,String user,String password)
    • 参数:指定链接线
    • jdbc:mysql://ip地址(域名):端口号/数据库名称
    • jdbc:mysql://localhost:3306/db2
    • 若是本机可简写:jdbc:mysql:///数据库名称
    • user:用户名
    • password:密码

Connection:数据库连接对象

功能:

  1. 获取执行sql的对象
    Statement createStatement()
    PreparedStatement prepareStatement(String sql)
  2. 管理事务:
    开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
    提交事务:commit()
    回滚事务:rollback()

Statement:执行sql的对象

  1. 用于执行静态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");
  • 注意:
    1. 游标向下移动一行
    2. 判断是否有数据
    3. 获取数据
练习
  1. 定义一个Emp类
  2. 定义方法 public List<Emp> findAll(){}
  3. 实现方法 select * from emp;
练习2

需求:

  1. 通过键盘录入用户名和方法

  2. 判断是否登录成功

    select * from user where username=""and password"";

    若sql的查询有结果,则成功

步骤:

  1. 创建数据库表user

PreparedStatement:执行sql的对象

SQL注入问题:在拼接sql时,有一些特殊的关键字参与字符串的拼接,会造成安全性问题

  1. 用户名随便,密码:a' or 'a'='a'
  2. 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)

最终步骤:
  1. 导入驱动jar包

  2. 注册驱动

  3. 获取数据库连接对象Connection

  4. 定义sql

    注意:select * from user where username=? and password =?

  5. 获取执行sql语句的对象,PreparedStatement stmt=conn.PrepareStatement(sql);

  6. 给?赋值
    prep.setString(1,username)

    prep.setString(2,password)

  7. 执行sql不再传sql语句

  8. 处理结果

  9. 释放资源

抽取JDBC工具类:JDBCUtils

  1. 注册驱动也抽取
  2. 抽取方法获取连接对象
    public static Connection getConnection(){}
    public static void close(Statement stmt,Connection conn){}

JDBC控制事务

使用Connection对象来管理事务

  1. 开始事务:setAutoCommetion(boolean aUtoCommit):调用方法设置参数为false 即开启事务
  • 在sql执行之前开启事务
  1. 回滚:rollback()
  • 在异常中回滚事务
  1. 提交事务:commit()
  • 当所有sql执行完后提交事务

数据库连接池

概念:是一个容器(集合),存放数据库连接的容器
当系统初始化好后,容器会申请一些连接对象,当用户来访问数据库时,从容器中链接对象,用户访问完成之后,会将连接对象归还给容器
好处:节约资源,用户访问高效
实现:

  1. 标准接口:DateSource javax.sql包下的
    方法:
    1. 获取连接:getConnection()
    2. 归还连接:如果链接对象是从连接池中获取的,那么connection.close()方法则不会关闭连接,而是归还
  2. 一般我们不去实现它,有数据厂商去实现
    1. C3P0:数据库连接池技术
    2. Druid:数据库连接池实现技术,阿里巴巴提供

C3P0连接池技术

  1. 导入jar包两个:c3p0-0.9.5.5.jar和mchange-commons-java-0.2.19.jar
  2. 定义配置文件
  • 名称:c3p0.properties或c3p0-config.xml
  • 路径:直接将文件放在src目录下
    3.创建核心对象:数据库连接池对象ComboPooledDataSource
    4.获取连接:getConnection

druid连接池技术
步骤:
1.导入jar包druid.jar
2.定义配置文件:
是properties的形式
可以叫任意名称,放在任意目录下

  1. 获取数据库连接池对象:通过工厂来获

    DruidDataSourceFactory
    DataSource ds=DruidDataSourceFactory.createDataSource(pro)

  2. 获取连接:getConnection()
    定义一个工具类

  3. 定义一个类 JDBCUtils

  4. 提供静态代码块加载配置文件,初始化连接池对象

  5. 提供方法

    1. 获取连接方法:通过数据库连接池获取连接
    2. 释放资源
    3. 获取连接池的方法

Spring JDBC:JDBC Template

  • Spring框架对JDBC的简单封装,提供了一个JDBCTemplated对象简化JDBC的开发
  • 步骤:
  1. 导入jar包
  2. 创建jdbcTemplate对象,依赖于数据源DataSource
    JdbcTemplate template=new JdbcTemplate(DataSource ds)
  3. 调用JdbcTemplate的方法来实现CRUD的操作
  • update():执行DML语句。增删改
  • queryForMap():查询结果将结果集封装为map集合
  • queryForList():查询结果将结果封装为List集合
  • query():查询结果,将结果封装为JavaBean对象
  • queryForObject(sql,Object):查询结果,将结果封装为对象
    练习:
    需求
  1. 添加一号数据的salary 为10000
  2. 添加一条记录
  3. 删除刚才的记录
  4. 查询di为1的记录,将其封装为Map集合
  5. 查询所有记录,将其封装为List集合
  6. 查询所有记录将其封装为Emp对象的List集合
  7. 查询总记录数

Web概念概述

  • javaweb
  • 软件架构:
    1.c/s架构:Client/Server 客户端/服务器端
    • 在用户本地有一个客户端,在远程有一个服务器端程序
    • 如qq...
    • 优点:用户体验好
    • 缺点:开发,安装,部署,维护麻烦
  1. B/S:Browser/Server 浏览器/服务器端
  • 只需要一个浏览器,用户就可以访问不同的网址
  • 优点:开发,安装,部署,维护简单
  • 缺点:应用过大,用户体验可能受到影响,对硬件要求过高

B/S架构详解

  • 资源分类:
    1.静态资源
    使用静态资源开发的网页
    特点:
    • 所有用户访问的结果一样
    • 如:文本,图片,HTML,CSS,JavaScript
    • 如果用户请求静态资源服务器会直接将静态资源发送给浏览器。浏览器内置了解析引擎,可以展示静态资源
  1. 动态资源
    使用动态网页及时发布的资源
    特点:
  • 所有用户访问的结果可能不一样
  • 如:jsp/servlet,php,asp...
  • 如果用户请求的是动态资源,那么服务器会执行动态资源,再转换成静态资源,发送给浏览器
  • 静态资源:
  • HTML:用于搭建基础网页,展示页面的内容
  • CSS:用于美化页面,布局页面
  • JavaScript:控制页面的元素,额那个页面有一些动态的效果

HTML

概念:

是最基础的网页编程语言

  • Hyper Text Markup Language 超文本标记语言
    超文本:使用超链接的方法来,将不同空间的文字信息组织到一起的网状文本
    标记语言:由标签构成的语言。<标签名称>如html,xml
    标记语言不是编程语言
    *** 快速入门

语法

  1. html文档后缀名.html或.htm
  2. 标签分为:
* 围堵标签:有开始和结束标签。如<html></html>
* 自闭和标签:开始标签和结束标签在一起。如<br/>
  1. 标签可以嵌套:
* 需要正确的嵌套,不能你中有我,我中有你
* 错误:<a><b></a></b>
* 正确:<a><b></b></a>
4. 在开始标签中可以自定义属性。属性有键值对构成,只需要用引号(单双都可以)引起来
5. 在html中不区别大小写,但建议小写
  1. 标签学习
文件标签
* 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:文本信息在一行展示,行内标签 内联标签
语义化标签
  1. 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>
旅游网站的首页
  1. 确定布局,table
  2. 如果某一行只有一个单元格,则使用
    <td><tr></td></tr>
  3. 如果某一行有多个单元格,则使用表格嵌套

<tr><td> <table></table><tr><td>

css

页面美化和布局控制

  1. 概念:cascadiong style sheets 层叠样式表
    层叠:多个样式可以作用在同一个html上,同时生效

  2. 好处:
    功能强大,将内容的展示和样式控制分离
    降低耦合度,可以提高工作效率,可以协调分工

  3. 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. 分类:
    基本选择器:
    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;
    }
    
  2. 扩展选择器:
    1. 选择所有元素 : *{}
    2. 并集选择器:选择器1,选择器2{}
    3. 子选择器:选择器1 选择器2。筛选1下的2
    4. 父选择器:选择器1>选择器2 筛选2的父选择器1
    5. 属性选择器:选择元素名称,属性名=属性值的元素
    元素名称[属性名=“属性值”]{}
    6. 伪类选择器:选择元素的状态
    元素:状态
    如:<a>
    状态:
    link:初始状态
    hover:鼠标悬浮
    active:正在访问
    visited:被访问过了

  3. 属性

    1. 文本,字体
      font-size:字体大小
      color:文本颜色
      text-align:对齐方式
      line-height:行高
    2. 背景
      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发展史:

  1. 1992年,Nombase公司,开发出第一门客户端脚本语言,专门用于表单的校验,为c--,更名为ScriptEase
  2. 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LiveScript.后来请sun公司的人来开发为JavaScript
  3. 1996年,微软抄袭JavaScript开发出JScript语言
  4. 1997年,ECMA(欧洲计算机制造商协会),ECMAScript,就是所有客户端脚本语言的标准

JavaScript=ECMAScript+javaScript自己特有的东西(BOM+DOM)

ECMASricpt:

客户端脚本语言标准

1基本语法:

与html的结合方式
  1. 内部JS:<script>script语句的代码《script》

  2. 外部JS:dingyiscript标签通过src引入外部的js文件

    注意《script》可一定要在任何的地方,但是定义的位置会影响执行顺序

    《script》可以定义多个

注释
  1. 单行注释://
  2. 多行注释:/* */
数据类型
  1. 原始数据类型(基本数据类型):

    numder:数字。整数/小数/NaN(not a number 不是一个数字的数字类型)

    string:字符串。"abc"

    boolean:true false

    null:对象为空

    undefined:未定义。若未有初始化,则默认赋值为undefined

  2. 引用数据类型:对象

变量
  • 变量:一小块存储数据的内存空间

  • 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>
运算符
  1. 一元运算符:

    ++,--,+(正号)

    在js中运算数不是运算符所要求的,js引擎会自动进行类型转换

    其他类转number:

    • string转number:按照字面值转换,字面值不是数字会转成NaN
    • boolean转number:true为1,false为0
  2. 算术运算符

    +,-,*,/,%

  3. 赋值运算符

    =,+= -=

  4. 比较运算符

    < > >= <= == ===(全等)

    类型相同:直接比较

    字符串:按照字典顺序比较,按位逐一比较,直到得出大小为止

    类型不同:先进行类型转换,再比较

    ===全等。在比较之前先判断类型,若不一样则直接放回false

  5. 逻辑运算符

    && || !

    其他类型转boolean:

    1. number:0或NaN为假,其他为真
    2. string:除了空字符串(" "),其他都为true
    3. null&undefined:都是false
    4. 对象:都是true
  6. 三元运算符

    ? :表达式 a=b>c?b:c

流程控制语句:
  1. if...else

  2. switch:

    在java中可以接收的数据类型:byte,int,shor,char

    在JS中什么都可以接受

  3. while

  4. do...while

  5. for

JS特殊语法:
  1. 语句以;结尾,如果一行只有一条语句;可以省略(不建议)

  2. 变量定义使用var关键字,也可以不一样

    使用:定义的是局部变量

    不用:定义的是全局变量(不建议)

2对象

基本对象:

Function:函数(方法)对象
  1. 创建:

    var fun = new Function(形参,方法体);

    function 方法名称(形参列表){}

    var 方法名 = function(形参){}

  2. 方法

  3. 属性:

    length:长度

  4. 特点:

    方法定义时类型不用写

    方法是一个对象,会覆盖

    在JS中方法的调用只与方法名称有关,和参数无关

    在方法声明中,会有一个内置对象(数组),argument,封装所有的实际参数

  5. 调用:

    方法名称(实际参数列表)

Array:数组对象
  1. 创建:

    var arr=new Array(元素列表);

    var arr =new Array(默认长度);

    var arr = [元素列表];

  2. 方法

    join(拼接的参数,(如,-等)):将数组中的元素拼接成字符串

    push(参数):向数组尾部添加元素并返回新的长度

  3. 属性

    length:长度

  4. 特点

    1. JS中元素类型可变
    2. JS中数组的长度是可变的

Boolean:基本数据类型的包装类

Date:日期对象
  1. 创建

    var date=new Date();

  2. 方法

    toLocaleString():返回当前date对象对应的时间本地字符串格式

    getTime():获取毫秒值。返回当前对象描述的时间到1970年1月1日0点的毫秒差

Math:数学对象
  1. 创建

    1. 特点:Math不用创建,直接使用 Math.方法名()
  2. 方法

    random():返回0~1的随机数,含0不含1

    ceil(x):对数进行上舍入

    floor(x):对数进行下舍入

    round(x):把数四舍五入为最接近的整数

  3. 属性

    • PI:圆周率
  4. 例:var number=Math.floor((Math.random()*100))+1

Number

String

RegExp:正则表达式对象
  1. 正则表达式:定义字符串的组成规则的

    单个字符:[ ] [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次

  2. 创建:

    var reg=new RegExp("正则表达式");

    var reg = /正则表达式/;

    var reg= /^\w{5-56}$/

    开始结束符号:^开始$结束

  3. 方法:

    test(参数):验证指定字符串是否符合规则

Global
  1. 特点:全局对象,不需要对象就可以直接调用

    方法名()

  2. 方法:

    encodeUPI():url编码

    decodeUPI():url解码

    encodeUPIComponent():url编码,编码的字符更多

    decodeUPIComponent():url解码,编码的字符更多

    eval():将JS的字符串作为脚本代码去实现

    isNaN():判断是否是NaN

    • NaN六亲不认,NaN参与的==比较都为false

    parsdeInt():将字符串转为数字

    • 逐一判断每一个字符是不是数字,直到不是数字停止,将前面的数字转为number

BOM

  1. 概念:Borwser Object Model 浏览器对象模型
  • 将浏览器的各个组成部分封装成各个对象
  1. 组成:
  • Navigator:浏览器对象

  • window:窗口对象

    1. 创建:

    2. 方法:

      与弹出框有关

      • 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);

    3. 属性:

      获取其他BOM对象

      • history
      • screen
      • location
      • Navigator

      获取DOM对象 document.write()

    4. 特点:

      window对象不用创建直接使用,window.方法名()

      window可以不用引用

  • Screen:显示器屏幕对象

  • History:历史记录对象

    1. 创建:

      window.history

      history

    2. 方法

      back():加载history列表中的前一个URL

      forward():加载history列表中的下一个URL

      go(参数):加载history列表中的某个具体的页面

      参数:

      • 正数:前进多少个历史记录
      • 负数:后退多少个历史记录
    3. 属性

      • lebgth:返回当前窗口的历史浏览记录,中的URL个数
  • Location:地址栏

    1. 创建:

      window.location

      location

    2. 方法

      relaod():重新加载,刷新

    3. 属性

      href:获取当前的地址

      var href=location.href;

      location.href="https://www.baidu.com"

轮播图

分析:

  1. 在页面上使用img展示图片
  2. 定义一个方法修改图片的src属性
  3. 定义一个定时器,每个三秒调用一次方法
自动跳转首页

分析:

  1. 显示页面效果 <p>
  2. 定义一个方法修改时间
  3. 倒计时读秒,使用定时器

DOM

概念:文档对象模型

  • 将标记文档封装为各个对象

image-20240801200923321

W3C DO标准 - 分为3部分

  • 核心DOM针对任何结构化文档的标准模型

    • Document:文档对象
    • Element:元素对象
    • Attribute:属性对象
    • Text:文本对象
    • Comment:注释对象
    • Node:节点对象,其他5个父类对象
  • XML DOM- 针对XML文档的标准模型

  • HTML DOM--针对HTML文档的标准模型

核心DOM模型:

  • Document:文档对象

    创建:在html中可以使用window对象来获取

    • window.document
    • document

    方法:

    1. 获取Element对象

      getElementsById():根据id属性获取元素对象

      getElementsByTagName():根据(标签名称)元素名称获取元素对象,返回值是一个数组

      getElementsByClassName():格局Class属性获取元素对象。返回值是一个数组

      getElementsByName():根据name属性获取元素对象们

    2. 创建其他DOM对象:

      createAttribute(name):属性

      createComment():注释

      crteateElement():元素

      createTextNode():文本

  • Element:元素对象

    获取

    • 通过document来获取和创建

    方法

    • removeAttribute():删除属性
    • setAttribute(属性,属性值):设置属性
  • Node:节点对象,其他5个父类对象

    特点:所有dom对象都可以作为节点

    方法

    CRUD dom树

    • appendChild(节点):向节点的子节点添加新的子节点
    • removeChild(节点):删除当前节点的子节点 div1.removeChild(div2)
    • replaceChild():用新节点替换子节点

    属性:

    parentNode:返回父类节点

案例

动态表格

分析:

  1. 给添加按钮绑定单击事件

  2. 获取文本框的内容

  3. 创建td,设置td的文本为文本框的内容

  4. 创建tr

  5. 将td添加到tr中

  6. 获取table

    <a href="javascript:void(0)">
    

删除:

  1. 确定是哪个超连接

    a href="javascript:void(0);"onclick = "delete(this);"

  2. 删除:removeChild();通过父标签parentNode

HTML DOM模型

  1. 标签体的设置和获取:innerHTML

  2. 使用html元素对象的属性

  3. 设置样式

    使用元素的style属性来设置

    • div1.style.border="1px solic red"

    提前定义好类选择器的样式,通过元素的className属性来实现设置器的class的属性值

    • div1.classNate="d1";

功能:控制html文档的内容

代码:获取页面标签(元素)对象Element

  • document.getElementByd("id"):通过元素的id获取元素的对象

操作Elment对象

  1. 修改属性 .属性
  2. 修改标签体的内容 .innerHTML

事件

事件的监听机制

事件:某些操作,单击,双击

事件源:组件,按钮 文本输入框

监听器:代码

注册监听:将事件,事件源,监听器集合在一起。当事件源上发生了某个事件,则会触发执行某个监听器代码

功能:某些组件被执行某些操作或,就会出发一些代码的执行

如何绑定事件:

  1. 直接在html标签上,指定某些事件的属性(操作),属性值就是JS代码

    事件:

    点击事件:

    1. onclick---单击事件
    2. ondbclivk--双击事件

    焦点事件:

    1. onblur:失去焦点

      一般用于表单校验

    2. onfocus:元素获得焦点

    加载事件

    1. onload:一张页面或一副图像完成加载

      window.onload=function(){}

    鼠标事件

    1. onmousedown:鼠标按钮被按下

      定义一个方法时,定义一个形参,event对象

      event对象的button属性可以可以获取鼠标按钮被点击了

    2. onmouseup:鼠标按钮被松开

    3. onmousemove:鼠标被移动

    4. onmouseover:鼠标移动到某个元素

    5. onmouseout:鼠标从某元素移开

    键盘事件

    1. onkeydown:某个键盘按键被按下
    2. onkeyup:某个键盘按键被松开
    3. onkeypress:某个键盘按键被 按下并松开

    选择和改变

    1. onchange:域的内容被选中
    2. onselect:文本被选中

    表单事件

    1. onsumbit:确认按钮被点击

      可以阻止表单被提交

      • 方法返回false则表单被阻止提交
    2. onreset:重置按钮被点击

  2. 通过js获取属性,指定事件属性,设置一个函数

练习:
  1. 获取图片对象

  2. 绑定一个单机事件

  3. 每次点击切换图片

表格练习
  1. 表格
  2. 在页面加载完后绑定事件
  3. 给全选绑定单击事件
  4. 获取所有checkbox
  5. 遍历cb,设置每一个cb的状态为选中 cbs.checked=true;
  6. 反选:本身为非。第一个cb点击:获取所有的cb设置所有的cb的状态都和第一个一样
  7. 给所有tr绑定鼠标移到元素之上和移除的事件:换颜色

表单校验

  1. 给表单绑定onsubmit事件。监听器中判断每一个方法校验的结果

    若都为true,则返回true

    若都为false,则返回false

  2. 定义一些方法分别校验各个表单项

    获取用户名的值,定义正则表达式

    判断值是否符合规范,提示信息

  3. 给各个表单项绑定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个格子,可以指定元素占几个格子

步骤:

  1. 定义容器:相当于之前的table

    容器分类:

    1. container:固定宽度,有留白
    2. container-fluid:每一种设备都是100%宽度
  2. 定义行,相当于之前的tr 样式:row

  3. 定义元素,指定该元素在不同设备上所占的格子数目。 样式:col-设备代号-格子数目

    设备代号:

    1. xs:超小屏幕 手机(<768px):col-xs-12
    2. sm:小屏幕 平板(>768px)
    3. md:中等屏幕 桌面显示器(>=992px)
    4. 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:万维网联盟

  1. xml标签都是自定义的,html标签都是预定义
  2. xml的语法严格,hrml语法松散
  3. xml是存储数据的,html是展示数据

语法

基本语法

  1. xml文档的后缀名 .xml
  2. xml第一行必须定义为文档声明
  3. xml文档中有且仅有一个根标签
  4. 属性值必须使用引号单双都可以
  5. 标签必须正确关闭
  6. xml标签名称区分大小写

快速入门

<?xml version='1.0'?>
<users>
<user id='1'>
    <name>zhansan</name>
    <age>22</age>
    <gender>male</gender>
</user>
</users>

组成部分

  1. 文档声明

    1. 格式:<?xml 列表属性 ?>

    2. 属性列表

      • version:版本号,必须的属性

      • encoding:编码方式。告知解析引擎 当前文档使用的字符集,默认值:ISO-8859-1

      • standalone:是否独立

        取值:

        • yes:不依赖其他文件
        • no:依赖其他文件
  2. 指令(了解):结合css的

    • <?xml-stylesheet type="text/css" href="a.css"?>
  3. 标签:自定义的

    规则:

    1. 名称可以包含字母数字及其他字符
    2. 名称不可以以数字或标点符号开始
    3. 名称不能以字母xml (或XML Xml等)开始
    4. 名称不能有空格
  4. 属性

    id属性值唯一

  5. 文本

    • CDATA区:在该区中的水会被原样展示
    • 格式:<![CDATA[数据]]>

谁编写xml?-用户,软件使用者

谁解析xml?-软件

约束:

规定xml文档的书写规则

作为框架的使用者(程序员):

  1. 能够在xml中引入约束文档
  2. 能够简单的读懂约束文档

分类:

  1. DTD:简单的约束技术
  2. Schema:复杂的约束技术
DTD
  1. 引入dtd文档到xml文档中

    内部dtd:将看看约束规则定义在xml文档中

    外部dtd:将约束的规则定义在外部的dtd文档中

    • 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置"
    • 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名" "dtd文件的位置URL"
Schema

引入:

  1. 填写xml文档的根元素
  2. 引入xsi前缀。xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. 引入xsd文件命名空间.xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
  4. 为每一个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文档

  1. 解析(读取):将文档中的数据读取到内存中
  2. 写入:将内存中的数据保存到xml文档中,持久化保存

解析xml的方式

  1. DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树

    • 优点:操作方便,可以对文档进行CRUD的所有操作
    • 缺点:占内存
  2. SAX:逐行读取,基于事件驱动的

    • 优点:不占内存
    • 缺点:只能读取,不能增删改

xml常见的解析器

  1. JAXP:sun公司提供的解析器,支持dom和sax两种思想
  2. DOM4J:一款非常优秀的解析器
  3. jsoup:是java的解析HTML的解析器,可解析xml
  4. PULL:android(安卓)操作系统内置的解析器,sax方式的

JSOUP

jsoup是一款java的html的解析器,可直接解析URL地址,html文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似与jQuery的操作方法来取出和操作数

快速入门

步骤:

  1. 导入jar包
  2. 获取Document的对象
  3. 获取对应的标签Element对象
  4. 获取数据

代码:

  1. 获取student.xml的path(地址)

  2. 解析xml文档,加载文档进内存,获取dom树--->Document

    Document document = Jsouip.parse(new File(path),"utf-8");

  3. 获取元素对象Element

    Elements elements=document.getElementsByTag("name");

    Syste.out.println(element.size());

  4. 获取第一个name的Element对象

    Element element=element.get(0);

  5. 获取数据

    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的父类

快速查询

  1. selector:选择器

    使用方法:Elements select(String cssQuery)

    • 语法参考Selector类中定义的语法

    Elements elements=document.select("student[number='hema001']");

  2. XPath:

    即xml路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言

    • 使用Jsoup的XPath需要额外导入jar包
    • 查询w3cshool参考手册,使用xpath的语法完成查询
    • List<JXNode> jxNodes2=jxDocument.selN("//student/name[@id='ithema']")

web知识回顾

软件架构

  1. C/S:客户端/服务器端
  2. B/S:浏览器/服务器端

资源分类:

  1. 静态资源:所有用户访问或,得到的结果是一样,称为静态资源.可以直接被浏览器解析

    如:html,css,javaScript

  2. 动态资源:每个用户访问相同的资源后,得到的结果可能不同,称为动态资源。动态资源被访问后要先转换成静态资源,再返回给浏览器

    如:servlet/jsp,php,asp...

网络通信三要素:

  1. ip:电子设备在网络中的唯一标识

  2. 端口:应用程序在计算机中的唯一标识。0~65536

  3. 传输协议:规定了数据传输的规则

    基础协议:

    1. tcp:安全协议,三次握手。速度稍慢
    2. 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服务器软件

  1. 下载:http://tomcat.apache.org/

  2. 安装

  3. 卸载

  4. 启动:bin/startup.bat,运行

    访问:在浏览器输入:http://loaclhost:8080 回车访问自己,http://别人的id:8080 回车访问别人

    可能遇到的问题:

    1. 黑窗口:没有正确配置JAVA_HOME环境变量

    2. 启动报错:端口号被占用在.cdm终端中输入netstat -ano找到端口号用任务管理器来结束进程

      修改自身端口号:

      conf/server.xml

      <Connect port="8888"

      一般默认将tomcat的默认端口修改为80.80是http协议的默认端口

  5. 关闭:

    1. 正常关闭:

      bin/.shutdown.bat

      ctrl+c

    2. 强制关闭:关闭启动窗口

  6. 配置:

    部署项目的方式:

    1. 直接将目录放到webapps中

      /hellow:项目的访问路径-->虚拟目录

      简化部署:将项目打成一个war包,再将war部署到

    2. 配置conf/server.xml文件

      <HOST>标签体中配置

      <Context docBase="D:\hellow" path="/hehe"/>

      docBase:项目存放的目录

      path:虚拟目录

    3. 在conf\Catalina\locahost创建任意名称的xml文件,在文件中编写<Context docBase="D:\hellow"/>

      虚拟目录:xml文件的名称

image-20240805085914956

bin:可执行文件

conf:配置文件

lib:依赖jar包

logs:日志文件

temp:临时文件

webapps:存放web项目

work:存放运行时的数据

静态项目和动态项目

  • 目录结构

    java动态项目的目录结构

    • 项目目录

      WEB-INF

      • web.xml:该目录的核心配置文件
      • Classes目录:放置字节码文件
      • lib目录:放置项目依赖的jar包

将Tomcat集成到idea

Servlet:

运行在浏览器中的小程序

概念

servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则

将来我们定义一个类,实现Servlet接口,复写方法

快速入门

  1. 创建javaEE的项目

  2. 定义一个类,实现Servlet接口

    public class ServletDemo1 implements Servlet

  3. 实现接口中的抽象方法

  4. 配置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>
    

![image-20240805200843409](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240805200843409.png)

### 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

![image-20240806113612664](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240806113612664.png)

#### 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展示:登录失败,用户名或密码错误

分析:

![image-20240806195221938](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240806195221938.png)

开发步骤:

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,显示:用户名,欢迎你

  ![image-20240809145658525](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240809145658525.png)

## 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开发模式

 ![image-20240809180230193](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240809180230193.png)

## 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. 数据访问层:操作数据存储文件的

![image-20240810155639977](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810155639977.png)

### 案例

#### 分析

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

![image-20240810162644729](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810162644729.png)

##### 添加

![image-20240810210119148](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810210119148.png)

##### 删除

![image-20240810210042236](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810210042236.png)

##### 修改

![image-20240810210649513](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810210649513.png)

 

##### 删除选中

![image-20240810212452346](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810212452346.png)

##### 分页查询

 ![image-20240810215556672](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810215556672.png)

![image-20240810220116311](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810220116311.png)

多条件组合加查询

![image-20240810220806503](C:\Users\xiaoxin\AppData\Roaming\Typora\typora-user-images\image-20240810220806503.png)

## 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("放行了")
}

过滤器生命周期方法

  1. init:在服务器启动后,会创建Filter对象,然后调用inti方法。只执行一次,用于加载资源
pulic void init (FilterConfig filterConfig) throws ServletExcption{}
  1. doFilter:每一次请求被拦截资源时会执行,可以执行多次
public void doFiler(ServletRequest servletRequest,ServleResponse,FilterChain filterChain)
throws IOException,ServletException{
System.out.println("filterDemo1被执行了...");
filterChain.doFilter(servletRequest,servletResponse);}
  1. destroy:在服务器关闭后,Filter对象被销毁。如果服务器时正常关闭,则会执行destroy方法,只执行一次。用于释放资源
public void destroy(){}

过滤器配置详解

拦截资源路径配置:

  1. 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器在回被执行

    @WebFilter("/index.jsp")
    
  2. 拦截目录:/user/* 访问/user下的所有资源时过滤器都会被执行

    @WebFilter("/user/*")
    
  3. 后缀名拦截:*.jsp 不要写/ 访问所有后缀名为jsp资源时,过滤器都会执行

    @WebFilter("*.jsp")
    
  4. 拦截所有资源:/* 访问所有资源时,过滤器都会执行

    @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配置

    设置标签即可

过滤器链(配置多个过滤器)

过滤器的先后顺序:

  1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
  • 如:ADDlter和BDDlter,ADDlter就会先执行,再比如Acl3和Acl17,Acl17会先执行1<3
  1. web.xml配置:谁定义在上边,谁先执行

执行顺序:如果有两个过滤器:过滤器1和过滤器2:

  1. 过滤器1
  2. 过滤器2
  3. 资源执行
  4. 过滤器2
  5. 过滤器1

案例

案例1

登录验证:

需求:

  1. 访问day1_case案例的资源,验证其是否登录
  2. 如果登录,则直接放行
  3. 如果没有登录就跳转到登录页面,提示“您还未登录请先登录”。

分析:

  1. 判断是否登录相关的资源
    • 是,直接放行
    • 不是,判断是否登录
  2. 判断当前用户是否登录,判断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中的数据改变:你是坏蛋-->你是**

方法:

  1. 对req对象的getParameter方法进行增强产生一个新的request对象
  2. 放行。将新的request对现场传入

chain.doFilter(req,resp);

增强对象的功能:

设计模式:一些通用的解决固定问题的方式

  1. 装饰模式

  2. 代理模式

    概念:

    1. 真实对象:被代理的对象
    2. 代理对象:
    3. 代理模式:代理对象代理真是对象,达到增强真实对象的目的

    实现方式:

    1. 静态代理:有一个类文件描述代理模式
    2. 动态代理:在内存中形成代理类

    实现步骤:

    1. 代理对象和真实对象实现相同的接口
    2. 代理对象 = Proxy.newProxyInstance();
    3. 实现代理对象调用方法
    4. 增强方法
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对象创建后会调用该方法

步骤:

  1. 定义一个类,实现ServletContextListener接口
  2. 复写方法
  3. 配置
    1. web.xml
    2. 注解

先在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是一种在无需重新加载整个页面的情况下,能更新部分页面的技术,提升用户体验

image-20240926160956129

JSON

JavaScript对象表示法

在java中的对象表示使用

Person p=new Person();
p.setName("张三");
p.setAge(23);
var p={"name":"张三","age":"23"};

json现在多用于存储和交换文本信息的语法

进行数据的传输

json比xml更小,更快,更易解析。

语法

基本规则

数据在名称/值对中:json数据是由键值对构成的

键用引号引起来,也可以不使用引号

键值对类型:

  1. 数字(整数或浮点数)
  2. 字符串:(在双引号中)
  3. 逻辑值(true或false)
  4. 数组(在方括号中) {"persons":[{},
  5. 对象(在花括号中){"address":{"procince":"陕西"....}}
  6. null

数据由逗号分隔:多个键值对由逗号分隔

花括号保存对象:使用{}定义json格式

方括号保存数组:[]

Redis

概念

redis是一款高性能的NOSQL系列的非关系型数据库

NOSQL泛指非关系型数据库各个数据之间没有关系

posted @ 2025-04-08 19:53  畏惧不前  阅读(33)  评论(0)    收藏  举报