Java Web
Java Web 学习笔记
介绍:
- javaWeb:使用Java语言完成服务器端程序开发
Junit单元测试
测试分类:
- 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
- 白盒测试:需要写代码的。关注程序具体的执行流程、
Junit使用:白盒测试
步骤
定义一个测试类(测试用例)
建议:
- 测试类名:被测试的类名Test CalculateTest
- 包名:xxx.xxx.xx.test cn.itcast.test
定义测试方法:可独立运行
建议:
- 方法名:test测试的方法名 testAdd( )
- 返回值:void
- 参数列表:空参
给方法加@Test注解
导入Junit依赖环境
判定结果:
红色:失败
绿色:成功
一般我们会使用断言操作来处理结果
Assert.assertEquals(期望的结果,运算的结果)
示例:
@Before&@After
方法名前加@Before注解 相当于所有测试类开始前都要先执行这个方法
初始化方法:用于资源申请,所有测试方法在执行之前都会先执行该方法
注解@After 释放资源方法:在所有测试方法执行完成后,都会自动执行该方法
总结:
@Before:
修饰的方法会在测试方法之前被执行
@After:
修饰的方法会在测试方法执行之后自动被执行
反射:框架设计的灵魂
框架:半成品软件。 可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处:
1. 可以在程序运行过程中,操作这些对象
1. 可以解耦,提高程序的可扩展性
获取Class对象的方式
Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
类名.class:通过类名的属性class获取
多用于参数的传递
对象.getClass():getClass( )方法在object类中定义着。
多用于对象的获取字节码的方式
结论:
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class对象功能
此章节JavaSE最后章节反射有讲解
获取功能:
获取成员变量们
Field[ ] getFields( )
Field getFields(String name )
Field[ ] getDeclaredFields( )
Field getDeclaredFields(String name )
获取构造方法们
获取成员方法们
获取类名
String getName( )
Field:成员变量
操作:
设置值
void set(Object obj,object value)
获取值
get(Object obj)
忽略访问权限修饰符的安全检查
setAccessible(true):暴力反射
Constructor:构造方法
创建对象:
T newInstance(Object … initargs)
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
Method:方法对象
执行方法:
Object invoke(Object obj,Object… args)
获取方法名称:
String getName:获取方法名
类也可以获取名称
反射案例
没听太懂 回头反复观看
注解
概念:说明程序的。给计算机看的
注释:用文字描述程序的。给程序员看的
概述:
- JDK1.5之后的新特性
- 说明程序的
- 使用注解:@注解名称
作用分类:
- 编写文档:通过代码里标识的注解生成文档[生成文档doc文档]
- 代码分析:通过代码里标识的注解对代码进行分析[使用反射]
- 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查[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 { }
属性:接口中的抽象方法
要求:
属性的返回值类型:基本数据类型,String,枚举,注解,以上类型的数组
定义了属性,在使用时需要给属性赋值
如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值
如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
数组负值时,值使用{ }包裹。如果数组中只有一个值,则{ }省略
赋值示例:
元注解:用于描述注解的注解
@Target:描述注解能够作用的位置
ElementType取值:
TYPE:可以作用于类上
METHOD:可以作用于方法上
FIELD:可以作用于成员变量上
@Retention:描述注解被保留的阶段
- Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中并被JVM读取到 三个值 CLASS SOURCE
@Documented:描述注解是否被抽取到API文档中
@Inherited:描述注解是否被子类继承
在程序中使用(解析)注解
获取注解中定义的属性值
获取注解定义的位置的对象(Class,Method,Field)
获取指定的注解
getAnnotation(Class)
//其实就是在内存中生成了一个该注解接口的一个子类实现对象
调用注解对象中的抽象方法获取配置的属性值
value
使用示例:菜鸟教程
案例:
小结:
- 以后大多数时候,我们会使用注解,而不是自定义注解
- 注解给谁用?
- 编译器
- 解析程序用
- 注解不是程序的一部分,可以理解为注解就是一个标签
JavaWeb
什么是JavaWeb?
- 使用Java语言开发互联网项目。简单理解:使用Java语言开发网站
课程介绍:30天
- 数据库:5天 重要
- 网页前端:5天
- web核心技术:15天
- 旅游管理系统:5天
数据库内容介绍
- 数据库的基本概念
- MySQL的数据库软件
- 安装
- 卸载
- 配置
- SQL语言
数据库的基本概念
- 数据库的英文单词:DataBase 简称:DB
- 什么是数据库?
- 用于存储和管理数据的仓库。
- 数据库的特点:
- 持久化存储数据的。其实数据库就是一个文件系统
- 方便存储和管理数据
- 使用了统一的方式操作数据库–SQL
- 常见的数据库软件
- Oracle
- MySQL
- SQL Server
- …DB2
MySQL数据库软件
MySQL默认端口号 3306 MySQL服务名:MySQL80
安装
参考网上文章
卸载MySQL
利用geek卸载连带注册表 删除文件夹里面的各个MySql文件夹 删除服务 删除注册表 删除programData隐藏目录下的mysql文件 环境变量也记得修改
配置
MySQL服务:
不想自动启动的话 服务中找到MySQL80 改成手动 自动为开机自启
命令行:services.msc 打开服务窗口
使用管理员权限打开cmd:否则会发生权限不够问题
net stop MySQL80 关闭服务
net start MySQL80 开启服务
MySQL登陆
mysql -uroot -proot //-u用户名 -p密码
mysql -uroot -p //密码密文
mysql -hip -uroot -p连接目标的密码 //连接目的ip的MySQL
mysql –host=127.0.0.1 –user=root –password=连接目标的密码
退出
- quit
- exit
MySQL目录结构
因教学视频版本号为5.x 本机版本号为8.x 存在差异 不作唯一参考
MySQL安装目录
bin 二进制文件
data 日志数据文件
include c语言头信息
lib jar包
share MySQL错误信息
my.ini 配置文件
MySQL数据目录
隐藏的C盘ProgramData中MySQL文件夹中
Data文件夹中存取数据
数据库:文件夹
表:文件
数据:文件中存储的数据
SQL
什么是SQL?
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样地方,称为”方言”
SQL通用语法
- SQL 语句可以单行或多行书写,以分号结尾。
- 可使用空格和缩进来增强语句的可读性。
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
- 三种注释
- 单行注释: – 注释内容 或 # 注释内容(MySQL特有)
- 多行注释:/* 注释 */
SQL分类
DDL数据定义语言 (操作数据库、表)
DML数据操作语言 (增删改表中的数据)
DQL数据查询语言 (查询表中的数据)
DCL数据控制语言(了解//授权)
DDL:操作数据库、表
操作数据库:CRUD
C(Create):创建
创建数据库:
- create database 数据库名称;
创建数据库,判断不存在,再创建:
- create database if not exists 数据名称
创建数据库,并指定字符集
- create database 数据库名称 character set 字符集名;
练习:创建db4数据库,判断是否存在,并指定字符集为GBK
create database if not exists dbt character set gbk;
R(Retrieve):查询
查询所有数据库的名称:
show databases;
查询某个数据库的字符集:查询某个数据库的创建语句
show create database 数据库名称;
U(Update):修改
- 修改数据库的字符集
- alter database 数据库名称 charaacter set 字符集名称;
- 修改数据库的字符集
D(Delete):删除
- 删除数据库
- drop database 数据库名称;
- 判断数据库存在,存在再删除
- drop database if exists 数据库名称;
- 删除数据库
使用数据库
- 查询当前正在使用的数据库名称
- select database();
- 使用数据库
- use 数据库名称;
- 查询当前正在使用的数据库名称
操作表
C(Create):创建
语法
create table 表名(列名1 数据类型1,列名2 数据类型2,列名n 数据类型n);
注意:最后一列,不需要加逗号(,);
数据库类型:
- int:整数类型
- age int
- double:小数类型
- score double(5,2)
- date:日期类型,只包含年月日,yyyy-MM-dd
- datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
- timestamp:世界戳类型 yyyy-MM-dd HH:mm:ss
- 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
- varchar:字符串
- name varchar(20) 指定最大字符长度
- int:整数类型
创建表
- create table student(id int,name varchar(32),age int,score double(4,1),birthday date,insert_time timestamp);
复制表:
create table 表名 like 被复制的表名;
R(Retrieve):查询
- 查询某个数据库中所有的表名称
- show tables;
- 查询表结构
- desc 表名;
- 查询某个数据库中所有的表名称
U(Update):修改
修改表名
alter table 表名 rename to 新表名 ;
修改 表字符集
alter table 表名 character set 字符集;
添加一列
alter table 表名 add 列名 数据类型;
修改列名称 类型
alter table 表名 change 列名 修改后的列名 新数据类型;
alter table 表名 modify 列名 新数据类型;
删除列
alter table 表名 drop 列名;
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) * 每页显示的条数
分页操作是一个”方言”
约束
概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性。
分类:
主键约束
主键约束:primary key
注意:
- 含义:非空且唯一
- 一张表只能有一个字段为主键
- 主键就是表中记录的唯一标识
在创建表时,添加主键约束
删除主键
创建表后,添加主键
自动增长:
- 概念:如果某一列是数值类型的,使用 auto_increment 可以完成值得自动增长
- 创建表时,添加主键约束,并且完成主键自增长
- 一般和主键一起使用
- 递增上一个id
- 删除与添加自动增长使用alter table 表名 modify 命令
非空约束
非空约束:not null 某一列的值不能为null
创建表时添加约束
创建表后,添加非空约束
删除非空约束
唯一约束
唯一约束:unique 某一列的值不能重复
注意:
唯一约束可以有NULL值,但是只能由一条记录为NULL
创建表时,添加条件唯一约束
表创建后,添加唯一约束
删除唯一约束
外键约束
外键约束:foreign key 让表与表产生关系,从而保证数据的正确性。
在创建表时,可以添加外键
删除外键
alter table 表名 modify drop foreign key 外键名称
创建表之后,添加外键
alter tbale 表名 modify add constraint 外键名称 foreign key (外键字段名称) references 主表名称(主表列名称)
级联操作
添加级联
语法:
分类:谨慎操作
- 级联更新:ON UPDATE CASCADE
- 级联删除:ON DELETE CASCADE
数据库的设计
多表之间的关系
一对一关系:
如:人和身份证
一对多(多对一)关系:
如:部门和员工
多对多关系:
如:学生和课程
实现关系:
一对多(多对一)关系
- 如部门和员工
- 实现方式:在多的一方建立外键,指向一的一方的主键
多对多关系
- 多对多关系实现需要借助中间表
- 实现方式:中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
- 联合主键
一对一关系
- 任意一方添加唯一外键指向另一方的主键。
数据库设计的范式
概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求
分类:
- 第一范式(1NF):每一列都是不可分割的原子数据项
- 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖
- 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)
数据库的备份和还原
命令行方式:
语法:mysqldump -u用户名 -p密码 库名 > 保存的路径
还原:
- 登录数据库
- 创建数据库
- 使用数据库
- 执行文件。source文件 文件路径 目的路径是.sql文件
图形化工具方式:
点击数据库右键 转存sql文件 即可备份
右键 执行sql文件 即可导入
图像化工具不同可能叫法不同
多表查询
查询语法:select 列名列表 from 表名列表 where…
笛卡尔积:
- 有两个集合A,B 取这两个集合的所有组成情况。
- 要完成多表查询,需要消除无用的数据
多表查询的分类:
内连接查询
- 隐式内连接:使用where条件消除无用数据
- 显式内连接:[inner] join … on
- 注意
- 从哪里查数据
- 条件是什么
- 查询哪些字段
外连接查询
- 左外连接:lift [outer] join … on 查询的是左表所有数据以及其父表部分
- 右外连接:right [outer] join … on 查询的是右 表所有数据以及其父表部分
子查询
概念:查询中嵌套查询,称嵌套查询为子查询
子查询不同情况:
- 子查询的结果是单行单列的:
子查询可以作为条件,使用运算符去判断。运算符:> >= < <= = - 子查询的结果是多行单列的:
子查询可以作为条件,使用运算符in来判断 - 子查询的结果是多行多列的:
子查询可以作为一张虚拟表参与查询。
事务
事务的基本介绍
概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
操作:
- 开启事物:start transaction;
- 回滚:rollback;
- 提交:commit;
例子:
MySQL数据库中事务默认自动提交
一条DML(增删改)语句会自动提交一次事务。
事务提交的两种方式:
- 自动提交:
mysql默认自动提交 - 手动提交:
首先开启事务,再提交
- 自动提交:
修改事务的默认提交方式:
查看事务的默认提交方式:SELECT @@autocommit’ – 1 代表自动提交 0手动提交
修改默认的提交方式:set @@autocommit;
事务的四大特征
- 原子性:是不可分割的最小操作,要么同时成功,要么同时失败。
- 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
- 隔离性:多个事务之间。相互独立。
- 一致性:事务操作前后,数据总量不变
事务的隔离级别(了解)
概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在的问题:
- 脏读:读取到另一个事务中没有提交的数据
- 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
- 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
隔离级别:
- read uncommitted:读未提交
产生的问题:脏读、不可重复读、幻读 - read committed:读已提交 (Oracle默认)
产生的问题:不可重复读、幻读 - repeatable read:可重复读 (MySQL默认)
产生的问题:幻读 - serializable:串行化
可以解决所有的问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低
数据库查询隔离级别:
select @@tx_isolation;
数据库设置隔离级别:
set global transaction isolation level 级别字符串;
DCL
SQL分类:
- DDL:操作数据库和表
- DML:增删改表中数据
- DQL:查询表中数据
- DCL:管理用户,授权
DBA:数据库管理员
用户管理
DCL:管理用户,授权
- 添加用户
语法:create user ‘用户名‘@’主机名’ identified by ‘密码’; - 删除用户
语法:drop user ‘用户名‘@’主机名’; - 修改用户
语法:update user set password = password(‘新密码’) where user = ‘用户名’;
DCL提供:set password for ‘用户名‘@’主机名’ = password(‘新密码’);- mysql中忘记了root用户密码?
- cmd – > net stop mysql 停止mysql服务 需要管理员权限
- 使用无验证方式启动mysql服务: mysqld –skip-grant-tables
- 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登陆成功
- use mysql;
- update user set password = password(‘新密码’) where user = ‘root’;
- 关闭两个窗口
- 打开任务管理器
- 手动结束mysqld.exe的进程
- 启动MySQL服务
- 使用新密码登陆
- mysql中忘记了root用户密码?
- 查询用户
- 切换到mysql数据库
- 查询user表
- 通配符:%表示可以在任意注意使用用户登陆数据库
权限管理
查询权限
授予权限
grant 权限列表 on 数据库名.表名 to ‘用户名‘@’主机名’;
权限通配符 all 数据库 和 表名 可以用*
撤销权限
语法:revoke 权限列表 on 数据库名.表名 from ‘用户名’ @ ‘主机名’;
JDBC
概念:Java DataBase Connectivity Java数据库连接,Java语言操作数据库
JDBC本质:
快速入门
步骤
- 导入驱动jar包
复制jar包到libs目录下
右键 add as library 导入 - 注册驱动
Class.forName(“com.mysql.jdbc.Driver”); - 获取数据库连接对象 Connection
DriverManager.getConnection(“jdbc:mysql://localhost:3306/lijiaxu”,root,root); - 定义sql
String sql = “sql语句”; - 获取执行sql语句的对象 Statement
Statement stmt = conn.createStatement(); - 执行sql,接收返回结果
int count = stmt.executeUpdate(sql); - 处理结果
System.out.println(count); - 释放资源
stmt.close();
conn.close();
详解各个对象
DriverManager:驱动管理对象
告诉驱动需要用哪个jar包注册驱动: mysql5之后的驱动jar包可以省略注册驱动的步骤。
获取数据库连接
方法: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:密码
- url:指定连接的路径
Connection:数据库连接对象
- 功能
- 获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql) - 管理事务
- 开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
- 提交事务:commit()
- 回滚事务:rollback()
- 获取执行sql的对象
- 功能
Statement:执行sql的对象
- 执行sql
- boolean execute(String sql):可以执行任意的sql 了解
- int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值大于0的则执行成功,反之,则失败。 - ResultSet executeQuery(String sql):执行DQL(select)语句
- 练习:
- student表 添加一条记录
- student表 修改记录
- student表 删除记录
- 执行sql
ResultSet:结果集对象,封装查询对象结果
- boolean next():游标向下移动一行, 判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是,则返回true
- getXXX (参数):获取数据
- XXX:代表数据类型 如:int getInt()
- 参数:
- int:代表列的编号,从1开始。 如:getString(1) 取第一列的值
- String:代表列的名称。 如:getInt(“id”)
- 使用步骤:
- 游标向下移动一行
- 判断是否有数据
- 获取数据
练习:
查询stu表的数据将其封装为对象,然后装载集合 。然后返回.1. 定义Emp类 1. 定义方法public List\<Emp> findAll() { } 1. 实现方法 select * from emp;
PreparedStatement:执行sql的对象 (重要)
JDBC工具类
目的:简化书写
分析:
抽取注册驱动
抽取一个方法获取连接对象
需求:不想传递参数(麻烦),还得保证工具类的通用性。
解决:配置文件抽取一个方法释放资源
需求:
- 通过键盘录入用户名和密码
- 判断用户是否登陆成功
JDBC控制事务
事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败
操作:
- 开启事务
- 提交事务
- 回滚事务
使用 Connection对象来管理事务
- 开启事务:setAutoCommit(boolean autoCommit) false开启事务
在执行sql之前开启事务 - 提交事务:commit()
当所有sql都执行完提交事务 - 回滚事务:rollback()
在catch中回滚事务
数据库连接池
概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数 据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
好处:
1. 用户访问高效
1. 节省资源
实现:
标准接口:DataSource javax.sql包下的
方法:
获取连接:getConnection( )归还连接:close() 如果连接对象Connection是从连接池中获取的,那么调用Connection.close( )方法,咋不会关闭连接,而是归还连接
一般我们不去实现它,有数据库厂商来实现
1. C3P0:数据库连接池技术 2. Druid:德鲁伊 数据库连接池实现技术,由阿里巴巴提供的
C3P0:数据库连接池
步骤:
- 导入jar包
不要忘记导入驱动jar包 - 定义配置文件:
路径:直接将文件放在sec目录下即可 - 创建核心对象 数据库连接池对象 ComboPooledDataSource
- 获取连接:getConnection()
Druid:数据库连接池
由阿里巴巴提供
步骤:
- 导入jar包 druid-1.0.9.jar
- 定义配置文件:
是properties形式的
可以叫任意名称,可以放在任意目录下 - 加载配置文件 Properties
- 获取数据库连接池对象:
通过工厂类来获取 DruidDataSourceFactory - 获取连接:getConnection
定义工具类
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
Sprint JDBC
Spring框架对JDBC的简单封装 。
提供了JDBCTemplate对象简化JDBC的开发
步骤:
导入jar包
创建JbdcTemplate对象。依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);调用JdbcTemplate的方法来完成CRUD的操作
update():执行DML语句。增删改语句
queryForMap():查询结果将结果集封装为Map集合 注意:这个方法查询的结果集长度只能是1
queryForList():查询结果将结果集封装为list集合
注意:将每一条记录封装为一个Map集合,再将Map集合装在到List集合中
query():查询结果,将结果封装为javaBean对象
query的参数:RowMapper
一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的 自动封装
new BeanPropertyRowMapper<类型>(Emp.class)queryForObject:查询结果,将 结果封装为对象
练习:
需求:- 修改1号数据的salary为10000
- 添加一条记录
- 删除刚才添加的记录
- 查询id为1的记录,将其封装为map
- 查询所有记录 封装为list
- 查询所有记录,将其封装为emp对象的list集合
- 查询总记录数
Web
概述:
JavaWeb:使用Java语言开发基于互联网的项目
软件架构:
C/S:Client/Server 客户端/服务器端
再用户本地有一个客户端程序,再远程有一个服务器端程序
如:QQ,迅雷..
优点:
1. 用户体验好
缺点:
1. 安装,部署,开发,维护 麻烦B/S:Browers/Server浏览器/服务器端
只需要一个浏览器,用户通过不同的网址(URL),客户访问不同的服务器端程序优点:
1. 开发、安装、部署、维护简单
缺点:- 如果应用过大,用户的体验可能会受到影响
- 对硬件要求过高
B/S架构详解
客户端浏览器请求服务器
资源分类:
- 静态资源:
使用静态网页开发技术发布的资源
特点:
所有用户访问,得到的结果是一样的
如:文本,图片,音频,视频,
HTML,CSS,JavaScript 静态网页开发
如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器。浏览器中内置了静态资源的解析引擎,可以展示静态资源 - 动态资源:
使用动态网页及时发布的资源。
特点:- 所有用户访问,得到的结果可能不一样。
- 如:jsp/servlet,php,asp…
- 如果用户请求的是动态资源,那么服务器会执行动态资源,转换为静态资源,再发送给浏览器
要学习动态资源,必须先学习静态资源!
静态资源:静态网页技术三剑客
- HTML:用于搭建基础网页,展示页面的内容
- CSS:用于美化页面,布局页面
- JavaScript:控制页面的元素,让页面有一些动态的效果
HTML
概念:Hyper Text Markup Language 超文本标记语言 最基础的网页开发语言
- 超文本:超文本是用超链接的方法,将各种不同空间的文件信息组织在一起的网状文本。
- 标记语言:由标签构成得语言。<标签名称> 如HTML,XML
标记语言不是编程语言
HTML快速入门
语法:
- HTML文档后缀名 .html 或 .htm
- 标签分为
- 围堵标签:有开始标签和结束标签。如<html></html>
- 自闭和标签:开始标签和结束标签在一起。如<br/>
- 标签可以嵌套:
需要正确嵌套,不饿能你中有我,我中有你 - 在开始标签中可以定义属性。属性是由键值对构成,值需要用引号(单双均可)引起来
- 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:- 英文单词:red,green,blue
- rgb(值1,值2,值3):值得范围:0~255
- #值1值2值3:值得范围:00~FF之间。十六进制
width:
- 数值:width=’20’,数值的单位,默认是px(像素)
- 数值%:占比相对于父元素的比例
图片标签
img:展示图片
src:指定图片的路径
相对路径:以 . 开头的路径
. /:代表当前目录 . /image/1.jpg
.. / :代表上一级目录
如:<img src=”./image/jiangwai_1.jpg”>
<img src=”../image/jiangwai_1.jpg”>
列表标签
- 有序列表:
- ol 创建一个有序列表
- li 包裹变为项
- type属性可以指定样式 1 A a I i
- start 可以指定开始的项
- 无序列表
- ul
- li
- type属性可以改变类型 disc square circle
超链接标签
- <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>:表示表格的脚部分
特殊字符表
案例:
- 确定使用table来完成布局
- 如果某一行只有一个单元格,则使用<tr><td></td></tr>
- 如果某一行由多个单元格,则使用嵌套形式
表单标签*
概念:用于采集用户输入的数据的。用于和服务器进行交互。
使用的标签:form:用于定义表单的。可以定义一个范围,范围代表采集用户数据的范围
form的属性:
action:指定提交数据的URL 输入的数据提交的此地址
method:指定提交方法
分类:一共有7种,2种比较常见
get:- 请求参数会在地址栏中显示,会封装在请求行中
- 请求参数的长度是由限制的
- 不太安全
post:
- 请求参数不会在地址栏中显示,会封装在请求体中(HTTP协议后讲解)
- 请求参数的大小没有限制
- 较为安全
表单项种的数据要想被提交,必须指定name属性
表单项标签*
- input:可以通过type属性值,改变元素展示的样式
- type属性:
- text:文本输入框,input的默认类型
- value :指定默认值
- placeholder :指定输入框的提示信息,当输入框的内容发生变化,会自动清空提示信息
- password:密码输入框,自动密文显示
- radio:单选框
- 要想让多个单选框实现单选的效果,则多个单选框的的name属性值必须一样。name相同为一组单选框
- 一般会给每一个单选框提供value属性,指定其被选中后提交的值
- checkbox:复选框
- 无法区分提交值,应该给定value值,来确定提交的值
- radio和checkbox共同属性:checked=”checked” 或者checked 指定默认值 启动默认选择
- file:文件选择框
- hidden:隐藏域,用于提交一些信息的
- 按钮:
- submit:提交按钮,可以提交表单
- button:一个按钮
- <input type=”image” src = “路径”>:将按钮背景改为图片,也可以提交表单
- text:文本输入框,input的默认类型
- label:指定输入项的文字描述信息
- 注意:
- label的for属性一般会和 input 的 id 属性值 对应,如果对应,则点击label区域,会让input输入框获得焦点。
- 注意:
- HTML5新type类型
- type属性:
- select:下拉列表
- 子元素 :<option> 内容选项,指定列表项
- selected
- textarea:文本域
属性:- cols:指定列数,每一行有多少个字符
- rows:默认多少行。
CSS
页面美化和布局控制
概念:Cascading Style Sheets 层叠样式表
- 层叠:多个样式可以作用在同一个html的元素上,同时生效
好处:
- 功能强大
- 将内容展示和样式控制分离
- 降低耦合度。解耦
- 让分工协作更容易
- 提高开发效率
css页面美化和布局
CSS的使用
CSS与HTML结合方式
内联样式:由于没有降低耦合,不推荐
- 标签内使用style属性指定css代码
内部样式
- 在head标签内,定义style标签,style标签的标签体内容就是css代码
外部样式
定义css资源文件。
在head标签内,定义link标签,引入外部的资源文件
注意:1,2,3 ,作用范围越来越大——
1方式不常用,后期常用2,3
第三种格式导入css资源文件 可以在head标签中导入文件
CSS语法
格式:
选择器 {
属性名1:属性值1;
属性名2:属性值2;
…
}
选择器:筛选具有相似特征的元素
注意:
- 每一对属性需要使用;隔开,最后一对属性可以不加分号
选择器
分类:
基础选择器
- id选择器:选择器具体的id属性值的元素,建议在一个html中 id中唯一
语法:#id属性值{} - 元素选择器:选择具有相同标签名称的元素
语法:标签名称{}
注意:id选择器优先级要高于元素选择器 - 类选择器:选择具有相同的class属性值的元素
语法:.class属性值{}
注意:类选择器优先级高于元素选择器
- id选择器:选择器具体的id属性值的元素,建议在一个html中 id中唯一
扩展选择器
选择所有元素:
语法:* { }
并集选择器:
语法:选择器1,选择器2{ }子选择器:筛选选择器1元素下的选择器2元素
语法:选择器1 选择器2 { }父选择器:筛选选择器2的父元素选择器1
语法:选择器1 > 选择器2 { }属性选择器:选择元素名称,属性名=属性值的元素
- 1语法:元素名称[属性名 = “属性值”] { }
伪类选择器:选择一些元素具有的状态
语法:元素:状态{ } 如: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
基本语法
与html结合方式
- 内部JS
- 定义<script>,标签体内容就是js代码
- 外部JS
- 定义<script>,通过src属性引入外部的js文件
- 注意:
- <script>可以定义在html页面的任何地方,但是定义的位置会影响执行的顺序
- <script>可以定义多个
- 内部JS
注释
- 单行注释://注释内容
- 多行注释:/*注释内容*/
数据类型 typeof可以检测数据类型 document.writer可以把内容输出来body
- 原始数据类型(基本数据类型):
- number:数字。整数/小数/NaN(not a number 一个不是数字的数字类型)
- string:字符串。字符串 “abc” “a” ‘abc’
- boolean:true和false
- null:一个对象为空的占位符
- undefined:未定义。如果一个变量没有被初始化值,则会被默认赋值为undefined
- 引用数据类型(对象):
- 原始数据类型(基本数据类型):
变量:
- 变量:一小块存储数据的内存空间
- Java语言是强类型语言,而JavaScript是弱类型语言。
- 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
- 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
- 语法:
- var 变量名 = 初始化值;
运算符
一元运算符:只有一个运算数的运算符
++ – , +(正号) -(负号)
注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算符进行类型转换
其他类型转number:- string转number:按照字面值转换,如果字面值不是数字,则转为NaN(不是数字的数字)
- boolean转number:true转为1,false转为0
算术运算符:
+ - * / % …赋值运算符
= += -= ….比较运算符
> < >= <= == ===(全等于)
比较方式- 类型相同,直接比较
- 字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。
- 类型不同,先进行类型转换,再比较
- === 全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
- 类型相同,直接比较
逻辑运算符
&& 短路与 || 短路或 ! 非
其他类型转boolean- number:0或NaN为假,非0为true
- string:除了” “ 字符串,其他都是true
- null&undefined:都是false
- 对象:都是true
三元运算符
? :表达式
流程控制语句
- if … else. ..
- switch
- 在Java中,swithc语句可以接受的数据类型:byte int short char 枚举(1.5) string(1.7)
- switch(变量):
case 值 :
- switch(变量):
- 在JS中,switch语句可以接受任意的原始数据类型
- 在Java中,swithc语句可以接受的数据类型:byte int short char 枚举(1.5) string(1.7)
- while
- do … while
- for
JS特殊语法:
- 特殊语法
- 语句以;结尾,如果一行只有一条语句则;可以省略,**(不建议)**
- 变量的定义使用var关键字,也可以不使用
用:定义的变量为局部变量
不用:定义的变量为全局变量**(不建议)**
- 特殊语法
练习:带边框得99乘法表
基本对象
Function:函数对象
创建:
var fun = new Function(形式参数列表,方法体): //忘掉
function 方法名称(形式参数列表){
方法体
}
var 方法名 = function (形式参数列表) {
方法体
}
方法:
属性:
length:代表形参的个数特点:
- 方法定义是,形参的类型不用写,返回值类型也不写
- 方法是一个对象,如果定义名称相同的方法,会覆盖
- 在JS中,方法的调用只与方法的名称有关,和方法的参数列表无关
- 在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
调用:
方法名称(实际参数列表);
Array:数组对象
创建
- var arr = new Array(元素列表);
- var arr = new Array(默认长度);
- var arr = [元素列表];
- var arr = new Array
方法
join(参数):将数组中的元素按照指定的分隔符拼接为字符串push( ):向数组的末尾添加一个或更多元素,并返回新的长度
属性
length:数组的长度
特点
- JS中,数组元素的类型可变的。
- JS中,数组长度可变的
Date:日期对象
创建:
- var date = new Date( );
方法:
- tolocalString( ):返回当前date对象对应的时间本地字符串格式
- getTime( ):获取毫秒值。返回当前日期时间对象描述的时间到1970年1月1日零点的毫秒值差
Math:数学对象
创建:
- 特点:Math对象不用创建,直接使用。Math.方法名( );
方法:
- random( ):返回0-1之间的随机数。含0不含1
- ceil(x):对数进行上舍入。
- floor(x):对数进行下舍入。
- round(x):把数四舍五入为最接近的整数。
属性:
- PI
RegExp:正则表达式对象
正则表达式:定义字符串的组成规则
单个字符:[ ]
如:[ a ] [ ab ] [ a-zA-Z0-9_ ]
特殊符号代表特殊含义的单个字符
\d:单个数字字符[0-9]
\w:单个单词字符[ a-zA-Z0-9_ ]量词符号:
?:表示出现0次或1次
*:表示出现0次或多次
+:表示出现1次或多次
{m,n}:表示 m <= 数量 <=n- m如果缺省:{ ,n}:最多n次
- n如果缺省:{m, }:最少m次
\w* 表示字符串组成规则为单词字符构成单词字符出现0次或多次
开始结束符号
^:开始
$:结束
/^ab$/ 表示只会匹配到 以a打头 b结束的字符串
正则对象:
- 创建
- var reg = new RegExp(“正则表达式”);
- var reg = /正则表达式/;
- 方法
- **test(参数)**:验证指定的字符串是否符合正则定义的规范
Global:全局对象
特点:全局对象,这个Global封装的方法不需要对象就可以直接调用。方法名( );
全局属性和函数可用于所有内建的JavaScript对象。
方法:
- encodeURI( ):url编码
decodeURI( ):url解码 - encodeURIComponent( ):url编码
decodeURIComponent( ):url解码 - parseInt( ):将字符串转为数字
逐一判断每一个字符是否是数字,直到不是数字为止,将前边部分数字部分转为number - isNaN:判断一个值是否是NaN
NaN六亲不认,连自己都不认。NaN参与的==比较全部为false - **eval( )**:计算JavaScript字符串,并把它作为脚本代码来执行
URL编码
DOM简单学习
为了满足案例要求
功能:控制html文档的内容
代码:获取页面标签(元素)对象Element
- document.getElementByID(“id值”):通过元素的id获取元素对象
操作对象Element对象:
- 修改属性值:
- 明确获取的对象是哪一个?
- 查看API文档,找其中有哪些属性可以设置
- 修改标签体内容:
- 属性:innerHTML
举例:
事件简单学习
功能:某些组件被执行了某些操作后,触发某些代码的执行
如何绑定事件
- 直接在html标签上,指定事件的属性(操作),属性值就是js代码
- 事件:onclick — 单击事件
- 通过js获取元素对象,指定事件属性,设置一个函数
案例:电灯开关
BOM
概念:Browser Object Model 浏览器对象模型
将浏览器的各个组成部分封装成对象
组成:
- Window:窗口对象
- Navigator:浏览器对象
- Screen:显示器屏幕对象
- History:历史记录对象
- Location:地址栏对象
Window:窗口对象
创建
方法
与弹出框有关的方法:
**alert()**:显示带有一段消息和一个确认按钮的警告框。
**confirm()**:显示带有一段消息以及确认按钮和取消按钮的对话框
- 如果用户点击确定按钮,则方法返回true
- 如果用户点击取消按钮,则方法返回false
**prompt()**:显示可提示用户输入的对话框
- 返回值:获取用户输入的值 , 参数里面可以指定提示内容
与打开关闭有关的方法:
- **close()**:关闭浏览器窗口
谁调用我,我关谁
window.close(); - **open(“ “)**:打开一个新的浏览器窗口
参数可以传url,来打开指定地址的新窗口
返回值是新的window对象
- **close()**:关闭浏览器窗口
与定时器有关的方法:
**setTImeout()**:在指定的毫秒数后调用函数或计算表达式 一次性
参数:- js代码或者方法对象
- 毫秒值
返回值:
返回计时器的唯一编号id,用于取消定时器
**clearTimeout()**:取消由setTImeout() 方法设置的 timeout
参数:- 定时器的唯一编号,来确定取消哪一个定时器
**setInterval()**:按照指定的周期(以毫秒计)来调用函数或计算表达式 循环性
参数:
- js代码或者方法对象
- 毫秒值
返回值:
返回计时器的唯一编号id,用于取消定时器
**clearInterval()**:取消由setInterval() 设置的 timeout。
参数:
- 定时器的唯一编号,来确定取消哪一个定时器
属性
- 获取其他BOM对象
history
location
Navigator
Screen - 获取DOM对象
document
- 获取其他BOM对象
特点
- Window对象不需要创建可以直接使用 window使用。window.方法名();
- window引用可以省略。 方法名();
Location:地址栏对象
- 创建(获取):
- window.location
- location
- 方法:
- reload( ) 重新加载当前文档。 刷新
- 属性:
- href:设置或返回完整的URL。
History:历史记录对象
History对象包含用户(在浏览器窗口中)访问过的URL。
- 创建(获取):
- window.history
- history
- 方法
- back()
- forward()
- go(参数)
参数:- 正数:前进几个历史记录
- 负数:后退几个历史记录
- 属性
length:返回当前窗口历史列表中的URL历史记录数量
DOM
概念:Document Object Mode 文档对象模型
- 将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行一些CRUD的的动态操作
HTML DOM 定义访问和操作HTML文档的标准方法。
DOM将HTML文档表达为树形结构
W3C DOM 标准被分为3个不同的部分:
核心DOM - 针对任何结构化文档的标准模型
Document:文档对象
Element:元素对象
Attribute:属性对象
Text:文本对象
Comment:注释对象
Node:节点对象,其他5个的父对象
XML DOM - 针对XML文档的标准模型
HTML DOM - 针对HTML文档的标准模型
核心DOM模型:
- Document:文档对象
- Element:元素对象
- Node:节点对象,其他5个的父对象
Document:文档对象
- 创建(获取):在html dom模型中可以使用window对象来获取
- window.document
- document
- 方法:
- 获取Element对象:
- getElementById():根据id属性值获取元素对象。id属性值
- getElementsByTagName():根据元素名称获取元素对象们。返回值是一个数组
- getElementsByClassName():根据Class属性值获取元素对象们。返回值是一个数组
- getElementsByName():根据name属性值获取元素对象们。返回值是一个数组
- 创建其他DOM对象:
- createAttribute(name):
- createComment():
- createElement():
- createTextNode():
- 获取Element对象:
- 属性:
Element:元素对象
- 创建(获取):通过document来获取和创建
- 方法:
- removeAttribute():删除属性
- setAttribute():设置属性
Node:节点对象
其他5个的父对象
- 特点:所有dom对象都可以被认为是一个节点
- 方法:
CRUD dom树:- appendChild():向节点的子节点列表的结尾添加新的子节点。
- removeChild():删除(并返回)当前节点的指定子节点。
- replaceChild():用新节点替换一个子节点。
案例:其中的javascript:void(0);来让a标签没有跳转
- 属性:
- parentNode:返回节点的父节点。
HTML DOM
- 标签体的设置和获取:innerHTML
内容可以替换为html代码 - 使用html元素对象的属性
- 控制元素样式
- 使用元素的style属性来设置
如: - 提前定义好类选择器的样式,通过元素的className属性来设置其class属性值
- 使用元素的style属性来设置
BootStrap框架
概念:一个前端开发的框架
- 框架:一个半成品软件,开发人员可以在框架基础上,再次开发,简化编码
- 好处:
- 定义了很多的css样式和js插件。我们开发人员直接可以使用这些样式和插件,得到丰富的页面效果。
- 响应式布局。
- 同一套页面可以兼容不同分辨率的设备。
快速入门
下载bootstrap
在项目中将这三个文件夹复制过来
创建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个格子,可以指定元素占几个格子
- 步骤:
- 定义容器。相当于之前的table。
- 容器分类:
- container:两边留白,固定宽度
- container-fluid:每一种设备都是100%宽度
- 容器分类:
- 定义行。相当于之前的tr。样式:row
- 定义元素。指定该元素在不同的设备上,所占的各自数目。样式:col-设备代号-格子数目
- 设备代号:
- xs:超小屏幕 手机 (<768px):col-xs-12
- sm:小屏幕 平板 (>=768px)
- md:中等屏幕 桌面显示器 (>=992px)
- lg:大屏幕 大桌面显示器 (>=1200px)
- 设备代号:
- 定义容器。相当于之前的table。
- 注意事项
- 一行中如果格子数目超过12,则超出部分自动换行
- 栅格类属性可以向上兼容。栅格类适用于与屏幕宽度大小或等于分界点大小的设备
- 如果真实设备宽度小于了设置的栅格类属性的设备代码的最小值,会一个元素占满一整行。
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”
组件:
- 导航条
- 分页条
插件:
- 轮播图
事件监听机制
概念:某些组件被执行了某些操作后,触发某些代码的执行。
- 事件:某些操作,单击,双击,键盘按下,鼠标移动
- 事件源:组件。如:按钮 文本输入框…
- 监听器:代码。
- 注册监听:将事件,事件源,监听器结合在一起。当事件源上发生了某个事件,则触发执行某个监听器代码。
常见的事件
点击事件
- onclick:单击事件
- ondblclick:双击事件
焦点事件
- onblur:失去焦点
- onfocus:获得焦点
加载事件
- onload:一张页面或一幅图像完成加载
鼠标事件:
- onmousedown:鼠标按钮被按下
- 定义方法时,定义一个形参,接收event对象
- event对象的button属性可以获取鼠标按钮键被点击了
- 左键0,中键1,右键2
- onmouseup:鼠标按键被松开
- onmousemove:鼠标被移动
- onmouseover:鼠标移到某元素之上
- onmouseout:鼠标从某元素移开
- onmousedown:鼠标按钮被按下
键盘事件
- onkeydown:某个键盘按键被按下。
- onkeyup:某个键盘按键被松开。
- onkeypress:某个键盘按键被按下并松开。
选择和改变
- onchange:域的内容被改变。
- onselect:文本被选中。
表单事件
onsubmit:确认按钮被点击。
可以阻止表单的提交
方法返回false则表单被阻止提交
方法1:方法2:
onreset:重置按钮被点击。
XML
w3c:万维网联盟
概念:Extensible Markup Language 可扩展标记语言
- 可扩展:标签都是自定义的。 <user></user>
功能:
- 存储数据
- 配置文件
- 在网络中传输
xml和html的区别
- xml标签都是自定义的,html标签是预定义的。
- xml的语法严格,html语法松散
- xml是存储数据的,html是展示数据的
XML快速入门
语法:
基本语法:
- xml文档的后缀名.xml
- xml第一行必须定义为文档声明
- xml文档中有且仅有一个根标签
- 属性值必须使用引号(单双都可)引起来
- 标签必须正确关闭
- xml标签名称区分大小写
快速入门:
组成部分:
- 文档声明
- 格式:<?xml 属性列表 ?>
- 属性列表:
- version:版本号 必须的属性
- encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1
- standalone:是否独立
取值:- yes:不依赖其他文件
- no:依赖其他文件
- 指令(了解):结合css的
- <?xml-stylesheet type=”text/css” href=”a.css” ?>
- 标签:标签名称自定义的
- 规则:
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml (或者 XML、Xml 等等) 开始
- 名称不能包含空格
- 规则:
- 属性:
id属性值唯一 - 文本内容
- CDATA区:在该区域中的数据会被原样展示
- 格式:<![CDATA[ 数据 ]]>
- CDATA区:在该区域中的数据会被原样展示
- 文档声明
约束
规定xml文档的书写规则
作为框架的使用者(程序员):
- 能够在xml中引入约束文档
- 能够简单的读懂约束文档
分类:
- DTD:一种简单的约束技术
- Schema:一种复杂的约束技术
DTD:
- 引入dtd文档到xml文档中
- 内部dtd:将约束规则定义在xml文档中
- 外部dtd:将约束的规则定义在外部的dtd文件中
- 本地:<!DOCTYPE 根标签名 SYSTEM “dtd文件的位置”>
- 网络:<!DOCTYPE 根标签名 PUBLIC “dtd文件名字” “dtd文件的位置URL”>
- 引入dtd文档到xml文档中
Schema:
声明命名空间xmlns
后缀名.xsd
解析:操作xml文档,将文档中的数据读取到内存中
- 操作xml文档
- 解析(读取):将文档中的数据读取到内存中
- 写入:将内存中的数据保存到xml文档中。
- 解析xml的方式:*
- DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树
- 优点:操作方便,可以对文档进行CRUD的所有操作
- 缺点:占内存
- SAX:逐行读取,基于事件驱动的。
- 优点:不占内存
- 缺点:只能读取,不能增删改
- DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树
- xml常见的解析器:
- JAXP:sun公司提供的解析器,支持dom和sax两种思想
- DOM4J:一款非常优秀的解析器
- Jsoup:jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据。
- PULL:Android操作系统内置的解析器,sax方式的。
Jsoup解析器
快速入门
步骤:
- 导入jar包
- 获取Document对象
- 获取对应的标签Element对象
- 获取数据
对象的使用:
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的文档对象
- parse:解析html或xml文档,返回Document
Document:文档对象。代表内存中的dom树
获取ElementgetElementById(String id):根据id属性值获取唯一的element对象
getElementsByTag(String tagName):根据标签名称获取元素对象集合
getElementsByAttribute(String Key):根据属性名称获取元素对象集合
getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值来获取元素对象
Elements:元素Element对象的集合。可以当做ArrayList<Element>来使用
Element:元素对象
获取子元素对象
getElementById(String id):根据id属性值获取唯一的element对象
getElementsByTag(String tagName):根据标签名称获取元素对象集合
getElementsByAttribute(String Key):根据属性名称获取元素对象集合
getElementsByAttributeValue(String key,String value):根据对应的属性名和属性值来获取元素对象
获取属性值
- String attr(String key):根据属性名称获取属性值
获取文本内容
- String text():获取所有子标签的纯文本内容
- String html():获取标签体的所有内容(包括子标签的标签和文本内容)
Node:节点对象
是Docoument和Element的父类
快捷查询方式
- selector:选择器
- 使用的方法:Elements select(String cssQuery)
- 语法:参考Selector类中定义的语法
- 使用的方法:Elements select(String cssQuery)
- XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言
- 使用Jsoup的Xpath需要额外导入jar包。
- 查询w3cschool参考手册,使用xpath的语法完成查询
Web核心
web相关概念回顾
- 软件架构
- C/S:客户端/服务器端
- B/S:浏览器/服务器端 请求/响应
- 资源分类
- 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析
如:html,css,javascript - 动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换成静态资源,在返回给浏览器
如:servlet/jsp,php,asp…
- 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析
- 网络通信三要素
- IP:电子设备(计算机)在网络中的唯一标识
- 端口:应用程序在计算机中的唯一标识。0-65536 1024以内可能被系统占用
- 传输协议:规定了数据传输的规则
- 基础协议:
- tcp:安全协议,三次握手。速度稍慢
- 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服务器软件
安装:解压压缩包即可。
注意:安装目录建议不要有中文和空格卸载:删除安装目录文件夹
目录结构:启动:startup:启动 默认端口:8080
- bin/startup.bat,双击运行该文件即可
- 访问:浏览器输入:http://;localhost:8080 回车访问自己
http://别人ip:8080 访问指定ip
- 访问:浏览器输入:http://;localhost:8080 回车访问自己
- 可能遇到的问题:
- 暴力:找到占用的端口号,并且找到对应的进程,杀死该进程
- cmd命令netstat -ano 获取占用端口进程进程PID 在任务管理器杀死占用进程
- 温柔:修改自身的端口号
- 在tomcat安装目录conf/server.xml配置文件 修改相应的默认端口号
- 一般会将tomcat的默认端口号修改为80。80端口号是http协议的默认端口号。
- 好处:在访问时,就不用输入端口号
- 暴力:找到占用的端口号,并且找到对应的进程,杀死该进程
- bin/startup.bat,双击运行该文件即可
关闭:
- 正常关闭:
- bin/shutdown.bat
- Ctrl+C
- 强制关闭:
- 点击启动窗口的x
- 正常关闭:
配置:
部署项目的方式:
直接将项目放到webapps目录下即可
- /hello:项目的访问路径–>虚拟路径
- 简化部署:将项目打成一个war包,再将war包放置在webapps目录下
- war包会自动解压缩 war包可以通过压缩成zip后改后缀名 当然,推荐的是用专门的软件打包成war包
配置conf/server.xml文件
- 在<Hose>标签体中配置
<Context docBase=”D:\hello” path=”/hehe” />- docBase:项目存放的路径
- path:虚拟目录
- 在<Hose>标签体中配置
在conf/Catalina/locahost创建任意名称的xml文件。在文件中编写
<Context docBase=”D:\hello” />- 访问时虚拟目录为:xml文件的名称
- 好处还有可以热部署 更改server.xml文件需要重新启动tomcat,而且更改server.xml有可能导致全部项目打不开
静态项目和动态项目
目录结构
Java动态项目的目录结构
– 项目的根目录
– WEB-INF目录:
– web.xml:web项目的核心配置i文件 – classes目录:放置字节码文件的目录
– lib目录:放置依赖的jar包
将Tomcat继承到IDEA中,并且创建JavaEE的项目,部署项目
经过一系列的部署
新版idea中,创建java模块然后右键添加支持框架
配置tomcat在模块设置 添加tomcat配置
最后配置下tomcat的热部署以及在服务启动时部署
Servlet
- 概念server applet:运行在服务器端的小程序
- servlet就是一个接口,定义了java类被浏览器访问到(Tomcat识别)的规则
- 将来我们自定义要给类,实现Servlet接口,复写方法。
- 快速入门:
- 创建Java EE项目
- 定义一个类,实现Servlet接口
- public class ServletDemo1 implements Servlet
- 实现接口中的抽象方法
- 配置Servlet
- 执行原理:
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
- 如果有,则在找到对应的<servlet-class>全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
Servlet中的方法
被创建:执行init方法,只执行一次
Servlet什么时候被创建- 默认情况下,第一次被访问是,Servlet被创建
- 可以配置执行Servlet的创建时机。
- 在web.xml中的<servlet>标签下配置
- 第一次被访问时,创建
- <load-on-startup>的值为负数
- 在服务器启动时,创建
- <load-on-startup>的值为0或正整数
- 第一次被访问时,创建
- 在web.xml中的<servlet>标签下配置
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
- 多个用户同时访问时,可能存在线程安全问题
- 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值
提供服务:执行service方法,执行多次
- 每次访问Servlet时,Service方法都会被调用一次。
被销毁:执行destroy方法,只执行一次
- servlet被销毁时执行。服务器关闭时,Servlet被销毁
- 只有服务器正常关闭时,才会执行destory方法、
- destroy方法在Servlet被销毁之前执行,一般用于释放资源
getServletConfig方法 获取ServletConfig 对象 Servlet的配置对象
getServletInfo获取Servlet的一些信息,版本,作者等等。
Servlet3.0
- 好处:
- 支持注解配置。可以不需要web.xml了。
- 步骤:
- 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
- 定义一个类,实现Servlet接口
- 复写方法
- 在类上使用@WebServlet注解,进行配置
- @WebServlet(“资源路径”) 注解中有一个value,value表示重要的属性,只有一个属性value可以省略
- @WebServlet(urlPatterns = “资源路径”) 与1一样,直接用1
- IDEA与tomcat的相关配置
- IDEA会为每一个tomcat部署的项目单独建立一份配置文件
- 查看控制台的log:Using CATALINA_BASE:”路径”
- 工作空间项目 和 tomcat部署的web项目
- tomcat真正访问的是”tomcat部署的web项目”,”tomcat部署的web项目”对应着”工作空间项目”的web目录下的所有资源
- WEB-INF目录下的资源不能被浏览器直接访问。
- 断点调试:使用”小虫子”启动debug启动
- IDEA会为每一个tomcat部署的项目单独建立一份配置文件
Servlet的体系结构
Servlet – 接口
|
GenericServlet – 抽象类
|
HttpServlet – 抽象类
GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
- 将来定义Servlet类时,可以继承GennericServlet,实现Service()方法即可
HttpServlet
对http协议的一种封装,简化操作
- 定义类继承HttpServlet
- 复写doGet/doPost方法
Servlet相关配置
- urlpartten:Servlet访问路径
- 一个Servlet可以定义多个访问路径:@WebServlet({“/d4”,”/dd4”,”/ddd4”})
- 路径定义规则:
- /xxx:
- /xxx/xxx:多层路径,目录结构 /xxx/* *通配符写啥都可以
- /* 不管写什么路径都可以访问到 优先级比较低 找不到别的 用这个 不常用
- *.扩展名 *.do 别加/
HTTP
概念:Hyper Text Transfer Protocol 超文本传输协议
- 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
http://www.baidu.com - 基于请求响应/响应模型的,一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
- 历史版本:
- 1.0:每一次请求响应都会建立新的连接
- 1.1:复用连接
请求消息数据格式
请求行
请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1请求方式:
- HTTP协议有7种请求方式,常用的有两种
- GET:
- 请求参数在请求行中,在url后
- 请求的url长度有限制的
- 不太安全
- POST:
- 请求参数在请求体中
- 请求的url长度没有限制的
- 相对安全
- GET:
- HTTP协议有7种请求方式,常用的有两种
请求头:客户端浏览器告诉服务器一些信息
请求头名称:请求头值- 常见的请求头
- User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
- 可以在服务器端获取该头的信息,解决浏览器的兼容问题
- Referer:http://localhost/login.html
- 告诉服务器,我(当前请求)从哪里来
- 作用:
- 防盗链:
- 统计工作:
- 作用:
- 告诉服务器,我(当前请求)从哪里来
- User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
- 常见的请求头
请求空行
空行,就是用于分割POST请求的请求头,和请求体的。请求体(正文)
- 封装POST请求消息的请求参数的
- 字符串格式:
GET /login.html HTTP/1.1
Request
request对象和response对象的原理
- request和response对象是由服务器创建的。我们来使用它们
- request对象是来获取请求消息,response对象是来设置响应消息
request对象继承体系结构
ServletRequest – 接口HttpServletRequest – 接口
org.apache.catalina.connector.RequestFacade 类(tomcat)request
获取请求消息
- 获取请求行数据
格式:GET /day14/demo1?name=zhangsan HTTP/1.1- 方法:
- 获取请求方式:GET
- String getMethod()
- ***获取虚拟目录:/day14
- String getContextPath()
- 获取Servlet路径:
- String getServletPath()
- 获取get方式的请求参数:name=zhangsan
- String getQueryString()
- ***获取请求URI/URL:/day14/demo1
- String getRequestURI() /day14/demo1
- StringBuffer getRequestURL() http://localhost/day14/demo1
- URL:统一资源定位符:http://localhost/day14/demo1 中华人民共和国
- URI:统一资源标识符:/day14/demo1 共和国
- 获取协议及版本:HTTP/1.1
- String getProtocol()
- 获取客户机的IP地址
- String getRemoteAddr()
- 获取请求方式:GET
- 方法:
- 获取请求头数据
- 方法:
- (*) String **getHeader(String name)**:通过请求头的名称获取请求头的值
- Enumeration<String> **getHeaderNames()**:获取所有的请求头名称
- 方法:
- 获取请求体数据
- 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
- 步骤:
- 获取流对象
- BufferedReader **getReader()**:获取字符输入流,只能来操作字符数据
- ServletInputStream **getInputStream()**:获取字节输入流,可以操作所有类型数据
- 在文件上传知识点后讲解
- 再从流对象中拿数据
- 获取流对象
- 获取请求行数据
其他功能:
获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
- String **getParameter(String name)**:根据参数名称获取参数值 username=zs&password=123
- String[] **getParameterValues(String name)**:根据参数名称获取参数值的数组 hobby=xx&hobby=game
- Enumeration<String> **getParameterNames()**:获取所有请求的的参数名称
- Map<String,String[]> **getParameterMap()**:获取参数的map集合
中文乱码问题:
get方式:tomcat8 已经将get方式乱码问题解决了
post方式:会乱码
解决:在获取参数前设置请求request的编码 req.setCharacterEncoding(“UTF-8”);
请求转发:一种在服务器内部的资源跳转方式
- 步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequstDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:forward(ServletRequest req, ServletReponse resp)
- 特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源中
- 转发是一次请求
- 步骤:
共享数据:
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
- 方法:
- void setAttribute(String name,Object obj) :存储数据
- Object **getAttribute(String name)**:通过名字获取值
- void **removeAttribute(String name)**:通过键一处键值对
获取ServletContext
- ServletContext getServletContext()
案例:用户登陆
用户登陆案例需求:
编写login.html登陆页面
username & password 两个输入框使用Druid数据库连接池技术,操作mysql,login数据库中user表
使用jdbcTemplate技术封装JDBC
登陆成功跳转到SuccessServlet展示:登陆成功!用户名,欢迎你
登陆失败跳转到FailServlet展示:登陆失败,用户名或密码错误
分析
开发步骤
创建项目,导入配置文件,jar包
创建数据库环境
创建包cn.itcast.domain,创建类User
创建包cn.itcast.dao,创建类UserDao,提供login的方法
编写cn.itcast.servlet,创建类LoginServle类
login.html中form表单的action路径的写法
- 虚拟目录+Servlet的资源路径
BeanUtils工具类,简化数据的封装
用户封装JavaBean的JavaBean:标准的java类
要求:
- 类必须被public修饰
- 必须提供空参的构造器
- 成员变量必须使用private
- 提供公共setter和getter方法
功能:封装数据
概念: &&
成员变量:
属性:setter和getter方法截取后的产物
例如:getUsername( ) –> Username –> username方法:
- setProperty()
- getProperty()
- populate(Object obj,Map map):将map集合的键值对信息,封装到对应的JavaBean对象中
响应消息数据格式
- 响应行
- 组成:协议/版本 响应状态码 状态码描述
- 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
- 状态码都是3位数字
- 分类:
- 1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx多状态码
- 2xx:成功。代表:200
- 3xx:重定向。代表:302(重定向),304(访问缓存)
- 4xx:客户端错误。
- 代表:
- 404(请求路径没有对应的资源)
- 405(请求方式没有对应的doXxx方法)
- 代表:
- 5xx:服务器端错误。代表:500(服务器内部出现异常)
- 响应头
- 格式:头名称:值
- 常见的响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- Content-disposition:服务器告诉客户端以什么格式打开响应体数据
- 值:
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体。文件下载
- 值:
- 响应空行
- 响应体:传输的数据
响应字符串形式
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
功能:设置响应消息
- 设置相应行
- 格式:HTTP/1.1 200 ok
- 设置状态码:setStatus( int sc )
- 设置响应头:setHeader( String name, String value )
- 设置响应体:
- 使用步骤:
- 获取输出流
- 字符输出流:PrintWriter getWriter()
- 字节输出流:ServletOutputStream getOutputStream()
- 使用输出流,将数据输出到客户端浏览器
- 获取输出流
- 使用步骤:
- 设置相应行
案例:
完成重定向
- 重定向:资源跳转的方式
- 代码实现
- 设置状态码为302,告诉浏览器重定向
- 设置响应头location,这就是B资源的路径
- 简单的重定向方法
sendRedirect(“路径”) - 重定向的特点:redirect
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求,不能使用request对象来共享数据
- 转发的特点:forward
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
- 路径写法
- 路径分类
- 相对路径:通过相对路径不可以确定唯一资源
- 如:./index.html
- 不以/开头,以 . 开头路径
- 规则:找到访问当前资源和目标资源之间的相对位置关系
- ./ :当前目录
- ..// :后退一级目录
- 绝对路径:通过绝对路径可以确定唯一资源
- 如:http://localhost/day15/responseDemo2 /day15/responseDemo2
- 以/开头的路径
- 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
- 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)|
- 建议虚拟目录动态获取:request.getContextPath()
- <a> , <form> 重定向…
- 给服务器使用:不需要加虚拟路径
- 转发路径
- 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)|
- 相对路径:通过相对路径不可以确定唯一资源
- 路径分类
服务器输出字符数据到浏览器
步骤:
- 获取字符输出流
- 输出数据
注意:
乱码问题:
PrintWriter Pw = response.getWriter(); 获取的流的默认编码是ISO-8859-1
设置该流的默认编码
告诉浏览器响应体使用的编码
简单的形式,设置编码,是在获取流之前设置
response.setContentType(“text/html;chars et=utf-8”);
服务器输出字节数据到浏览器
- 步骤:
- 获取字节输出流
- 输出数据
- 步骤:
验证码
- 本质:图片
- 目的:放置恶意表单注册
ServletContext
概念:代表整个web应用,可以和程序的容器(服务器)来通信
获取:
- 通过request对象获取
request.getServletContext(); - 通过HttpServlet获取
this.getServletContext();
- 通过request对象获取
功能:
获取MIME类型:
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html image/jpeg
- 获取:String getMimeType(String file) 括号内参数一般为文件后缀
- MIME类型:在互联网通信过程中定义的一种文件数据类型
域对象:共享数据
- setAttribute(String name, Object value)
- getAttribute(String name)
- removeAttribute(String name)
- ServletContext对象范围:所有用户所有请求的数据
获取文件的真实(服务器)路径
- 方法:String getRealPath(String path)
案例
- 文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
分析:
- 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
- 任何资源都必须弹出下载提示框
- 使用响应头设置资源的打开方式:
- content-desponsition:attachment;filename-xxx
步骤:
- 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
- 定义Servlet
- 获取文件的名称
- 使用字节输入流加载文件进内存
- 指定response的响应头:content-desposition:attachment;filename=xxx
- 将数据写出到response输出流
问题:
- 中文文件名问题
- 解决思路:
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置filename的编码方式不同
- 解决思路:
- 中文文件名问题
会话技术
- 会话:一次会话中包含多次请求和响应。
- 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
- 功能:再一次会话的范围内的多次请求间,共享数据
- 方式:
- 客户端会话技术:Cookie
- 服务器端绘画技术:Session
Cookie
- 概念:客户端会话技术,将数据保存在客户端
- 快速入门:
- 使用步骤
- 创建Cookie对象,绑定数据
- new Cookie(String name, String value)
- 发送Cookie对象
- response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据
- Cookie[] request.getCookies()
- 创建Cookie对象,绑定数据
- 使用步骤
- 实现原理
- 基于响应头set-cookie和请求头cookie实现
cookie的细节
一次可不可以发送多个cookie?
- 可以
- 可以创建多个cookie对象,使用response调用多次addCookie方法发送cookie即可。
cookie在浏览器中保存多长时间?
- 默认情况中,当浏览器关闭后,Cookie数据被销毁
- 持久化存储:
- setMaxAge(int seconds)
- 正数:将cookie数据写到硬盘的文件中。持久化存储。cookie存活事件
- 负数:默认值
- 零:删除cookie信息
- setMaxAge(int seconds)
cookie能不能存中文?
- 在tomcat 8 之前 cookie中不能直接存储中文数据。
- 需要将中文数据转码—一般采用URL编码(%E3)
- 在tomcat 8 之后, cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
- 在tomcat 8 之前 cookie中不能直接存储中文数据。
cookie共享问题?
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享
默认情况下cookie不能共享
**setPath(String path)**:设置cookie的获取范围。默认情况下,设置当前的虚拟目录
- 如果要共享,则可以将path设置为”/“
不同的tomcat服务器间cookie共享问题?
- **setDomain(String path)**:如果设置一级域名相同,那么多个服务器之间cookie可以共享
- setDomain(“.baidu.com”); 那么tieba.baidu.com和news.baidu.com中cookie可以共享
- **setDomain(String path)**:如果设置一级域名相同,那么多个服务器之间cookie可以共享
Cookie(小饼干) 的特点和作用
- cookie存储数据在客户端浏览器
- 浏览器对于单个cookie的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20)
- 作用:
- cookie一般用于存储少量的不太敏感的数据
- 在不登陆的情况下,完成服务器对客户端的身份识别
案例:记住上一次访问事件
- 案例需求:
- 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
- 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
- 分析:
- 可以采用Cookie来完成
- 在服务器中的Servlet判断是否有一个名为lastTime的cookie
- 有:不是第一次访问
- 响应数据:欢迎回来,您上次访问时间为:2023年10月20日22:09:00
- 写回Cookie:lastTime=2023年10月20日22:09:00
- 没有:是第一次访问
- 响应数据:您好,欢迎您首次访问
- 写回Cookie:lastTime=2023年10月20日22:09:00
- 案例需求:
JSP:入门学习
概念:
Java Server Pages:java服务器端页面
可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
用于简化书写!!!
原理
- JSP本质上就是一个Servlet
JSP的脚本:JSP定义代码的方式
- **<% 代码 %>**:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本就可以定义什么。
- **<%! 代码 %>**:定义的Java代码,在jsp转换后的java类的成员位置。
- **<%= 代码 %>**:会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
JSP的内置对象
- 在jsp页面中不需要获取和创建,可以直接使用的对象
- jsp一共有9个内置对象。
- 先学习3个:
- request
- response
- out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
- response.getWriter()和out.writer()的区别:
- 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
- response.getWriter( )数据输出永远在out.write()之前
- response.getWriter()和out.writer()的区别:
改造Cookie案例
- JSP脚本可以截断 截断后中间用正常的html
Session
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
快速入门:
获取Session对象
HttpSession session = request.getSession();HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
原理
- Session的实现是依赖于Cookie的。
细节:
- 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
- 默认情况下,不是
- 如果需要相同,则可以创建cookie,键位JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie c = new Cookie(“JSESSIONID”,session.getID());
c.setMaxAge(60 * 60);
response.addcookie(c);
- 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
- 不是同一个 ,但是要确保数据不丢失
- session的钝化:
- 在服务器正常关闭之前,将session对象序列化到硬盘上
- session的活化:
- 在服务器启动后,将session文件转化为内存中的session对象即可。
- session的钝化:
- 不是同一个 ,但是要确保数据不丢失
- session什么时候被销毁?
- 服务器关闭
- session对象调用 invalidate() 。
- session默认失效时间 30分钟
选择性配置修改
<session-config>
<session=timeout>30<session-timeout>
<session-config>
- 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
session(主菜)的特点
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型,任意大小的数据
- session与Cookie的区别:
- session存储数据在服务器端,Cookie在客户端
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全
案例:验证码
案例需求:
- 访问带有验证码的登陆页面login.jsp
- 用户输入用户名,密码以及验证码。
- 如果用户名和密码输入有误,跳转登陆页面,提示:用户名和密码错误
- 如果验证码输入有误,跳转登陆页面,提示:验证码错误
- 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
分析
JSP
- 指令
- 作用:用于配置JSP页面,导入资源我呢见
- 格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %> - 分类:
- page :配置JSP页面的
- contentType:等同于response.setContentType()
- 设置响应体的mime类型以及字符集
- 设置当前jsp页面的编码(只能是高级的IDE,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
- import:导包
- errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
- isErrorPage:表示当前页面是否是错误页面。
- true:是,可以使用内置对象exception
- false:否。默认值。不可以使用内置对象exception
- contentType:等同于response.setContentType()
- include :页面包含的。导入页面的资源文件
- <%@include file=”top.jsp”%>
- taglib :导入资源
- <%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jst1/core“ %>
- prefix:前缀,自定义的 一般为c
- <%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jst1/core“ %>
- page :配置JSP页面的
- 注释:
- html注释:
**<!– –>**:只能只是html片段 - jsp注释
**<%– –%>**:可以注释所有
- html注释:
- 内置对象
- 在jsp页面中不需要创建,直接使用的对象
- 一共有9个:
- 变量名 真实类型 作用
- pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象
- request HttpServletRequest 一次请求访问的多个资源(转发)
- session HttpSession 一次会话的多个请求间
- application ServletContext 所有用户间共享数据
- response HttpServletResponse 响应对象
- page Object 当前页面(Servlet)的对象 this
- out JspWriter 输出对象,数据输出到页面上
- config ServletConfig Servlet的配置对象
- exception Throwable 异常对象
MVC:开发模式
jsp演变历史
- 早期只有servlet,只能使用response输出标签数据,非常麻烦
- 后来有了jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难以维护,难以分工协作
- 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性
MVC:
- M:Model,模型。JavaBean
- 完成具体的业务操作,如:查询数据库,封装对象
- V:View,视图。JSP
- 展示数据
- C:Controller,控制器。Servlet
- 获取用户的输入
- 调用模型
- 将数据交给视图进行展示
- 优缺点
- 优点:
- 耦合性低,方便维护,可以利于分工协作
- 重用性高
- 缺点:
- 使得项目架构变得复杂,对开发人员要求高
- 优点:
- M:Model,模型。JavaBean
EL表达式
- 概念:Expression Language 表达式语言
- 作用:替换和简化jsp页面中java代码的编写
- 语法:${ 表达式 }
- 注意:
- jsp默认支持EL表达式。如果要忽略EL表达式
- 设置jsp中page指令中:isELIgnored=”true” 忽略当前页面中所有的EL表达式
- \${表达式}:忽略当前这个EL表达式
- jsp默认支持EL表达式。如果要忽略EL表达式
- 使用:
- 运算
- 运算符:
- 算术运算符: + - * /(div) %(mod)
- 比较运算符: > < >= <= == !=
- 逻辑运算符: &&(and) ||(or) !(not)
- 空运算符:empty
- 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
- ${empty list}:判断字符串、集合、数组对象是否为null
- ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
- 运算符:
- 获取值
- el表达式只能从域对象中获取值
- 语法:
- ${域名称.键名}:从指定域中获取指定键的值
- 域名称:
- pageScope –> pagecontext
- requestScope –> request
- sessionScope –> session
- applicationScope –> application(ServletContext)
- 举例:在request域中存储了name=张三
- 获取:${requstScope.name}
- 域名称:
- ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。//可以简化书写
- ${域名称.键名}:从指定域中获取指定键的值
- 获取对象、List集合、Map集合的值
- 对象:${域名称.键名.属性名}
- 本质上会去调用对象的getter方法
- List集合:*${域名称.键名[索引]}*
- Map集合:
- ${域名称.键名.key名称}
- ${域名称.键名[“key名称”]}
- 对象:${域名称.键名.属性名}
- 隐式对象:
- el表达式中有11个隐式对象
- pageContext:
- 获取jsp其他8个内置对象
- ${pageContext.request.contextPath}:动态获取虚拟目录
- 获取jsp其他8个内置对象
- 运算
JSTL
- 概念:JavaServer Pages Tag Library JSP标准标签库
- 是由Apache组织提供的开源的免费的jsp标签 <标签>
- 作用:用于简化和替换jsp页面上的java代码
- 使用步骤:
- 导入jstl相关的jar包
- 引入标签库:taglib指令: <%@ taglib %>
- 使用标签
- 常用的 JSTL 标签
- if :相当于Java代码中的 if 语句
- choose :相当于Java代码中的 switch语句
- foreach :相当于Java代码中的 for 语句
- if :相当于Java代码中的 if 语句
- 练习:
- 需求在request域中有一个 存有User对象的List集合。需要使用 jstl+el 将 list 集合数据展示到 jsp 页面的表格 table 中
三层架构:软件设计架构
- 界面层(表示层):用户看到的界面。用户可以通过界面上的组件和服务器进行交互
- 业务逻辑层:处理业务逻辑的。
- 数据访问层:操作数据存储文件。
案例:用户信息列表展示
- 需求:用户信息的增删改查操作
- 设计:
- 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtils+tomcat
- 数据库设计:
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)
);
- 开发:
- 环境搭建
- 创建数据库环境
- 创建项目,导入需要的 jar 包
- 编码
- 环境搭建
- 测试
- 部署运维
分析: