Java Web 学习笔记

介绍:

  • javaWeb:使用Java语言完成服务器端程序开发

image-20230717135725891


Junit单元测试

测试分类:

  1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
  2. 白盒测试:需要写代码的。关注程序具体的执行流程、

Junit使用:白盒测试

步骤

  1. 定义一个测试类(测试用例)

    建议:

    • 测试类名:被测试的类名Test CalculateTest
    • 包名:xxx.xxx.xx.test cn.itcast.test
  2. 定义测试方法:可独立运行

    建议:

    • 方法名:test测试的方法名 testAdd( )
    • 返回值:void
    • 参数列表:空参
  3. 给方法加@Test注解

  4. 导入Junit依赖环境

判定结果:

  • 红色:失败

  • 绿色:成功

  • 一般我们会使用断言操作来处理结果

    Assert.assertEquals(期望的结果,运算的结果)

示例:

image-20230718072400810


@Before&@After

方法名前加@Before注解 相当于所有测试类开始前都要先执行这个方法

初始化方法:用于资源申请,所有测试方法在执行之前都会先执行该方法

注解@After 释放资源方法:在所有测试方法执行完成后,都会自动执行该方法

总结:

@Before:

​ 修饰的方法会在测试方法之前被执行

@After:

​ 修饰的方法会在测试方法执行之后自动被执行


反射:框架设计的灵魂

框架:半成品软件。 可以在框架的基础上进行软件开发,简化编码

反射:将类的各个组成部分封装为其他对象,这就是反射机制

​ 好处:

    1. 可以在程序运行过程中,操作这些对象
    1. 可以解耦,提高程序的可扩展性

获取Class对象的方式

  1. Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象

    多用于配置文件,将类名定义在配置文件中。读取文件,加载类

  2. 类名.class:通过类名的属性class获取

    多用于参数的传递

  3. 对象.getClass():getClass( )方法在object类中定义着。

    多用于对象的获取字节码的方式

结论:

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。


Class对象功能

此章节JavaSE最后章节反射有讲解

获取功能:

  • 获取成员变量们

    Field[ ] getFields( )

    Field getFields(String name )

    Field[ ] getDeclaredFields( )

    Field getDeclaredFields(String name )

  • 获取构造方法们

    image-20230717163044451

  • 获取成员方法们

    image-20230717163126670

  • 获取类名

​ String getName( )


Field:成员变量

操作:

  1. 设置值

    void set(Object obj,object value)

  2. 获取值

    get(Object obj)

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

    setAccessible(true):暴力反射


Constructor:构造方法

创建对象:

​ T newInstance(Object … initargs)

​ 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法


Method:方法对象

执行方法:

​ Object invoke(Object obj,Object… args)

获取方法名称:

​ String getName:获取方法名

类也可以获取名称


反射案例

没听太懂 回头反复观看


注解

概念:说明程序的。给计算机看的

注释:用文字描述程序的。给程序员看的

概述:

  • JDK1.5之后的新特性
  • 说明程序的
  • 使用注解:@注解名称

作用分类:

  1. 编写文档:通过代码里标识的注解生成文档[生成文档doc文档]
  2. 代码分析:通过代码里标识的注解对代码进行分析[使用反射]
  3. 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查[Override]

JDK中预定义的一些注解

@override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

@SuppressWarnings - 指示编译器去忽略注解中声明的警告。

一般传递参数all @SuppressWarnings(“all”)


自定义注解

//javac 编译文件 java运行 javap 反编译 javadoc 生成API文档

格式:

​ 元注解:

​ public @interface 注解名称{

​ 属性列表

​ }

本质:

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

​ public Interface My Anno extends java.lang.annotation.Annotation { }

属性:接口中的抽象方法

​ 要求:

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

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

    如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值

    如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。

    数组负值时,值使用{ }包裹。如果数组中只有一个值,则{ }省略

​ 赋值示例:

image-20230717202016668

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

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

ElementType取值:

  • TYPE:可以作用于类上

  • METHOD:可以作用于方法上

  • FIELD:可以作用于成员变量上

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

  • Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中并被JVM读取到 三个值 CLASS SOURCE

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

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


在程序中使用(解析)注解

获取注解中定义的属性值

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

  2. 获取指定的注解

    getAnnotation(Class)

    //其实就是在内存中生成了一个该注解接口的一个子类实现对象

    image-20230718072841389

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

    value

使用示例:菜鸟教程

image-20230718074009668


案例:

image-20230718085419789

image-20230718085456622


小结:

  1. 以后大多数时候,我们会使用注解,而不是自定义注解
  2. 注解给谁用?
    1. 编译器
    2. 解析程序用
  3. 注解不是程序的一部分,可以理解为注解就是一个标签

JavaWeb

什么是JavaWeb?

  • 使用Java语言开发互联网项目。简单理解:使用Java语言开发网站

课程介绍:30天

  • 数据库:5天 重要
  • 网页前端:5天
  • web核心技术:15天
  • 旅游管理系统:5天

数据库内容介绍

  1. 数据库的基本概念
  2. MySQL的数据库软件
    1. 安装
    2. 卸载
    3. 配置
  3. SQL语言

数据库的基本概念

  1. 数据库的英文单词:DataBase 简称:DB
  2. 什么是数据库?
    1. 用于存储和管理数据的仓库。
  3. 数据库的特点:
    1. 持久化存储数据的。其实数据库就是一个文件系统
    2. 方便存储和管理数据
    3. 使用了统一的方式操作数据库–SQL
  4. 常见的数据库软件
    1. Oracle
    2. MySQL
    3. SQL Server
    4. …DB2

MySQL数据库软件

MySQL默认端口号 3306 MySQL服务名:MySQL80

  1. 安装

    参考网上文章

  2. 卸载MySQL

    利用geek卸载连带注册表 删除文件夹里面的各个MySql文件夹 删除服务 删除注册表 删除programData隐藏目录下的mysql文件 环境变量也记得修改

  3. 配置

    MySQL服务:

    不想自动启动的话 服务中找到MySQL80 改成手动 自动为开机自启

    命令行:services.msc 打开服务窗口

    使用管理员权限打开cmd:否则会发生权限不够问题

    net stop MySQL80 关闭服务

    net start MySQL80 开启服务

  4. MySQL登陆

  5. mysql -uroot -proot //-u用户名 -p密码

  6. mysql -uroot -p //密码密文

  7. mysql -hip -uroot -p连接目标的密码 //连接目的ip的MySQL

  8. mysql –host=127.0.0.1 –user=root –password=连接目标的密码

  9. 退出

    1. quit
    2. exit

MySQL目录结构

因教学视频版本号为5.x 本机版本号为8.x 存在差异 不作唯一参考

  1. MySQL安装目录

    bin 二进制文件

    data 日志数据文件

    include c语言头信息

    lib jar包

    share MySQL错误信息

    my.ini 配置文件

  2. MySQL数据目录

    隐藏的C盘ProgramData中MySQL文件夹中

    Data文件夹中存取数据

    数据库:文件夹

    表:文件

    数据:文件中存储的数据


SQL

  1. 什么是SQL?

    Structured Query Language:结构化查询语言

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

  2. SQL通用语法

    1. SQL 语句可以单行或多行书写,以分号结尾
    2. 可使用空格和缩进来增强语句的可读性。
    3. MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
    4. 三种注释
      1. 单行注释: – 注释内容 或 # 注释内容(MySQL特有)
      2. 多行注释:/* 注释 */
  3. SQL分类

    1. DDL数据定义语言 (操作数据库、表)

      image-20230718150533737

    2. DML数据操作语言 (增删改表中的数据)

      image-20230718150547629

    3. DQL数据查询语言 (查询表中的数据)

      image-20230718150559147

    4. DCL数据控制语言(了解//授权)

      image-20230718150632396


DDL:操作数据库、表

操作数据库:CRUD

  1. C(Create):创建

    • 创建数据库:

      • create database 数据库名称;
    • 创建数据库,判断不存在,再创建:

      • create database if not exists 数据名称
    • 创建数据库,并指定字符集

      • create database 数据库名称 character set 字符集名;
    • 练习:创建db4数据库,判断是否存在,并指定字符集为GBK

      create database if not exists dbt character set gbk;

  2. R(Retrieve):查询

    1. 查询所有数据库的名称:

      show databases;

    2. 查询某个数据库的字符集:查询某个数据库的创建语句

      show create database 数据库名称;

  3. U(Update):修改

    • 修改数据库的字符集
      • alter database 数据库名称 charaacter set 字符集名称;
  4. D(Delete):删除

    • 删除数据库
      • drop database 数据库名称;
    • 判断数据库存在,存在再删除
      • drop database if exists 数据库名称;
  5. 使用数据库

    • 查询当前正在使用的数据库名称
      • select database();
    • 使用数据库
      • use 数据库名称;

操作表

  1. C(Create):创建

    1. 语法

      create table 表名(列名1 数据类型1,列名2 数据类型2,列名n 数据类型n);

      注意:最后一列,不需要加逗号(,);

    2. 数据库类型:

      1. int:整数类型
        • age int
      2. double:小数类型
        • score double(5,2)
      3. date:日期类型,只包含年月日,yyyy-MM-dd
      4. datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
      5. timestamp:世界戳类型 yyyy-MM-dd HH:mm:ss
        • 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
      6. varchar:字符串
        • name varchar(20) 指定最大字符长度
    3. 创建表

      • create table student(id int,name varchar(32),age int,score double(4,1),birthday date,insert_time timestamp);
    4. 复制表:

      create table 表名 like 被复制的表名;

  2. R(Retrieve):查询

    • 查询某个数据库中所有的表名称
      • show tables;
    • 查询表结构
      • desc 表名;
  3. U(Update):修改

    • 修改表名

      alter table 表名 rename to 新表名 ;

    • 修改 表字符集

      alter table 表名 character set 字符集;

    • 添加一列

      alter table 表名 add 列名 数据类型;

    • 修改列名称 类型

      alter table 表名 change 列名 修改后的列名 新数据类型;

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

    • 删除列

      alter table 表名 drop 列名;

  4. D(Delete):删除

    • drop table 表名;
    • drop table if exists 表名;//可以做判断

客户端图形化工具的使用


DML:增删改表中数据

添加数据

  • 语法:

    insert into 表名(列名1,列名2,…列名n) values (值1,值2,…值n);

  • 注意:

    列名要和值一一对应

    如果表名后,不定义列名,则默认给所有列添加值

    insert into 表名 values (值1,值2,值3,….值n);

  • 除了数字类型,其他类型需要用引号(单双都可以)引起来

删除数据

  • 语法:

    delete from 表名 [where 条件]

  • 注意:

    如果不加条件,则删除表中所有记录;

    如果要删除所有记录

    ​ delete from 表名; – 不推荐使用。有多少记录就执行多少次删除操作 效率低

    ​ truncate table 表名; – 先删除表,然后再创建一张一样的表 效率高

修改数据

  • 语法:

    update 表名 set 列名1 = 值1,列名2 = 值2,…列名n=值n [where 条件];

  • 注意:

    如果不加任何条件,则会将表中所有记录全部修改。


DQL:查询表中的记录

  • select * from 表名; – 查询所有

语法:

​ select 字段列表

​ from 表名列表

​ where 条件列表

​ group by 分组字段

​ having 分组之后的条件

​ order by 排序

​ limit 分页限定

基础查询

  • 多个字段的查询

    select 字段名1,字段名2…. from 表名;

    注意:

    ​ 如果查询所有字段,则可以使用*来替代字段列表

  • 去除重复

    distinct

  • 计算列

    一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)

    ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
    表达式1:哪个字段需要判断是否为null
    ​ 如果改字段为null后的替换值

  • 起别名

    as:as也可以省略 跟在字段名的后面


条件查询

  • where 子句后跟条件

  • 运算符

    • > 、<、<=、>=、=、<>

      select * from student1 where age =20;

      select * from student1 where age != 20;

      select * from student1 where age <>20;

    between…and

    ​ select * from student where age>=20 && age <=30;

    ​ select * from student where age>=20 AND age <=30;

    ​ select * from student where age between 20 and 30;

    in(集合)

    ​ in(10,19,18)– 查询含有这些值得

    like 模糊查找

    • 占位符:
      • _:单个任意字符
      • %:多个任意字符

    is null

    and 或 &&

    or 或 ||

    not 或 !


排序查询

  • 语法:order by 子句

    • order by 排序字段1 排序方式1,排序字段1 排序方式1,…

    • 默认升序

    • 排序方式:ASC:升序 DESC:降序

    • 注意:

      如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件。


聚合函数

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

  • count:计算个数

    一般选择非空的列:主键

    count(*)

  • max:计算最大值

  • min:计算最小值

  • sum:求和

  • avg:计算平均值

注意:聚合函数的计算,排除了null值。

​ 解决方案:

​ 1.选择不包含空的列进行计算

​ 2.IFNULL函数


分组查询

语法:group by 分组字段;

注意:

  • 分组之后查询的字段:分组字段,聚合函数
  • where和having的区别?
    • where在分组之前进行限定,如果不满足条件,则不参加分组
    • having在分组之后进行限定,如果不满足结果,则不会被查询出来
    • where 后不可以跟聚合函数,having 可以进行聚合函数的判断。

分页查询

语法:limit 开始的索引,每页查询的条数;

公式:开始的索引 = (当前的页码-1) * 每页显示的条数

image-20230719104709001

分页操作是一个”方言”


约束

概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性。

分类:

主键约束

  • 主键约束:primary key

    1. 注意:

      1. 含义:非空且唯一
      2. 一张表只能有一个字段为主键
      3. 主键就是表中记录的唯一标识
    2. 在创建表时,添加主键约束

    image-20230719114415011

    1. 删除主键

      image-20230719143520980

    2. 创建表后,添加主键

      image-20230719143554934

    3. 自动增长:

      • 概念:如果某一列是数值类型的,使用 auto_increment 可以完成值得自动增长
      • 创建表时,添加主键约束,并且完成主键自增长
      • 一般和主键一起使用
      • 递增上一个id
      • 删除与添加自动增长使用alter table 表名 modify 命令

非空约束

  • 非空约束:not null 某一列的值不能为null

    1. 创建表时添加约束

      image-20230719110325450

    2. 创建表后,添加非空约束

      image-20230719111310568

    3. 删除非空约束

      image-20230719111338721

唯一约束

  • 唯一约束:unique 某一列的值不能重复

    1. 注意:

      唯一约束可以有NULL值,但是只能由一条记录为NULL

    2. 创建表时,添加条件唯一约束

      image-20230719113609837

    3. 表创建后,添加唯一约束

      image-20230719113705130

    4. 删除唯一约束

      image-20230719112922405

外键约束

  • 外键约束:foreign key 让表与表产生关系,从而保证数据的正确性。

    1. 在创建表时,可以添加外键

      image-20230719154859432

    2. 删除外键

      alter table 表名 modify drop foreign key 外键名称

    3. 创建表之后,添加外键

      alter tbale 表名 modify add constraint 外键名称 foreign key (外键字段名称) references 主表名称(主表列名称)

    4. 级联操作

      • 添加级联

        语法:

        image-20230719161750052

      • 分类:谨慎操作

        1. 级联更新:ON UPDATE CASCADE
        2. 级联删除:ON DELETE CASCADE

数据库的设计

多表之间的关系

  • 一对一关系:

    如:人和身份证

  • 一对多(多对一)关系:

    如:部门和员工

  • 多对多关系:

    如:学生和课程

实现关系:

一对多(多对一)关系

  • 如部门和员工
  • 实现方式:在多的一方建立外键,指向一的一方的主键

多对多关系

  • 多对多关系实现需要借助中间表
  • 实现方式:中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
  • 联合主键

一对一关系

  • 任意一方添加唯一外键指向另一方的主键。

数据库设计的范式

概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求

image-20230721201337892

分类:

  • 第一范式(1NF):每一列都是不可分割的原子数据项
  • 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖
    image-20230721202100076
  • 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)

数据库的备份和还原

命令行方式:

语法:mysqldump -u用户名 -p密码 库名 > 保存的路径

还原:

  1. 登录数据库
  2. 创建数据库
  3. 使用数据库
  4. 执行文件。source文件 文件路径 目的路径是.sql文件

图形化工具方式:

  1. 点击数据库右键 转存sql文件 即可备份

  2. 右键 执行sql文件 即可导入

图像化工具不同可能叫法不同


多表查询

查询语法:select 列名列表 from 表名列表 where…

笛卡尔积:

  • 有两个集合A,B 取这两个集合的所有组成情况。
  • 要完成多表查询,需要消除无用的数据

多表查询的分类:

内连接查询

  1. 隐式内连接:使用where条件消除无用数据
    image-20230721205219837
  2. 显式内连接:[inner] join … on
    image-20230721205435046
  3. 注意
    • 从哪里查数据
    • 条件是什么
    • 查询哪些字段

外连接查询

  1. 左外连接:lift [outer] join … on 查询的是左表所有数据以及其父表部分
    image-20230721211003726
  2. 右外连接:right [outer] join … on 查询的是右 表所有数据以及其父表部分

子查询

概念:查询中嵌套查询,称嵌套查询为子查询

image-20230721213120318

子查询不同情况:

  1. 子查询的结果是单行单列的:
    子查询可以作为条件,使用运算符去判断。运算符:> >= < <= =
  2. 子查询的结果是多行单列的:
    子查询可以作为条件,使用运算符in来判断
    image-20230722073724292
  3. 子查询的结果是多行多列的:
    子查询可以作为一张虚拟表参与查询。
    image-20230722074041285

事务

事务的基本介绍

概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。

操作:

  1. 开启事物:start transaction;
  2. 回滚:rollback;
  3. 提交:commit;

例子:

image-20230722083258602

  1. MySQL数据库中事务默认自动提交

    • 一条DML(增删改)语句会自动提交一次事务。

    • 事务提交的两种方式:

      • 自动提交:
        mysql默认自动提交
      • 手动提交:
        首先开启事务,再提交
    • 修改事务的默认提交方式:

      • 查看事务的默认提交方式:SELECT @@autocommit’ – 1 代表自动提交 0手动提交

      • 修改默认的提交方式:set @@autocommit;


事务的四大特征

  • 原子性:是不可分割的最小操作,要么同时成功,要么同时失败。
  • 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
  • 隔离性:多个事务之间。相互独立。
  • 一致性:事务操作前后,数据总量不变

事务的隔离级别(了解)

概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。

存在的问题:

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

隔离级别:

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

注意:隔离级别从小到大安全性越来越高,但是效率越来越低

数据库查询隔离级别:
select @@tx_isolation;

数据库设置隔离级别:

set global transaction isolation level 级别字符串;


DCL

SQL分类:

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

DBA:数据库管理员

用户管理

DCL:管理用户,授权

  1. 添加用户
    语法:create user ‘用户名‘@’主机名’ identified by ‘密码’;
  2. 删除用户
    语法:drop user ‘用户名‘@’主机名’;
  3. 修改用户
    语法:update user set password = password(‘新密码’) where user = ‘用户名’;
    DCL提供:set password for ‘用户名‘@’主机名’ = password(‘新密码’);
    • mysql中忘记了root用户密码?
      1. cmd – > net stop mysql 停止mysql服务 需要管理员权限
      2. 使用无验证方式启动mysql服务: mysqld –skip-grant-tables
      3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登陆成功
      4. use mysql;
      5. update user set password = password(‘新密码’) where user = ‘root’;
      6. 关闭两个窗口
      7. 打开任务管理器
      8. 手动结束mysqld.exe的进程
      9. 启动MySQL服务
      10. 使用新密码登陆
  4. 查询用户
    1. 切换到mysql数据库
    2. 查询user表
    3. 通配符:%表示可以在任意注意使用用户登陆数据库

权限管理

查询权限

image-20230722103246734

授予权限
grant 权限列表 on 数据库名.表名 to ‘用户名‘@’主机名’;

权限通配符 all 数据库 和 表名 可以用*
image-20230722105707219

撤销权限

语法:revoke 权限列表 on 数据库名.表名 from ‘用户名’ @ ‘主机名’;
image-20230722110331496


JDBC

概念:Java DataBase Connectivity Java数据库连接,Java语言操作数据库

JDBC本质:

image-20230722111714158

快速入门

步骤

  1. 导入驱动jar包
    复制jar包到libs目录下
    右键 add as library 导入
  2. 注册驱动
    Class.forName(“com.mysql.jdbc.Driver”);
  3. 获取数据库连接对象 Connection
    DriverManager.getConnection(“jdbc:mysql://localhost:3306/lijiaxu”,root,root);
  4. 定义sql
    String sql = “sql语句”;
  5. 获取执行sql语句的对象 Statement
    Statement stmt = conn.createStatement();
  6. 执行sql,接收返回结果
    int count = stmt.executeUpdate(sql);
  7. 处理结果
    System.out.println(count);
  8. 释放资源
    stmt.close();
    conn.close();

详解各个对象

  1. DriverManager:驱动管理对象
    告诉驱动需要用哪个jar包

    • 注册驱动: mysql5之后的驱动jar包可以省略注册驱动的步骤。
      image-20230722153052808

    • 获取数据库连接

      方法:static Connection getConnection(String url, String user, String password)
      参数:

      • url:指定连接的路径
        语法:jdbc:mysql://IP地址(域名):端口号/数据库名称
        例子:jdbc:mysql://localhost:3306/db3
        细节:如果连接的是本机的mysql服务器,并且mysql服务默认端口是3306,则url可以简写为jdbc:mysql:///db3
      • user:用户名
      • password:密码
  2. Connection:数据库连接对象

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

    1. 执行sql
      1. boolean execute(String sql):可以执行任意的sql 了解
      2. int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
        返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值大于0的则执行成功,反之,则失败。
      3. ResultSet executeQuery(String sql):执行DQL(select)语句
    2. 练习:
      1. student表 添加一条记录
      2. student表 修改记录
      3. student表 删除记录
  4. ResultSet:结果集对象,封装查询对象结果

    • boolean next():游标向下移动一行, 判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是,则返回true
    • getXXX (参数):获取数据
      • XXX:代表数据类型 如:int getInt()
      • 参数:
        1. int:代表列的编号,从1开始。 如:getString(1) 取第一列的值
        2. String:代表列的名称。 如:getInt(“id”)
    • 使用步骤:
      1. 游标向下移动一行
      2. 判断是否有数据
      3. 获取数据

    image-20230723115951353

    练习:
    查询stu表的数据将其封装为对象,然后装载集合 。然后返回.

        1. 定义Emp类
        1. 定义方法public  List\<Emp>  findAll()  {  }
        1. 实现方法  select  *  from  emp;
    
  5. PreparedStatement:执行sql的对象 (重要)

    image-20230724104429477


JDBC工具类

目的:简化书写

分析:

  1. 抽取注册驱动
    抽取一个方法获取连接对象
    需求:不想传递参数(麻烦),还得保证工具类的通用性。
    解决:配置文件

    image-20230724074247680

  2. 抽取一个方法释放资源


需求:

  1. 通过键盘录入用户名和密码
  2. 判断用户是否登陆成功

JDBC控制事务

事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败

操作:

  1. 开启事务
  2. 提交事务
  3. 回滚事务

使用 Connection对象来管理事务

  • 开启事务:setAutoCommit(boolean autoCommit) false开启事务
    在执行sql之前开启事务
  • 提交事务:commit()
    当所有sql都执行完提交事务
  • 回滚事务:rollback()
    在catch中回滚事务

数据库连接池

概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数 据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

好处:
1. 用户访问高效
1. 节省资源

实现:

  1. 标准接口:DataSource javax.sql包下的

    1. 方法:
      获取连接:getConnection( )

      归还连接:close() 如果连接对象Connection是从连接池中获取的,那么调用Connection.close( )方法,咋不会关闭连接,而是归还连接

  2. 一般我们不去实现它,有数据库厂商来实现

    1. C3P0:数据库连接池技术
        2. Druid:德鲁伊  数据库连接池实现技术,由阿里巴巴提供的
    

C3P0:数据库连接池

步骤:

  1. 导入jar包
    image-20230724113117961
    不要忘记导入驱动jar包
  2. 定义配置文件:
    image-20230724113334952
    路径:直接将文件放在sec目录下即可
  3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
  4. 获取连接:getConnection()

Druid:数据库连接池

由阿里巴巴提供

步骤:

  1. 导入jar包 druid-1.0.9.jar
  2. 定义配置文件:
    是properties形式的
    可以叫任意名称,可以放在任意目录下
  3. 加载配置文件 Properties
  4. 获取数据库连接池对象:
    通过工厂类来获取 DruidDataSourceFactory
  5. 获取连接:getConnection

定义工具类

  1. 定义一个类 JDBCUtils
  2. 提供静态代码块加载配置文件,初始化连接池对象
  3. 提供方法
    1. 获取连接方法:通过数据库连接池获取连接
    2. 释放资源
    3. 获取连接池的方法

Sprint JDBC

Spring框架对JDBC的简单封装 。

提供了JDBCTemplate对象简化JDBC的开发

步骤:

  1. 导入jar包
    image-20230724144741407

  2. 创建JbdcTemplate对象。依赖于数据源DataSource
    JdbcTemplate template = new JdbcTemplate(ds);

  3. 调用JdbcTemplate的方法来完成CRUD的操作
    update():执行DML语句。增删改语句
    queryForMap():查询结果将结果集封装为Map集合

    ​ 注意:这个方法查询的结果集长度只能是1

    queryForList():查询结果将结果集封装为list集合

    ​ 注意:将每一条记录封装为一个Map集合,再将Map集合装在到List集合中

    query():查询结果,将结果封装为javaBean对象

    ​ query的参数:RowMapper
    ​ 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的 自动封装
    ​ new BeanPropertyRowMapper<类型>(Emp.class)

    queryForObject:查询结果,将 结果封装为对象

  4. 练习:
    需求:

    1. 修改1号数据的salary为10000
    2. 添加一条记录
    3. 删除刚才添加的记录
    4. 查询id为1的记录,将其封装为map
    5. 查询所有记录 封装为list
    6. 查询所有记录,将其封装为emp对象的list集合
    7. 查询总记录数

Web

概述:

  • JavaWeb:使用Java语言开发基于互联网的项目

  • 软件架构:

    • C/S:Client/Server 客户端/服务器端
      再用户本地有一个客户端程序,再远程有一个服务器端程序
      如:QQ,迅雷..
      优点:
      1. 用户体验好
      缺点:
      1. 安装,部署,开发,维护 麻烦

    • B/S:Browers/Server浏览器/服务器端
      只需要一个浏览器,用户通过不同的网址(URL),客户访问不同的服务器端程序

      优点:
      1. 开发、安装、部署、维护简单
      缺点:

      1. 如果应用过大,用户的体验可能会受到影响
      2. 对硬件要求过高

B/S架构详解

客户端浏览器请求服务器

资源分类:

  1. 静态资源:
    使用静态网页开发技术发布的资源
    特点:
    所有用户访问,得到的结果是一样的
    如:文本,图片,音频,视频,
    HTML,CSS,JavaScript 静态网页开发
    如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器。浏览器中内置了静态资源的解析引擎,可以展示静态资源
  2. 动态资源:
    使用动态网页及时发布的资源。
    特点:
    • 所有用户访问,得到的结果可能不一样。
    • 如:jsp/servlet,php,asp…
    • 如果用户请求的是动态资源,那么服务器会执行动态资源,转换为静态资源,再发送给浏览器

要学习动态资源,必须先学习静态资源!

静态资源:静态网页技术三剑客

  • HTML:用于搭建基础网页,展示页面的内容
  • CSS:用于美化页面,布局页面
  • JavaScript:控制页面的元素,让页面有一些动态的效果

HTML

概念:Hyper Text Markup Language 超文本标记语言 最基础的网页开发语言

  • 超文本:超文本是用超链接的方法,将各种不同空间的文件信息组织在一起的网状文本。
  • 标记语言:由标签构成得语言。<标签名称> 如HTML,XML
    标记语言不是编程语言

HTML快速入门

语法:

  1. HTML文档后缀名 .html 或 .htm
  2. 标签分为
    1. 围堵标签:有开始标签和结束标签。如<html></html>
    2. 自闭和标签:开始标签和结束标签在一起。如<br/>
  3. 标签可以嵌套:
    需要正确嵌套,不饿能你中有我,我中有你
  4. 在开始标签中可以定义属性。属性是由键值对构成,值需要用引号(单双均可)引起来
  5. html的标签不区分大小写,建议使用小写

标签

文件标签

概述:构成html最基本的标签

  • html:html文档的根标签 最顶层
  • head:头标签。用于指定html文档的一些属性。引入外部资源
  • title:标题标签
  • body:体标签
  • <!DOCTYPE html> :html5中定义该文档是html文档

文本标签

概述:和文本有关的标签

  • 注释:<!– 注释内容 – >

  • <h1> to <h6>:标题标签 字体大小逐渐递减

  • <p>:段落标签

  • <br>:换行标签

  • <hr>:显示一条水平线
    属性:改变一些样式

    color:颜色

    width:宽度

    size:高度

    align:对齐方式
    center:居中 left:左对齐 right:右对齐
    不建议使用 css可以控制

  • <b>:字体加粗

  • <i>:字体斜体

  • <font>:字体标签

  • <center>:文本居中

    属性:
    color:颜色
    sieze:大小
    face:字体

    属性定义:
    color:

    1. 英文单词:red,green,blue
    2. rgb(值1,值2,值3):值得范围:0~255
    3. #值1值2值3:值得范围:00~FF之间。十六进制

    width:

    1. 数值:width=’20’,数值的单位,默认是px(像素)
    2. 数值%:占比相对于父元素的比例

图片标签

​ img:展示图片
​ src:指定图片的路径
​ 相对路径:以 . 开头的路径
​ . /:代表当前目录 . /image/1.jpg
​ .. / :代表上一级目录
​ 如:<img src=”./image/jiangwai_1.jpg”>
​ <img src=”../image/jiangwai_1.jpg”>

列表标签

  1. 有序列表:
    • ol 创建一个有序列表
    • li 包裹变为项
    • type属性可以指定样式 1 A a I i
    • start 可以指定开始的项
  2. 无序列表
    • ul
    • li
    • type属性可以改变类型 disc square circle

超链接标签

  1. <a>:定义一个超链接
    • href属性* href=”www.baidu.com“ Typora中 Ctrl + 左键跳转链接 指定访问资源的url url统一资源定位符 路径的表示形式 可以访问本地内部资源 mailto:邮箱 可以直接跳转到本地邮件客户端给指定邮箱发送邮件
    • target属性 值 _self(默认值)表示本页面内打开 _blank 新的空白窗口打开

div和span:块标签

span:文本信息在一行展示,行内标签 内联标签

div:每一个div占满一整行。块级标签

语义化标签

HTML5中为了提高程序的可读性,提供了一些标签。

<header> </header>

<footer> </footer>

只是来表示头和尾方便理解

表格标签

table:定义表格

  • width:宽度
  • border:边框
  • cellpadding:定义内容和单元格的距离
  • cellspacing:定义单元格之间的距离。如果指定为0,则单元格的线会合为一条
  • bgcolor:背景色
  • aglin:对齐方式

tr:定义行

  • bgcolor:背景色
  • aglin:对齐方式

td:定义单元格

  • colspan:合并列
  • rowspan:合并行

th:定义表头单元格

<caption> :表格标题

<thead>:表示表格的头部分

<tbody>:表示表格的体部分 增强可读性

<tfoot>:表示表格的脚部分

特殊字符表

image-20230727074137631


案例:

  1. 确定使用table来完成布局
  2. 如果某一行只有一个单元格,则使用<tr><td></td></tr>
  3. 如果某一行由多个单元格,则使用嵌套形式
    image-20230727114042356

表单标签*

概念:用于采集用户输入的数据的。用于和服务器进行交互。

使用的标签:form:用于定义表单的。可以定义一个范围,范围代表采集用户数据的范围

form的属性:

  • action:指定提交数据的URL 输入的数据提交的此地址

  • method:指定提交方法

    • 分类:一共有7种,2种比较常见
      get:

      • 请求参数会在地址栏中显示,会封装在请求行中
      • 请求参数的长度是由限制的
      • 不太安全

      post:

      • 请求参数不会在地址栏中显示,会封装在请求体中(HTTP协议后讲解)
      • 请求参数的大小没有限制
      • 较为安全
    • 表单项种的数据要想被提交,必须指定name属性

表单项标签*

  • input:可以通过type属性值,改变元素展示的样式
    • type属性:
      • text:文本输入框,input的默认类型
        1. value :指定默认值
        2. placeholder :指定输入框的提示信息,当输入框的内容发生变化,会自动清空提示信息
      • password:密码输入框,自动密文显示
      • radio:单选框
        1. 要想让多个单选框实现单选的效果,则多个单选框的的name属性值必须一样。name相同为一组单选框
        2. 一般会给每一个单选框提供value属性,指定其被选中后提交的值
      • checkbox:复选框
        1. 无法区分提交值,应该给定value值,来确定提交的值
      • radio和checkbox共同属性:checked=”checked” 或者checked 指定默认值 启动默认选择
      • file:文件选择框
      • hidden:隐藏域,用于提交一些信息的
      • 按钮
        • submit:提交按钮,可以提交表单
        • button:一个按钮
        • <input type=”image” src = “路径”>:将按钮背景改为图片,也可以提交表单
    • label:指定输入项的文字描述信息
      • 注意:
        • label的for属性一般会和 input 的 id 属性值 对应,如果对应,则点击label区域,会让input输入框获得焦点
    • HTML5新type类型
      image-20230727210348768
  • select:下拉列表
    1. 子元素 :<option> 内容选项,指定列表项
    2. selected
  • textarea:文本域
    属性:
    1. cols:指定列数,每一行有多少个字符
    2. rows:默认多少行。

CSS

页面美化和布局控制

概念:Cascading Style Sheets 层叠样式表

  • 层叠:多个样式可以作用在同一个html的元素上,同时生效

好处:

  • 功能强大
  • 将内容展示和样式控制分离
    • 降低耦合度。解耦
    • 让分工协作更容易
    • 提高开发效率

css页面美化和布局

CSS的使用

CSS与HTML结合方式

  1. 内联样式:由于没有降低耦合,不推荐

    • 标签内使用style属性指定css代码
  2. 内部样式

    • 在head标签内,定义style标签,style标签的标签体内容就是css代码
  3. 外部样式

    • 定义css资源文件。

    • 在head标签内,定义link标签,引入外部的资源文件

  4. 注意:1,2,3 ,作用范围越来越大——
    1方式不常用,后期常用2,3

​ 第三种格式导入css资源文件 可以在head标签中导入文件
image-20230728094624082


CSS语法

格式:

​ 选择器 {

​ 属性名1:属性值1;

​ 属性名2:属性值2;

​ …

​ }

选择器:筛选具有相似特征的元素

注意:

  • 每一对属性需要使用;隔开,最后一对属性可以不加分号

选择器

分类:

  1. 基础选择器

    1. id选择器:选择器具体的id属性值的元素,建议在一个html中 id中唯一
      语法:#id属性值{}
    2. 元素选择器:选择具有相同标签名称的元素
      语法:标签名称{}
      注意:id选择器优先级要高于元素选择器
    3. 类选择器:选择具有相同的class属性值的元素
      语法:.class属性值{}
      注意:类选择器优先级高于元素选择器
  2. 扩展选择器

    1. 选择所有元素:

      语法:* { }

    2. 并集选择器:
      语法:选择器1,选择器2{ }

    3. 子选择器:筛选选择器1元素下的选择器2元素
      语法:选择器1 选择器2 { }

    4. 父选择器:筛选选择器2的父元素选择器1
      语法:选择器1 > 选择器2 { }

    5. 属性选择器:选择元素名称,属性名=属性值的元素

      1. 1语法:元素名称[属性名 = “属性值”] { }
    6. 伪类选择器:选择一些元素具有的状态

      语法:元素:状态{ } 如:a:link

      如:<a>
      状态:
      link:初始化的状态
      ​ visited:被访问过的状态

      ​ active:正在访问状态

      ​ hover:鼠标悬浮状态


属性

字体、文本

  • font-size:字体大小
  • color:文本颜色
  • txet-align:对齐方式
  • line-height:行高

背景

  • background:

边框

  • boder:设置边框,复合属性
    boder-radius:圆角

尺寸

  • width:宽度
  • height:高度

盒子模型:控制布局

  • margin:外边距
  • padding:内边距
    • 默认情况下内边距会影响整个盒子的大小
    • box-sizing:border-box; 设置盒子的属性,让width和height就是最终盒子的大小
  • float:浮动
    • left
    • right

JavaScript*

概念:一门客户端脚本语言

  • 运行在客户端浏览器中的。每一个浏览器哦都有JavaScript的解析引擎

  • 脚本语言:不需要编译,直接就可以被浏览器解析执行

功能:

  • 可以来增强用户和html页面的交互过程,可以来控制html元素,让页面有一些动态的效果,增强用户的体验

JavaScript发展史:

  • 1992年,Nobase公司,开发出第一门客户端脚本语言,专门用于表单校验。命名为C- - ,后来更名为:ScriptEase
  • 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LIveScript。后来,请来了SUN公司的专家,修改LiveScript,命名为JavaScript
  • 1996年,微软抄袭JavaScript开发出JScript语言
  • 1997年,ECMA(欧洲计算机制造商协会),ECMAScript,就是所有客户端脚本语言的标准。

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


ECMAScript

基本语法

  1. 与html结合方式

    1. 内部JS
      • 定义<script>,标签体内容就是js代码
    2. 外部JS
      • 定义<script>,通过src属性引入外部的js文件
    3. 注意:
      • <script>可以定义在html页面的任何地方,但是定义的位置会影响执行的顺序
      • <script>可以定义多个
  2. 注释

    1. 单行注释://注释内容
    2. 多行注释:/*注释内容*/
  3. 数据类型 typeof可以检测数据类型 document.writer可以把内容输出来body

    1. 原始数据类型(基本数据类型):
      1. number:数字。整数/小数/NaN(not a number 一个不是数字的数字类型)
      2. string:字符串。字符串 “abc” “a” ‘abc’
      3. boolean:true和false
      4. null:一个对象为空的占位符
      5. undefined:未定义。如果一个变量没有被初始化值,则会被默认赋值为undefined
    2. 引用数据类型(对象):
  4. 变量:

    • 变量:一小块存储数据的内存空间
    • Java语言是强类型语言,而JavaScript是弱类型语言。
      • 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
      • 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
    • 语法:
      • var 变量名 = 初始化值;
  5. 运算符

    • 一元运算符:只有一个运算数的运算符
      ++ – , +(正号) -(负号)
      注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算符进行类型转换
      其他类型转number:

      • string转number:按照字面值转换,如果字面值不是数字,则转为NaN(不是数字的数字)
      • boolean转number:true转为1,false转为0
    • 算术运算符:
      + - * / % …

    • 赋值运算符
      = += -= ….

    • 比较运算符
      > < >= <= == ===(全等于)
      比较方式

      1. 类型相同,直接比较
        • 字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。
      2. 类型不同,先进行类型转换,再比较
        • === 全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
    • 逻辑运算符
      && 短路与 || 短路或 ! 非
      其他类型转boolean

      1. number:0或NaN为假,非0为true
      2. string:除了” “ 字符串,其他都是true
      3. null&undefined:都是false
      4. 对象:都是true

      image-20230729090912464

    • 三元运算符
      ? :表达式

  6. 流程控制语句

    1. if … else. ..
    2. switch
      • 在Java中,swithc语句可以接受的数据类型:byte int short char 枚举(1.5) string(1.7)
        • switch(变量):
          case 值 :
      • 在JS中,switch语句可以接受任意的原始数据类型
        image-20230729093527190
    3. while
    4. do … while
    5. for
  7. JS特殊语法:

    • 特殊语法
      1. 语句以;结尾,如果一行只有一条语句则;可以省略,**(不建议)**
      2. 变量的定义使用var关键字,也可以不使用
        用:定义的变量为局部变量
        不用:定义的变量为全局变量**(不建议)**
  8. 练习:带边框得99乘法表


基本对象

Function:函数对象
  1. 创建:

    1. var fun = new Function(形式参数列表,方法体): //忘掉

    2. function 方法名称(形式参数列表){

      ​ 方法体

      }

    3. var 方法名 = function (形式参数列表) {

      ​ 方法体
      }

  2. 方法:

  3. 属性:
    length:代表形参的个数

  4. 特点:

    1. 方法定义是,形参的类型不用写,返回值类型也不写
    2. 方法是一个对象,如果定义名称相同的方法,会覆盖
    3. 在JS中,方法的调用只与方法的名称有关,和方法的参数列表无关
    4. 在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
  5. 调用:
    方法名称(实际参数列表);


Array:数组对象
  1. 创建

    1. var arr = new Array(元素列表);
    2. var arr = new Array(默认长度);
    3. var arr = [元素列表];
    4. var arr = new Array
  2. 方法
    join(参数):将数组中的元素按照指定的分隔符拼接为字符串

    push( ):向数组的末尾添加一个或更多元素,并返回新的长度

  3. 属性

    length:数组的长度

  4. 特点

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

Date:日期对象

创建:

  1. var date = new Date( );

方法:

  1. tolocalString( ):返回当前date对象对应的时间本地字符串格式
  2. getTime( ):获取毫秒值。返回当前日期时间对象描述的时间到1970年1月1日零点的毫秒值差

Math:数学对象

创建:

  • 特点:Math对象不用创建,直接使用。Math.方法名( );

方法:

  • random( ):返回0-1之间的随机数。含0不含1
  • ceil(x):对数进行上舍入。
  • floor(x):对数进行下舍入。
  • round(x):把数四舍五入为最接近的整数。

属性:

  • PI

RegExp:正则表达式对象

正则表达式:定义字符串的组成规则

  1. 单个字符:[ ]
    如:[ a ] [ ab ] [ a-zA-Z0-9_ ]
    特殊符号代表特殊含义的单个字符
    \d:单个数字字符[0-9]
    \w:单个单词字符[ a-zA-Z0-9_ ]

  2. 量词符号:
    ?:表示出现0次或1次
    *:表示出现0次或多次
    +:表示出现1次或多次
    {m,n}:表示 m <= 数量 <=n

    • m如果缺省:{ ,n}:最多n次
    • n如果缺省:{m, }:最少m次

    \w* 表示字符串组成规则为单词字符构成单词字符出现0次或多次

  3. 开始结束符号
    ^:开始
    $:结束
    /^ab$/ 表示只会匹配到 以a打头 b结束的字符串

正则对象:

  1. 创建
    1. var reg = new RegExp(“正则表达式”);
    2. var reg = /正则表达式/;
  2. 方法
    1. **test(参数)**:验证指定的字符串是否符合正则定义的规范

Global:全局对象

特点:全局对象,这个Global封装的方法不需要对象就可以直接调用。方法名( );

全局属性和函数可用于所有内建的JavaScript对象。

方法:

  1. encodeURI( ):url编码
    decodeURI( ):url解码
  2. encodeURIComponent( ):url编码
    decodeURIComponent( ):url解码
  3. parseInt( ):将字符串转为数字
    逐一判断每一个字符是否是数字,直到不是数字为止,将前边部分数字部分转为number
  4. isNaN:判断一个值是否是NaN
    NaN六亲不认,连自己都不认。NaN参与的==比较全部为false
  5. **eval( )**:计算JavaScript字符串,并把它作为脚本代码来执行

URL编码
image-20230730212201044


DOM简单学习

为了满足案例要求

功能:控制html文档的内容

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

  • document.getElementByID(“id值”):通过元素的id获取元素对象

操作对象Element对象:

  1. 修改属性值:
    1. 明确获取的对象是哪一个?
    2. 查看API文档,找其中有哪些属性可以设置
  2. 修改标签体内容:
    1. 属性:innerHTML

举例:
image-20230731093231681


事件简单学习

功能:某些组件被执行了某些操作后,触发某些代码的执行

如何绑定事件

  1. 直接在html标签上,指定事件的属性(操作),属性值就是js代码
    1. 事件:onclick — 单击事件
  2. 通过js获取元素对象,指定事件属性,设置一个函数
    image-20230731102022320

案例:电灯开关


BOM

概念:Browser Object Model 浏览器对象模型
将浏览器的各个组成部分封装成对象

组成:

  • Window:窗口对象
  • Navigator:浏览器对象
  • Screen:显示器屏幕对象
  • History:历史记录对象
  • Location:地址栏对象

Window:窗口对象

  1. 创建

  2. 方法

    1. 与弹出框有关的方法:

      • **alert()**:显示带有一段消息和一个确认按钮的警告框。

      • **confirm()**:显示带有一段消息以及确认按钮和取消按钮的对话框

        • 如果用户点击确定按钮,则方法返回true
        • 如果用户点击取消按钮,则方法返回false
      • **prompt()**:显示可提示用户输入的对话框

        • 返回值:获取用户输入的值 , 参数里面可以指定提示内容
    2. 与打开关闭有关的方法:

      • **close()**:关闭浏览器窗口
        谁调用我,我关谁
        window.close();
      • **open(“ “)**:打开一个新的浏览器窗口
        参数可以传url,来打开指定地址的新窗口
        返回值是新的window对象
    3. 与定时器有关的方法:

      • **setTImeout()**:在指定的毫秒数后调用函数或计算表达式 一次性
        参数:

        1. js代码或者方法对象
        2. 毫秒值

        返回值:

        ​ 返回计时器的唯一编号id,用于取消定时器

      • **clearTimeout()**:取消由setTImeout() 方法设置的 timeout
        参数:

        1. 定时器的唯一编号,来确定取消哪一个定时器
      • **setInterval()**:按照指定的周期(以毫秒计)来调用函数或计算表达式 循环性

      • 参数:

        1. js代码或者方法对象
        2. 毫秒值

        返回值:

        ​ 返回计时器的唯一编号id,用于取消定时器

      • **clearInterval()**:取消由setInterval() 设置的 timeout。

      • 参数:

        1. 定时器的唯一编号,来确定取消哪一个定时器
  3. 属性

    1. 获取其他BOM对象
      history
      location
      Navigator
      Screen
    2. 获取DOM对象
      document
  4. 特点

    • Window对象不需要创建可以直接使用 window使用。window.方法名();
    • window引用可以省略。 方法名();

Location:地址栏对象

  1. 创建(获取):
    1. window.location
    2. location
  2. 方法:
    • reload( ) 重新加载当前文档。 刷新
  3. 属性:
    • href:设置或返回完整的URL。

History:历史记录对象

History对象包含用户(在浏览器窗口中)访问过的URL。

  1. 创建(获取):
    1. window.history
    2. history
  2. 方法
    1. back()
    2. forward()
    3. go(参数)
      参数:
      • 正数:前进几个历史记录
      • 负数:后退几个历史记录
  3. 属性
    length:返回当前窗口历史列表中的URL历史记录数量

DOM

概念:Document Object Mode 文档对象模型

  • 将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行一些CRUD的的动态操作

HTML DOM 定义访问和操作HTML文档的标准方法。

DOM将HTML文档表达为树形结构
image-20230731192229566


W3C DOM 标准被分为3个不同的部分:

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

    • Document:文档对象

    • Element:元素对象

    • Attribute:属性对象

    • Text:文本对象

    • Comment:注释对象

    • Node:节点对象,其他5个的父对象

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

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


核心DOM模型:

  • Document:文档对象
  • Element:元素对象
  • Node:节点对象,其他5个的父对象

Document:文档对象

  1. 创建(获取):在html dom模型中可以使用window对象来获取
    1. window.document
    2. document
  2. 方法:
    1. 获取Element对象:
      1. getElementById():根据id属性值获取元素对象。id属性值
      2. getElementsByTagName():根据元素名称获取元素对象们。返回值是一个数组
      3. getElementsByClassName():根据Class属性值获取元素对象们。返回值是一个数组
      4. getElementsByName():根据name属性值获取元素对象们。返回值是一个数组
    2. 创建其他DOM对象:
      1. createAttribute(name):
      2. createComment():
      3. createElement():
      4. createTextNode():
  3. 属性:

Element:元素对象

  1. 创建(获取):通过document来获取和创建
  2. 方法:
    1. removeAttribute():删除属性
    2. setAttribute():设置属性

Node:节点对象

其他5个的父对象

  • 特点:所有dom对象都可以被认为是一个节点
  • 方法:
    CRUD dom树:
    1. appendChild():向节点的子节点列表的结尾添加新的子节点。
    2. removeChild():删除(并返回)当前节点的指定子节点。
    3. replaceChild():用新节点替换一个子节点。

案例:其中的javascript:void(0);来让a标签没有跳转
image-20230801092355611


  • 属性:
    1. parentNode:返回节点的父节点。

HTML DOM

  1. 标签体的设置和获取:innerHTML
    内容可以替换为html代码
  2. 使用html元素对象的属性
  3. 控制元素样式
    1. 使用元素的style属性来设置
      如:
      image-20230801142506588
    2. 提前定义好类选择器的样式,通过元素的className属性来设置其class属性值

BootStrap框架

概念:一个前端开发的框架

  • 框架:一个半成品软件,开发人员可以在框架基础上,再次开发,简化编码
  • 好处:
    1. 定义了很多的css样式和js插件。我们开发人员直接可以使用这些样式和插件,得到丰富的页面效果。
    2. 响应式布局。
      • 同一套页面可以兼容不同分辨率的设备。

快速入门

  1. 下载bootstrap

  2. 在项目中将这三个文件夹复制过来

  3. 创建html页面,引入必要的资源文件
    引入模板

    <!doctype html>
    <html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <title>Bootstrap 101 Template</title>
    
        <!-- Bootstrap -->
        <link rel="stylesheet" href="../css/bootstrap.min.css" >
    
    
    </head>
    <body>
    <h1>你好,世界!</h1>
    
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="../js/jquery-3.2.1.min.js" ></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="../js/bootstrap.min.js" ></script>
    </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:大屏幕 大桌面显示器 (>=1200px)
  • 注意事项
    1. 一行中如果格子数目超过12,则超出部分自动换行
    2. 栅格类属性可以向上兼容。栅格类适用于与屏幕宽度大小或等于分界点大小的设备
    3. 如果真实设备宽度小于了设置的栅格类属性的设备代码的最小值,会一个元素占满一整行。

CSS 样式和 JS 插件

要求可以达到看文档,直接拿过来用

全局CSS样式:

  • 按钮:class=”btn btn-default” btn-default可以修改为指定样式

  • 图片:

    • class=”img-responsive“:图片在任意尺寸都占100%

    • 图片形状

      <img src="..." alt="..." class="img-rounded">  	//方的
      <img src="..." alt="..." class="img-circle">	//圆的
      <img src="..." alt="..." class="img-thumbnail">	//带框的
  • 表格

    • table
    • table-bodered
    • table-hover
  • 表单

    • 给表单项添加class=”form-control”

组件:

  • 导航条
  • 分页条

插件:

  • 轮播图

事件监听机制

概念:某些组件被执行了某些操作后,触发某些代码的执行。

  • 事件:某些操作,单击,双击,键盘按下,鼠标移动
  • 事件源:组件。如:按钮 文本输入框…
  • 监听器:代码。
  • 注册监听:将事件,事件源,监听器结合在一起。当事件源上发生了某个事件,则触发执行某个监听器代码。

常见的事件

  1. 点击事件

    1. onclick:单击事件
    2. ondblclick:双击事件
  2. 焦点事件

    1. onblur:失去焦点
    2. onfocus:获得焦点
  3. 加载事件

    1. onload:一张页面或一幅图像完成加载
  4. 鼠标事件:

    1. onmousedown:鼠标按钮被按下
      • 定义方法时,定义一个形参,接收event对象
      • event对象的button属性可以获取鼠标按钮键被点击了
      • 左键0,中键1,右键2
    2. onmouseup:鼠标按键被松开
    3. onmousemove:鼠标被移动
    4. onmouseover:鼠标移到某元素之上
    5. onmouseout:鼠标从某元素移开
  5. 键盘事件

    1. onkeydown:某个键盘按键被按下。
    2. onkeyup:某个键盘按键被松开。
    3. onkeypress:某个键盘按键被按下并松开。
  6. 选择和改变

    1. onchange:域的内容被改变。
    2. onselect:文本被选中。
  7. 表单事件

    1. onsubmit:确认按钮被点击。

      • 可以阻止表单的提交

        • 方法返回false则表单被阻止提交
          方法1:
          image-20230802075842917

          方法2:
          image-20230802075909406

    2. onreset:重置按钮被点击。


XML

w3c:万维网联盟

概念:Extensible Markup Language 可扩展标记语言

  • 可扩展:标签都是自定义的。 <user></user>

功能:

  • 存储数据
    1. 配置文件
    2. 在网络中传输

xml和html的区别

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

XML快速入门

语法:

  • 基本语法:

    1. xml文档的后缀名.xml
    2. xml第一行必须定义为文档声明
    3. xml文档中有且仅有一个根标签
    4. 属性值必须使用引号(单双都可)引起来
    5. 标签必须正确关闭
    6. xml标签名称区分大小写
  • 快速入门:
    image-20230802101545425

  • 组成部分:

    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文档的书写规则

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

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

    1. DTD:一种简单的约束技术
    2. Schema:一种复杂的约束技术
  • DTD:

    • 引入dtd文档到xml文档中
      • 内部dtd:将约束规则定义在xml文档中
      • 外部dtd:将约束的规则定义在外部的dtd文件中
        • 本地:<!DOCTYPE 根标签名 SYSTEM “dtd文件的位置”>
        • 网络:<!DOCTYPE 根标签名 PUBLIC “dtd文件名字” “dtd文件的位置URL”>
  • Schema:

    声明命名空间xmlns

    后缀名.xsd
    image-20230802144904333


解析:操作xml文档,将文档中的数据读取到内存中

  • 操作xml文档
    1. 解析(读取):将文档中的数据读取到内存中
    2. 写入:将内存中的数据保存到xml文档中。
  • 解析xml的方式:*
    1. DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树
      • 优点:操作方便,可以对文档进行CRUD的所有操作
      • 缺点:占内存
    2. SAX:逐行读取,基于事件驱动的。
      • 优点:不占内存
      • 缺点:只能读取,不能增删改
  • xml常见的解析器:
    1. JAXP:sun公司提供的解析器,支持dom和sax两种思想
    2. DOM4J:一款非常优秀的解析器
    3. Jsoup:jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据。
    4. PULL:Android操作系统内置的解析器,sax方式的。

Jsoup解析器

快速入门

  • 步骤:

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

    image-20230802154835413

  • 对象的使用:

    1. Jsoup:工具类,可以解析html或xml文档,返回Document

      • parse:解析html或xml文档,返回Document
        • parse(File in, String charsetName) 解析xml或html文件的。
        • parse(String html):解析xml或html字符串
        • parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
    2. Document:文档对象。代表内存中的dom树
      获取Element

      • getElementById(String id):根据id属性值获取唯一的element对象

      • getElementsByTag(String tagName):根据标签名称获取元素对象集合

      • getElementsByAttribute(String Key):根据属性名称获取元素对象集合

      • getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值来获取元素对象

    3. Elements:元素Element对象的集合。可以当做ArrayList<Element>来使用

    4. Element:元素对象

      1. 获取子元素对象

        • getElementById(String id):根据id属性值获取唯一的element对象

        • getElementsByTag(String tagName):根据标签名称获取元素对象集合

        • getElementsByAttribute(String Key):根据属性名称获取元素对象集合

        • getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值来获取元素对象

      2. 获取属性值

        • String attr(String key):根据属性名称获取属性值
      3. 获取文本内容

        • String text():获取所有子标签的纯文本内容
        • String html():获取标签体的所有内容(包括子标签的标签和文本内容)
    5. Node:节点对象
      是Docoument和Element的父类


快捷查询方式

  1. selector:选择器
    • 使用的方法:Elements select(String cssQuery)
      • 语法:参考Selector类中定义的语法
  2. XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言
    • 使用Jsoup的Xpath需要额外导入jar包。
    • 查询w3cschool参考手册,使用xpath的语法完成查询

Web核心

web相关概念回顾

  1. 软件架构
    1. C/S:客户端/服务器端
    2. B/S:浏览器/服务器端 请求/响应
  2. 资源分类
    1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析
      如:html,css,javascript
    2. 动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换成静态资源,在返回给浏览器
      如:servlet/jsp,php,asp…
  3. 网络通信三要素
    1. IP:电子设备(计算机)在网络中的唯一标识
    2. 端口:应用程序在计算机中的唯一标识。0-65536 1024以内可能被系统占用
    3. 传输协议:规定了数据传输的规则
      1. 基础协议:
        1. tcp:安全协议,三次握手。速度稍慢
        2. udp:不安全的协议。有可能丢失。速度快

Web服务器软件

  • 服务器:安装了服务器软件的计算机
  • 服务器软件:接收用户的请求 ,处理请求,做出响应
  • web服务器软件:接收用户的请求,处理请求,做出响应
    • 在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目
    • web容器
  • 常见的java相关的web服务器软件:
    • weblogic:Oracle公司,大型的javaEE服务器,支持所有的javaEE规范收费的。
    • webSphere:IBM公司,大型的javaEE服务器,支持所有的javaEE规范收费的。
    • JBOSS:JBOSS公司的,大型的javaEE服务器,支持所有的javaEE规范收费的。
    • Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范servlet/jsp。开源的,免费的。
  • JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范

Tomcat

web服务器软件

  1. 下载 Apache Tomcat® - Welcome!

  2. 安装:解压压缩包即可。
    注意:安装目录建议不要有中文和空格

  3. 卸载:删除安装目录文件夹
    目录结构:
    image-20230803072417390

  4. 启动:startup:启动 默认端口:8080

    • bin/startup.bat,双击运行该文件即可
      • 访问:浏览器输入:http://;localhost:8080 回车访问自己
        http://别人ip:8080 访问指定ip
    • 可能遇到的问题:
      1. 暴力:找到占用的端口号,并且找到对应的进程,杀死该进程
        • cmd命令netstat -ano 获取占用端口进程进程PID 在任务管理器杀死占用进程
      2. 温柔:修改自身的端口号
        • 在tomcat安装目录conf/server.xml配置文件 修改相应的默认端口号
        • 一般会将tomcat的默认端口号修改为80。80端口号是http协议的默认端口号。
          • 好处:在访问时,就不用输入端口号
  5. 关闭:

    1. 正常关闭:
      • bin/shutdown.bat
      • Ctrl+C
    2. 强制关闭:
      • 点击启动窗口的x
  6. 配置:

    部署项目的方式:

    1. 直接将项目放到webapps目录下即可

      • /hello:项目的访问路径–>虚拟路径
      • 简化部署:将项目打成一个war包,再将war包放置在webapps目录下
        • war包会自动解压缩 war包可以通过压缩成zip后改后缀名 当然,推荐的是用专门的软件打包成war包
    2. 配置conf/server.xml文件

      • 在<Hose>标签体中配置
        <Context docBase=”D:\hello” path=”/hehe” />
        • docBase:项目存放的路径
        • path:虚拟目录
    3. 在conf/Catalina/locahost创建任意名称的xml文件。在文件中编写
      <Context docBase=”D:\hello” />

      • 访问时虚拟目录为:xml文件的名称
      • 好处还有可以热部署 更改server.xml文件需要重新启动tomcat,而且更改server.xml有可能导致全部项目打不开
    4. 静态项目和动态项目

      • 目录结构

        • Java动态项目的目录结构

          – 项目的根目录
          – WEB-INF目录:
          ​ – web.xml:web项目的核心配置i文件

          ​ – classes目录:放置字节码文件的目录

          ​ – lib目录:放置依赖的jar包

    5. 将Tomcat继承到IDEA中,并且创建JavaEE的项目,部署项目
      经过一系列的部署
      新版idea中,创建java模块然后右键添加支持框架
      配置tomcat在模块设置 添加tomcat配置
      最后配置下tomcat的热部署以及在服务启动时部署


Servlet

  • 概念server applet:运行在服务器端的小程序
    • servlet就是一个接口,定义了java类被浏览器访问到(Tomcat识别)的规则
    • 将来我们自定义要给类,实现Servlet接口,复写方法。
  • 快速入门
    1. 创建Java EE项目
    2. 定义一个类,实现Servlet接口
      • public class ServletDemo1 implements Servlet
    3. 实现接口中的抽象方法
    4. 配置Servlet
      image-20230803152656289
  • 执行原理:
    1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
    2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
    3. 如果有,则在找到对应的<servlet-class>全类名
    4. tomcat会将字节码文件加载进内存,并且创建其对象
    5. 调用其方法

Servlet中的方法

  1. 被创建:执行init方法,只执行一次
    Servlet什么时候被创建

    • 默认情况下,第一次被访问是,Servlet被创建
    • 可以配置执行Servlet的创建时机。
      • 在web.xml中的<servlet>标签下配置
        1. 第一次被访问时,创建
          • <load-on-startup>的值为负数
        2. 在服务器启动时,创建
          • <load-on-startup>的值为0或正整数

    Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的

    • 多个用户同时访问时,可能存在线程安全问题
    • 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值
  2. 提供服务:执行service方法,执行多次

    • 每次访问Servlet时,Service方法都会被调用一次。
  3. 被销毁:执行destroy方法,只执行一次

    • servlet被销毁时执行。服务器关闭时,Servlet被销毁
    • 只有服务器正常关闭时,才会执行destory方法、
    • destroy方法在Servlet被销毁之前执行,一般用于释放资源
  4. getServletConfig方法 获取ServletConfig 对象 Servlet的配置对象

  5. getServletInfo获取Servlet的一些信息,版本,作者等等。


Servlet3.0

  • 好处:
    • 支持注解配置。可以不需要web.xml了。
  • 步骤:
    1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
    2. 定义一个类,实现Servlet接口
    3. 复写方法
    4. 在类上使用@WebServlet注解,进行配置
      1. @WebServlet(“资源路径”) 注解中有一个value,value表示重要的属性,只有一个属性value可以省略
      2. @WebServlet(urlPatterns = “资源路径”) 与1一样,直接用1
  • IDEA与tomcat的相关配置
    1. IDEA会为每一个tomcat部署的项目单独建立一份配置文件
      • 查看控制台的log:Using CATALINA_BASE:”路径”
    2. 工作空间项目 和 tomcat部署的web项目
      • tomcat真正访问的是”tomcat部署的web项目”,”tomcat部署的web项目”对应着”工作空间项目”的web目录下的所有资源
      • WEB-INF目录下的资源不能被浏览器直接访问。
      • 断点调试:使用”小虫子”启动debug启动

Servlet的体系结构

Servlet – 接口

​ |

GenericServlet – 抽象类

​ |

HttpServlet – 抽象类


GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象

  • 将来定义Servlet类时,可以继承GennericServlet,实现Service()方法即可

HttpServlet

对http协议的一种封装,简化操作

  1. 定义类继承HttpServlet
  2. 复写doGet/doPost方法

Servlet相关配置

  1. urlpartten:Servlet访问路径
    1. 一个Servlet可以定义多个访问路径:@WebServlet({“/d4”,”/dd4”,”/ddd4”})
    2. 路径定义规则:
      1. /xxx:
      2. /xxx/xxx:多层路径,目录结构 /xxx/* *通配符写啥都可以
      3. /* 不管写什么路径都可以访问到 优先级比较低 找不到别的 用这个 不常用
      4. *.扩展名 *.do 别加/

HTTP

概念:Hyper Text Transfer Protocol 超文本传输协议

  • 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
  • 特点:
    1. 基于TCP/IP的高级协议
    2. 默认端口号:80
      http://www.baidu.com
    3. 基于请求响应/响应模型的,一次请求对应一次响应
    4. 无状态的:每次请求之间相互独立,不能交互数据
  • 历史版本:
    • 1.0:每一次请求响应都会建立新的连接
    • 1.1:复用连接

请求消息数据格式

  1. 请求行
    请求方式 请求url 请求协议/版本
    GET /login.html HTTP/1.1

    请求方式:

    • HTTP协议有7种请求方式,常用的有两种
      • GET:
        1. 请求参数在请求行中,在url后
        2. 请求的url长度有限制的
        3. 不太安全
      • POST:
        1. 请求参数在请求体中
        2. 请求的url长度没有限制的
        3. 相对安全
  2. 请求头:客户端浏览器告诉服务器一些信息
    请求头名称:请求头值

    • 常见的请求头
      1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
        • 可以在服务器端获取该头的信息,解决浏览器的兼容问题
      2. Refererhttp://localhost/login.html
        1. 告诉服务器,我(当前请求)从哪里来
          • 作用:
            1. 防盗链:
            2. 统计工作:
  3. 请求空行
    空行,就是用于分割POST请求的请求头,和请求体的。

  4. 请求体(正文)

    • 封装POST请求消息的请求参数的
  • 字符串格式:
    GET /login.html HTTP/1.1
    image-20230805095723092

Request

  1. request对象和response对象的原理

    image-20230805113202577

    1. request和response对象是由服务器创建的。我们来使用它们
    2. request对象是来获取请求消息,response对象是来设置响应消息

  2. request对象继承体系结构
    ServletRequest – 接口

    HttpServletRequest – 接口
    org.apache.catalina.connector.RequestFacade 类(tomcat)

  3. request

    1. 获取请求消息

      1. 获取请求行数据
        格式:GET /day14/demo1?name=zhangsan HTTP/1.1
        • 方法:
          1. 获取请求方式:GET
            • String getMethod()
          2. ***获取虚拟目录:/day14
            • String getContextPath()
          3. 获取Servlet路径
            • String getServletPath()
          4. 获取get方式的请求参数:name=zhangsan
            • String getQueryString()
          5. ***获取请求URI/URL:/day14/demo1
          6. 获取协议及版本:HTTP/1.1
            • String getProtocol()
          7. 获取客户机的IP地址
            • String getRemoteAddr()
      2. 获取请求头数据
        1. 方法:
          • (*) String **getHeader(String name)**:通过请求头的名称获取请求头的值
          • Enumeration<String> **getHeaderNames()**:获取所有的请求头名称
      3. 获取请求体数据
        • 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
        • 步骤:
          1. 获取流对象
            • BufferedReader **getReader()**:获取字符输入流,只能来操作字符数据
            • ServletInputStream **getInputStream()**:获取字节输入流,可以操作所有类型数据
              • 在文件上传知识点后讲解
          2. 再从流对象中拿数据
            image-20230806174514418
    2. 其他功能:

      1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

        1. String **getParameter(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集合
        • 中文乱码问题:

          • get方式:tomcat8 已经将get方式乱码问题解决了

          • post方式:会乱码

            解决:在获取参数前设置请求request的编码 req.setCharacterEncoding(“UTF-8”);

      2. 请求转发:一种在服务器内部的资源跳转方式

        1. 步骤:
          1. 通过request对象获取请求转发器对象:RequestDispatcher getRequstDispatcher(String path)
          2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest req, ServletReponse resp)
        2. 特点:
          1. 浏览器地址栏路径不发生变化
          2. 只能转发到当前服务器的内部资源中
          3. 转发是一次请求
      3. 共享数据:

        • 域对象:一个有作用范围的对象,可以在范围内共享数据
        • request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
        • 方法:
          1. void setAttribute(String name,Object obj) :存储数据
          2. Object **getAttribute(String name)**:通过名字获取值
          3. void **removeAttribute(String name)**:通过键一处键值对
      4. 获取ServletContext

        • ServletContext getServletContext()
  4. 案例:用户登陆

    • 用户登陆案例需求:

      1. 编写login.html登陆页面
        username & password 两个输入框

      2. 使用Druid数据库连接池技术,操作mysql,login数据库中user表

      3. 使用jdbcTemplate技术封装JDBC

      4. 登陆成功跳转到SuccessServlet展示:登陆成功!用户名,欢迎你

      5. 登陆失败跳转到FailServlet展示:登陆失败,用户名或密码错误

    • 分析

      image-20230808161609984

    • 开发步骤

      1. 创建项目,导入配置文件,jar包

      2. 创建数据库环境

      3. 创建包cn.itcast.domain,创建类User

      4. 创建包cn.itcast.dao,创建类UserDao,提供login的方法

      5. 编写cn.itcast.servlet,创建类LoginServle类

      6. login.html中form表单的action路径的写法

        • 虚拟目录+Servlet的资源路径
      7. 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集合的键值对信息,封装到对应的JavaBean对象中

响应消息数据格式

  1. 响应行
    1. 组成:协议/版本 响应状态码 状态码描述
    2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
      1. 状态码都是3位数字
      2. 分类:
        1. 1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx多状态码
        2. 2xx:成功。代表:200
        3. 3xx:重定向。代表:302(重定向),304(访问缓存)
        4. 4xx:客户端错误。
          • 代表:
            • 404(请求路径没有对应的资源)
            • 405(请求方式没有对应的doXxx方法)
        5. 5xx:服务器端错误。代表:500(服务器内部出现异常)
  2. 响应头
    1. 格式:头名称:值
    2. 常见的响应头:
      1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
      2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
        • 值:
          • in-line:默认值,在当前页面内打开
          • attachment;filename=xxx:以附件形式打开响应体。文件下载
  3. 响应空行
  4. 响应体:传输的数据
  • 响应字符串形式
    HTTP/1.1 200 OK
    Content-Type:text/html;charset=UTF - 8
    Content-Length:101
    Date:Wed,06 Jun 2018 07:08:42 GMT

    <html>
    <head>
    <title>$Title$<title>
    </head>
    <body>
    hello,response
    </body>
    </html>


Response

  • 功能:设置响应消息

    1. 设置相应行
      1. 格式:HTTP/1.1 200 ok
      2. 设置状态码:setStatus( int sc )
    2. 设置响应头:setHeader( String name, String value )
    3. 设置响应体:
      • 使用步骤:
        1. 获取输出流
          • 字符输出流:PrintWriter getWriter()
          • 字节输出流:ServletOutputStream getOutputStream()
        2. 使用输出流,将数据输出到客户端浏览器
  • 案例:

    1. 完成重定向

      • 重定向:资源跳转的方式
      • 代码实现
        1. 设置状态码为302,告诉浏览器重定向
        2. 设置响应头location,这就是B资源的路径
      • 简单的重定向方法
        sendRedirect(“路径”)
      • 重定向的特点:redirect
        1. 地址栏发生变化
        2. 重定向可以访问其他站点(服务器)的资源
        3. 重定向是两次请求,不能使用request对象来共享数据
      • 转发的特点:forward
        1. 转发地址栏路径不变
        2. 转发只能访问当前服务器下的资源
        3. 转发是一次请求,可以使用request对象来共享数据
      • 路径写法
        1. 路径分类
          1. 相对路径:通过相对路径不可以确定唯一资源
            • 如:./index.html
            • 不以/开头,以 . 开头路径
            • 规则:找到访问当前资源和目标资源之间的相对位置关系
              • ./ :当前目录
              • ..// :后退一级目录
          2. 绝对路径:通过绝对路径可以确定唯一资源
            • 如:http://localhost/day15/responseDemo2 /day15/responseDemo2
            • 以/开头的路径
            • 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
              • 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)|
                • 建议虚拟目录动态获取:request.getContextPath()
                • <a> , <form> 重定向…
              • 给服务器使用:不需要加虚拟路径
                • 转发路径
    2. 服务器输出字符数据到浏览器

      • 步骤:

        1. 获取字符输出流
        2. 输出数据
      • 注意:

        • 乱码问题:

          1. PrintWriter Pw = response.getWriter(); 获取的流的默认编码是ISO-8859-1

          2. 设置该流的默认编码

          3. 告诉浏览器响应体使用的编码

            简单的形式,设置编码,是在获取流之前设置
            response.setContentType(“text/html;chars et=utf-8”);

    3. 服务器输出字节数据到浏览器

      • 步骤:
        1. 获取字节输出流
        2. 输出数据
    4. 验证码

      1. 本质:图片
      2. 目的:放置恶意表单注册

ServletContext

  1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信

  2. 获取:

    1. 通过request对象获取
      request.getServletContext();
    2. 通过HttpServlet获取
      this.getServletContext();
  3. 功能:

    1. 获取MIME类型:

      • MIME类型:在互联网通信过程中定义的一种文件数据类型
        • 格式:大类型/小类型 text/html image/jpeg
      • 获取:String getMimeType(String file) 括号内参数一般为文件后缀
    2. 域对象:共享数据

      1. setAttribute(String name, Object value)
      2. getAttribute(String name)
      3. removeAttribute(String name)
      • ServletContext对象范围:所有用户所有请求的数据
    3. 获取文件的真实(服务器)路径

      1. 方法:String getRealPath(String path)

案例

  • 文件下载需求:
  1. 页面显示超链接
  2. 点击超链接后弹出下载提示框
  3. 完成图片文件下载
  • 分析:

    1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
    2. 任何资源都必须弹出下载提示框
    3. 使用响应头设置资源的打开方式:
      • content-desponsition:attachment;filename-xxx
  • 步骤:

    1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
    2. 定义Servlet
      1. 获取文件的名称
      2. 使用字节输入流加载文件进内存
      3. 指定response的响应头:content-desposition:attachment;filename=xxx
      4. 将数据写出到response输出流
  • 问题:

    • 中文文件名问题
      • 解决思路:
        1. 获取客户端使用的浏览器版本信息
        2. 根据不同的版本信息,设置filename的编码方式不同

会话技术

  1. 会话:一次会话中包含多次请求和响应。
    • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  2. 功能:再一次会话的范围内的多次请求间,共享数据
  3. 方式:
    1. 客户端会话技术:Cookie
    2. 服务器端绘画技术:Session

  1. 概念:客户端会话技术,将数据保存在客户端
  2. 快速入门:
    • 使用步骤
      1. 创建Cookie对象,绑定数据
        • new Cookie(String name, String value)
      2. 发送Cookie对象
        • response.addCookie(Cookie cookie)
      3. 获取Cookie,拿到数据
        • Cookie[] request.getCookies()
  3. 实现原理
    • 基于响应头set-cookie和请求头cookie实现

image-20231020171933594

  1. cookie的细节

    1. 一次可不可以发送多个cookie?

      • 可以
      • 可以创建多个cookie对象,使用response调用多次addCookie方法发送cookie即可。
    2. cookie在浏览器中保存多长时间?

      1. 默认情况中,当浏览器关闭后,Cookie数据被销毁
      2. 持久化存储:
        • setMaxAge(int seconds)
          1. 正数:将cookie数据写到硬盘的文件中。持久化存储。cookie存活事件
          2. 负数:默认值
          3. 零:删除cookie信息
    3. cookie能不能存中文?

      • 在tomcat 8 之前 cookie中不能直接存储中文数据。
        • 需要将中文数据转码—一般采用URL编码(%E3)
      • 在tomcat 8 之后, cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
    4. cookie共享问题?

      1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享

        • 默认情况下cookie不能共享

        • **setPath(String path)**:设置cookie的获取范围。默认情况下,设置当前的虚拟目录

          • 如果要共享,则可以将path设置为”/“
      2. 不同的tomcat服务器间cookie共享问题?

        • **setDomain(String path)**:如果设置一级域名相同,那么多个服务器之间cookie可以共享
          • setDomain(“.baidu.com”); 那么tieba.baidu.com和news.baidu.com中cookie可以共享
  2. Cookie(小饼干) 的特点和作用

    1. cookie存储数据在客户端浏览器
    2. 浏览器对于单个cookie的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20)
    • 作用:
      1. cookie一般用于存储少量的不太敏感的数据
      2. 在不登陆的情况下,完成服务器对客户端的身份识别
  3. 案例:记住上一次访问事件

    1. 案例需求:
      1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
      2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
    2. 分析:
      1. 可以采用Cookie来完成
      2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie
      3. 有:不是第一次访问
        1. 响应数据:欢迎回来,您上次访问时间为:2023年10月20日22:09:00
        2. 写回Cookie:lastTime=2023年10月20日22:09:00
      4. 没有:是第一次访问
        1. 响应数据:您好,欢迎您首次访问
        2. 写回Cookie:lastTime=2023年10月20日22:09:00

JSP:入门学习

  1. 概念:

    • Java Server Pages:java服务器端页面

      可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
      用于简化书写!!!

  2. 原理

    • JSP本质上就是一个Servlet
  3. JSP的脚本:JSP定义代码的方式

    1. **<% 代码 %>**:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本就可以定义什么。
    2. **<%! 代码 %>**:定义的Java代码,在jsp转换后的java类的成员位置。
    3. **<%= 代码 %>**:会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
  4. JSP的内置对象

    • 在jsp页面中不需要获取和创建,可以直接使用的对象
    • jsp一共有9个内置对象。
    • 先学习3个:
      • request
      • response
      • out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
        • response.getWriter()和out.writer()的区别:
          • 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
          • response.getWriter( )数据输出永远在out.write()之前
  5. 改造Cookie案例

    • JSP脚本可以截断 截断后中间用正常的html

Session

  1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession

  2. 快速入门:

    1. 获取Session对象
      HttpSession session = request.getSession();

    2. HttpSession对象:

      Object getAttribute(String name)

      void setAttribute(String name, Object value)

      void removeAttribute(String name)

  3. 原理

    • Session的实现是依赖于Cookie的。
  4. 细节:

    1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
      • 默认情况下,不是
      • 如果需要相同,则可以创建cookie,键位JSESSIONID,设置最大存活时间,让cookie持久化保存
        Cookie c = new Cookie(“JSESSIONID”,session.getID());
        c.setMaxAge(60 * 60);
        response.addcookie(c);
    2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
      • 不是同一个 ,但是要确保数据不丢失
        • session的钝化:
          • 在服务器正常关闭之前,将session对象序列化到硬盘上
        • session的活化:
          • 在服务器启动后,将session文件转化为内存中的session对象即可。
    3. session什么时候被销毁?
      1. 服务器关闭
      2. session对象调用 invalidate()
      3. session默认失效时间 30分钟
        选择性配置修改
        <session-config>
        <session=timeout>30<session-timeout>
        <session-config>
  5. session(主菜)的特点

    1. session用于存储一次会话的多次请求的数据,存在服务器端
    2. session可以存储任意类型,任意大小的数据
    • session与Cookie的区别:
      1. session存储数据在服务器端,Cookie在客户端
      2. session没有数据大小限制,Cookie有
      3. session数据安全,Cookie相对于不安全

案例:验证码

  1. 案例需求:

    1. 访问带有验证码的登陆页面login.jsp
    2. 用户输入用户名,密码以及验证码。
      • 如果用户名和密码输入有误,跳转登陆页面,提示:用户名和密码错误
      • 如果验证码输入有误,跳转登陆页面,提示:验证码错误
      • 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
  2. 分析

    image-20231024152137182


JSP

  1. 指令
    • 作用:用于配置JSP页面,导入资源我呢见
    • 格式:
      <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %>
    • 分类:
      1. page :配置JSP页面的
        • contentType:等同于response.setContentType()
          1. 设置响应体的mime类型以及字符集
          2. 设置当前jsp页面的编码(只能是高级的IDE,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
        • import:导包
        • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
        • isErrorPage:表示当前页面是否是错误页面。
          • true:是,可以使用内置对象exception
          • false:否。默认值。不可以使用内置对象exception
      2. include :页面包含的。导入页面的资源文件
        • <%@include file=”top.jsp”%>
      3. taglib :导入资源
  2. 注释:
    1. html注释:
      **<!– –>**:只能只是html片段
    2. jsp注释
      **<%– –%>**:可以注释所有
  3. 内置对象
    • 在jsp页面中不需要创建,直接使用的对象
    • 一共有9个:
      • ​ 变量名 真实类型 作用
      • pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象
      • request HttpServletRequest 一次请求访问的多个资源(转发)
      • session HttpSession 一次会话的多个请求间
      • application ServletContext 所有用户间共享数据
      • response HttpServletResponse 响应对象
      • page Object 当前页面(Servlet)的对象 this
      • out JspWriter 输出对象,数据输出到页面上
      • config ServletConfig Servlet的配置对象
      • exception Throwable 异常对象

MVC:开发模式

  1. jsp演变历史

    1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
    2. 后来有了jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难以维护,难以分工协作
    3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性
  2. MVC:

    1. M:Model,模型。JavaBean
      • 完成具体的业务操作,如:查询数据库,封装对象
    2. V:View,视图。JSP
      • 展示数据
    3. C:Controller,控制器。Servlet
      • 获取用户的输入
      • 调用模型
      • 将数据交给视图进行展示
    • 优缺点
      1. 优点:
        1. 耦合性低,方便维护,可以利于分工协作
        2. 重用性高
      2. 缺点:
        1. 使得项目架构变得复杂,对开发人员要求高

image-20231027172542079


EL表达式

  1. 概念:Expression Language 表达式语言
  2. 作用:替换和简化jsp页面中java代码的编写
  3. 语法:${ 表达式 }
  4. 注意:
    • jsp默认支持EL表达式。如果要忽略EL表达式
      1. 设置jsp中page指令中:isELIgnored=”true” 忽略当前页面中所有的EL表达式
      2. \${表达式}:忽略当前这个EL表达式
  5. 使用:
    1. 运算
      • 运算符:
        1. 算术运算符: + - * /(div) %(mod)
        2. 比较运算符: > < >= <= == !=
        3. 逻辑运算符: &&(and) ||(or) !(not)
        4. 空运算符:empty
          • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
          • ${empty list}:判断字符串、集合、数组对象是否为null
          • ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
    2. 获取值
      1. el表达式只能从域对象中获取值
      2. 语法:
        1. ${域名称.键名}:从指定域中获取指定键的值
          • 域名称:
            1. pageScope –> pagecontext
            2. requestScope –> request
            3. sessionScope –> session
            4. applicationScope –> application(ServletContext)
          • 举例:在request域中存储了name=张三
          • 获取:${requstScope.name}
        2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。//可以简化书写
      3. 获取对象、List集合、Map集合的值
        1. 对象:${域名称.键名.属性名}
          • 本质上会去调用对象的getter方法
        2. List集合:*${域名称.键名[索引]}*
        3. Map集合:
          • ${域名称.键名.key名称}
          • ${域名称.键名[“key名称”]}
    3. 隐式对象:
      • el表达式中有11个隐式对象
      • pageContext:
        • 获取jsp其他8个内置对象
          • ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

  1. 概念:JavaServer Pages Tag Library JSP标准标签库
    • 是由Apache组织提供的开源的免费的jsp标签 <标签>
  2. 作用:用于简化和替换jsp页面上的java代码
  3. 使用步骤:
    1. 导入jstl相关的jar包
    2. 引入标签库:taglib指令: <%@ taglib %>
    3. 使用标签
  4. 常用的 JSTL 标签
    1. if :相当于Java代码中的 if 语句
      image-20231030203627902
    2. choose :相当于Java代码中的 switch语句
      image-20231030210033654
    3. foreach :相当于Java代码中的 for 语句
      image-20231030214536832
  5. 练习:
    • 需求在request域中有一个 存有User对象的List集合。需要使用 jstl+el 将 list 集合数据展示到 jsp 页面的表格 table 中

三层架构:软件设计架构

  1. 界面层(表示层):用户看到的界面。用户可以通过界面上的组件和服务器进行交互
  2. 业务逻辑层:处理业务逻辑的。
  3. 数据访问层:操作数据存储文件。

image-20231031113516635


案例:用户信息列表展示

  1. 需求:用户信息的增删改查操作
  2. 设计:
    1. 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtils+tomcat
    2. 数据库设计:
      create database day17; –创建数据库
      user day17; – 使用数据库
      create table user( – 创建表
      id int primary key auto_increment,
      name varchar(20) not null,
      gender varchar(5),
      age int,
      address varchar(32),
      qq varchar(20),
      email varchar(50)
      );
  3. 开发:
    1. 环境搭建
      1. 创建数据库环境
      2. 创建项目,导入需要的 jar 包
    2. 编码
  4. 测试
  5. 部署运维

分析:
image-20231031174609328