JavaWeb知识汇总

news2024/12/24 8:57:11

文章目录

    • 前导
    • 一、数据库
      • 1.相关概念
      • 2.数据模型
      • 3.SQL
      • 4.约束
      • 5.数据库设计
      • 6.多表查询
      • 7.事务
    • 二、JDBC
      • 1.步骤
      • 2.JDBC事务管理
      • 3.数据库连接池
    • 三、Maven
      • 1.maven生命周期
      • 2.maven坐标详解
      • 3.依赖管理
    • 四、Mybatis
      • 1.快速入门
      • 2.Mapper代理开发
      • 3.核心配置文件
      • 4.参数传递
      • 5.注解开发
    • 五、HTML
      • 1.快速入门
      • 2.基本标签
    • 六、CSS
      • 1.导入方式
      • 2.选择器
    • 七、JavaScript
      • 1.引入方式
      • 2.基础语法
      • 3.JavaScript对象
      • 4.事件监听
      • 5.正则表达式
    • 八、web核心
      • 1.HTTP
        • 1.请求数据格式
        • 2.响应数据格式
      • 2.Web服务器—tomcat
      • 3.Servlet
        • 1.快速入门
        • 2.servlet生命周期
        • 3.体系结构
      • 4.Request&Response
    • 九、JSP
      • 1.jsp原理
      • 2.jsp脚本
    • 十、会话跟踪技术
      • 1.Cookie
      • 2.Session
      • 3.小结
    • 十一、Filter&Listener
      • 1.Filter
      • 2.Listener
    • 十二、AJAX
    • 十三、Vue
    • 十四、Element

前导

  1. 数据库:MySQL、JDBC、maven、mybatis
  2. 前端:HTML+css、js、Ajax+vue+ElementUI
  3. web核心:tomcat+HTTP+servlet、request+response、jsp、cookie+session、filter+listener

一、数据库

1.相关概念

MySQL安装:解压版/安装版

MySQL登录参数:

mysql -u用户名 -p密码 -h要连接得MySQL服务器得IP地址(默认为127.0.0.1) -P端口号(默认3306)
mysql -uroot -p123456 -h127.0.0.1 -P3306

2.数据模型

关系型数据库:建立在关系模型基础上的数据库,多张能够相互连接的二维表组成的数据库(通过表来存储数据,这也是关系型数据库和非关系型数据库的区别)

数据库对应在硬盘上的文件夹,/mysql/data/database

3.SQL

sql语句不区分大小写,建议把关键字大写

单行注释:-- 内容或者#内容,注意–后有空格

在这里插入图片描述

DDL对数据库和表的操作:

#数据库操作
show databases;
#information_schema为逻辑视图,硬盘中并不存在
create database if not exists db1;

drop database db1;
drop database if exists db1;

use db1;
select database();#查看当前使用的数据库

#表操作
show tables;
desc table1;#查看表的结构信息

create table 表名(
  字段名1 类型1,
  字段名2 类型2,
  score double(5,2) #描述为0~100分,保留2位小数
);
#最后一行末尾不要加逗号

char数据类型表示定长字符串,浪费空间但是存储性能高;varchar描述变长字符串,节约空间但存储性能低。如性别确认的这一类字段,用char

drop table stu;
drop table if exists stu;

#修改表
1.修改表名
alert table student rename to stu;

2.添加一列
alter table stu add address varchar(50);

3.修改数据类型
alter table modify address char(50);

4.修改列名和数据类型
alter table 表名 change 列名 新列名 新数据类型;
alter table stu change address addr varchar(30);

5.删除列
alter table stu drop addr;

DML对表中数据进行增删改操作

insert into 表名(列名1,列名2,...)values (值1,值2,...);
insert into 表名(列名1,列名2,...)values (值1,值2,...),values (值1,值2,...),values (值1,值2,...),...;	#批量添加

update 表名 set 列名1=值1,列名2=值2,... [where 条件];
#修改语句如果不加条件,则将所有数据都修改

delete from 表名 [where 条件];

DQL查询操作

select 字段列表 from 表名列表 where 条件 
                            group by 分组字段 
                            having 分组后条件 
                            order by 排序字段 
                            limit 分页限定;
#不要使用select * from stu;
select name,age,sex as 性别 from stu;
#去除重复记录
select distinct 字段列表 from 表名;
select *from stu where age between 20 and 30;
#不等号:!=、<>
#null值的比较不能使用=或者!=,需要使用is 或者 is null
#等号:=
like 模糊查询:_单个任意字符;%多个任意字符

ASC:升序排列(默认值);DESC:降序排列
select *from stu order by math desc,english asc;#按数学成绩降序,若相同按英语升序
#如果有多个排序条件,当前边的条件值相同时,才会根据第二个条件进行排序

#聚合函数:将一列数据作为整体,进行纵向计算,如count(),max(),...
#null值不参与所有聚合函数的运算
select 聚合函数(列名) from 表;
select count(*) from stu;

#执行顺序:where > 聚合函数 > having
#分组之后,查询的字段为聚合函数或者为分组字段,查询其他字段无任何意义
select sex,avg(math) from stu group by sex;

where和having的区别:

  • 执行时机不一样:where是分组之前进行限定,不满足where条件,则不参与分组,而having是分组之后对结果进行过滤

  • 可判断的条件不一样:where不能对聚合函数进行判断,having可以

    #分页查询
    select 字符列表 from 表名 limit 起始索引,查询条目数;
    select *from stu limit 0,3;
    #起始索引从0开始
    #计算公式:起始索引=(当前页码-1)*每页显示的条数

4.约束

约束作用于表中列上的规则,用于限制加入表中的数据

create table dept(
id int primary key auto_increment,
name varchar(20) not null unique,
bonus double(7,2) default 0,
);
#自增长:当列是数字类型并且唯一约束

外键约束:让两个表的数据之间建立连接,保证数据的一致性和完整性

create table emp(
id int primary key,
name varchar(20),
dept_id int,
constraint fk_emp_dept foreign key(dept_id) references dept(id)
#constraint 外键名称 foreign key(外键列名)references 主表(主表列名)
);
alter table 表名 add constraint 外键名称 foreign key (外键字段名称)references 主表名称(主表列名);

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

5.数据库设计

软件研发步骤:需求分析——设计——编码——测试——安装部署

数据库设计:有哪些表,表中有哪些字段,表与表有哪些关系

数据库设计步骤:需求分析——逻辑分析(ER)——物理设计——维护设计

一对一关系:多用于表拆分,将一个实体中常用字段放一张表,不经常使用的字段放另一张表,用于提升查询性能,如tb_user,tb_user_desc,设置唯一约束外键保证一对一关系

设计实现:

  1. 一对多:在多的一方建立外键关联一的一方主键
  2. 多对多:建立第三张中间表,中间表至少包含2个外键,分别关联双方主键
  3. 一对一:在任意一方建立外键,关联对方主键,并设置外键唯一

6.多表查询

连接查询:

  1. 内连接:相当于查询A B交集数据

  2. 外连接:左外连接;右外连接

    #隐式内连接
    select 字段列表 from 表1,表2,… where 条件;
    select t1.name,t1.gender,t2.name from emp t1,dept t2 where t1.dept_id=t2.id;

    #显式内连接
    select 字段列表 from 表1 [inner] join 表2 on 条件;
    select *from emp inner join dept on emp.dept_id=dept.id;

    #左外连接:查询A表的所有数据和交集部分数据
    select 字段列表 from 表1 left [outer] join 表2 on 条件;

    #右外连接:查询B表的所有数据和交集部分数据
    select 字段列表 from 表1 right [outer] join 表2 on 条件;

子查询

#1.单行单列:作为条件值,使用= != > < 等进行条件判断
select 字段列表 from 表 where 字段名 = (子查询);

#2.多行单列:作为条件值,使用in等关键字进行条件判断
select 字段列表 from 表 where 字段名 in (子查询);

#3.多行多列:作为虚拟表
select 字段列表 from (子查询)where 条件;

7.事务

一组数据库操作命令,要么同时成功,要么同时失败

#开启事务,此时的操作是临时性的,需要提交事务进行持久化更改
start transaction;
或者begin;
#提交事务(默认是自动提交的)
commit;
#回滚事务
rollback;

四大特征:A(原子性)C(一致性)I(隔离性)D(持久性)

二、JDBC

使用Java语言操作关系型数据库的一套API,使用这套接口编程,而真正执行的代码是驱动jar包中的实现类

1.步骤

#1.创建工程,导入驱动jar包

#2.注册驱动
Class.forName(driver);

#3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
//若连接本机mysql并且端口默认的3306,可以简写url为"jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true"

#4.定义SQL语句
String sql="update...";

#5.获取执行SQL对象
Statement stmt=conn.createStatement();
或PreparedStatement pstmt=conn.prepareStatement(sql);
#6.执行SQL
stmt.executeUpdate(sql);

#7.处理返回结果

#8.释放资源

2.JDBC事务管理

try{
  //开启事务
  conn.setAutoCommit(false);
  //执行sql
  int count=stmt.executeUpdate(sql);
  //提交事务
  conn.commit();
}catch(Exception e){
  //回滚事务
  conn.rollback();
}

PreparedStatement作用:预编译SQL语句并执行,性能更高,而且它可以预防SQL注入问题

SQL注入:通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法

String pwd="'or'1'='1";
String sql="select *from user where pwd='"+pwd+"'";
//拼完之后得到的sql语句为select *from user where pwd='' or '1'='1';导致问题

3.数据库连接池

  • 数据库连接池是一个容器,负责分配、管理数据库连接
  • 它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个

优势:资源重用;提升系统响应速度;避免数据库连接遗漏

常见的数据库连接池:DBCP;C3P0;Druid(德鲁伊)

步骤:

//1.导入jar包:druid-1.1.12jar

//2.定义配置文件:druid.properties

//3.加载配置文件
Properties prop=new Properties();
prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));

//4.获取连接池对象
DataSource dataSource=DruidDataSourceFactory.createDataSource(prop);

//5.获取数据库连接Connection
Connection conn=dataSource.getConnection();

alt+鼠标左键:整列编辑

在实体类中,基本数据类型建议使用对应的包装类型:例如状态字段如果使用int则默认值为0,可能会对业务的判断有错误的影响,而对应的包装类型Integer默认值为null,就更准确

三、Maven

专门用于管理和构建Java项目的工具:

  1. 一套标准化的项目结构
  2. 一套标准化的构建流程(编译,测试,打包,发布…)
  3. 一套依赖管理机制:管理项目所依赖的第三方资源(jar包、插件…)

依赖管理过程:项目配置引用jar包——本地仓库——中央仓库

//编译
mvn compile
//删除
mvn clean 
//打包
mvn package
//测试:执行/src/test/java路径下的代码
mvn test
//安装:将项目jar安装在本地仓库中
mvn install

1.maven生命周期

Maven提供了三套独立的生命周期:clean, default 和 site

同一生命周期内,执行后面的命令,前面的所有命令会自动执行

clean生命周期:清理项目,删除前一次构建在target文件夹下生成的各个Jar包等,

  • 三个步骤
    pre-clean:执行一些清理前需要完成的工作
    clean:清理上一次构建生成的文件
    post-clean:执行一些清理后需要完成的工作
  • 举例:
    mvn clean 就是在调用clean生命周期的clean阶段,实际执行了pre-clean和clean阶段

default生命周期:定义了真正构建项目中需要执行的所有步骤

  • 八个步骤
    validate:验证工程是否正确,所有需要的资源是否可用。
    compile:编译项目的源代码。
    test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
    package:把已编译的代码打包成可发布的格式,比如jar。
    integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
    verify:运行所有检查,验证包是否有效且达到质量标准。
    install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
    Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
  • 举例:
    1. mvn test 就是在调用default生命周期的test阶段,实际执行了validate到test阶段之间的所有阶段
    2. mvn clean package 就是在调用clean生命周期的clean阶段和default生命周期的package阶段,实际执行clean生命周期pre-clean和clean阶段和default生命周期validate到package阶段之间的所有阶段

site生命周期:是建立和发布项目站点,Maven可以给予pom所包含的信息,生成一个站点,方便团队交流和发布项目信息

  • 四个步骤
    pre- site
    site:生成项目站点文档
    post-site
    site-deploy:将生成的项目站点发布到服务器上

2.maven坐标详解

坐标是资源的唯一标识

主要组成:

  • groupId: 组织名称,如com.itheima

  • artifactId: 定义当前maven项目的名称,通常为模块名称,如order-service

  • version: 当前项目版本号

    com.xin
    maven-demo
    1.0-SNAPSHOT

3.依赖管理

使用坐标导入jar包

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
</dependencies>

依赖范围:通过设置坐标的依赖范围,可以设置对应jar包的作用范围(编译环境、测试环境、运行环境)

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
        <scope>test</scope>
    </dependency>
</dependencies>

在这里插入图片描述

四、Mybatis

mybatis是一个持久层框架,用于简化jdbc开发

JavaEE三次架构:表现层、业务层、持久层

JDBC的缺点:

  1. 硬编码:注册驱动、获取连接、SQL语句
  2. 操作繁琐:手动设置参数、手动封装结果集

1.快速入门

步骤:

  1. 创建表,添加数据

  2. 创建模块,导入坐标

    	<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
    
  3. 编写mybatis核心配置文件mybatis-config.xml——替换连接信息,解决硬编码的问题

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.xin.pojo"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql:///test?serverTimezone=Asia/Shanghai&amp;useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
    <!--        <mapper resource="com/xin/mapper/UserMapper.xml"/>-->
            <package name="com.xin.mapper"/>
        </mappers>
    </configuration>
    
    
  4. 编写SQL映射文件——统一管理SQL语句,解决硬编码的问题

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.xin.mapper.BlogMapper">
      <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
      </select>
    </mapper>
    
  5. 编码
    Ⅰ.定义pojo类
    Ⅱ.加载核心配置文件,获取SqlSessionFactory对象
    Ⅲ.获取SqlSession对象,执行SQL语句
    Ⅳ.释放资源

2.Mapper代理开发

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession = sqlSessionFactory.openSession();
//List<User> list = sqlSession.selectList("test.selectAll");
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.selectAll();
System.out.println(list);
sqlSession.close();

3.核心配置文件

实体类属性名和数据库表列名不一致,不能够自动封装数据:

  1. 起别名
  2. resultMap定义映射

结果映射:resultMap

<resultMap id="userResultMap" type="User">
  <!--id :完成主键字段的映射;result:完成一般字段的映射-->
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

参数占位符:

  1. #{}: 会将其替换为?,防止SQL注入
  2. ${}: 拼sql,会存在SQL注入问题

特殊字符的处理:

  1. 转义字符,如小于号<可以用& lt;
  2. CDATA区

多条件查询参数接收不同方式:

  1. 散装参数:如果方法中有多个参数,使用@Param(“SQL参数占位符名称”)
  2. 对象参数:对象的属性名称要和参数占位符名称一致
  3. map集合参数

动态条件查询:动态SQL(SQL语句会随着用户的输入或外部条件的变化而变化)

  • if:条件判断,test属性表示逻辑表达式
  • choose (when, otherwise)
  • trim (where, set)
  • foreach
<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE state =ACTIVE<if test="title != null">
    AND title like #{title}
  </if>
</select>

//where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state =ACTIVE<choose><!--相当于switch-->
    <when test="title != null"><!--相当于case-->
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

添加功能:

  1. Mybatis事务:openSession()默认开启事务,进行增删查改操作后需要使用sqlSession.commit()手动提交事务;openSession(true)设置为自动提交事务(关闭事务)

  2. 在数据添加成功后,需要获取插入数据库数据主键的值:

        <insert id="addOrder" useGeneratedKeys="true" keyProperty="id">...
    

修改功能:

//set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

批量删除:

void deleteByIds(@Param("ids")int[]ids);

<delete id="deleteByIds">
  delete from tb_brand
  where id in
  <foreach collection="ids" item="id" separator="," open="(" close=")">
    #{id}
  </foreach>
</delete>
//注意:
//collection需要正确对应,如果没有Param注解,基本数组需要用array

4.参数传递

单个参数:

  1. POJO类型:直接使用,属性名和占位符一致
  2. Map集合:直接使用,键名和占位符一致
  3. Collection:封装成Map集合,可以使用@Param注解,替换Map集合中默认的arg键名,可读性更高
    map.put(“arg0”,collection集合);
    map.put(“collection”,collection集合);
  4. List:封装成Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
    map.put(“arg0”,list集合);
    map.put(“collection”,list集合);
    map.put(“list”,list集合);
  5. Array:封装成Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
    map.put(“arg0”,数组);
    map.put(“array”,数组);
  6. 其他类型:直接使用

多个参数:系统默认封装为Map集合

map.put("arg0",参数1);
map.put("arg1",参数2);

map.put("param1",参数1);
map.put("param2",参数2);

5.注解开发

注解完成简单功能

配置文件完成复杂功能

五、HTML

HTML:超文本标记语言,运行在浏览器上,html标签由浏览器解析

网页组成:HTML(结构)+CSS(表现)+JavaScript(行为)

1.快速入门

文件结构:

<html>
  <head>
    <title></title>
  </head>
  <body>
  </body>
</html>

html标签不区分大小写

html文件以.htm或.html为扩展名

html5标识:

2.基本标签

特殊的转义字符:

  • < :& lt;
  • ; :&nbsp;

图片:< img src=“”>

音频:< audio src=“”>

视频:< video src=“”>

超链接:< a>< /a>

  • href指定访问资源的url;
  • target指定打开资源的方式:
    • _self:默认值,在当前页面打开
    • _blank:在空白页面打开

列表:

  • 有序列表ol
  • 无序列表ul
  • 列表项li

布局标签:

  • div:块级标签,独占整行
  • span:行内标签,只占内容的部分,不会独占整行

表单标签

  • 表单项数据要想被提交,必须指定其name属性
  • get:请求参数会拼接在url后面;url长度有限制 4KB
  • post:请求参数会在http请求协议的请求体中;参数长度无限制

六、CSS

css用于控制网页表现

1.导入方式

  • 内联方式:在标签内部使用style属性,属性值为css属性键值对
    < div style=“color:red”>hello css< /div>

  • 内部样式:定义< style>标签,在标签内部定义css样式
    < style type=“text/css”>
    div{
    color:red;
    }
    </ style>

  • 外部样式:定义link标签,引入外部的css文件
    < link rel=“stylesheet” href=“demo.css”>

2.选择器

  1. 元素选择器:元素名称{color:red}
  2. id选择器:#id属性值{}
  3. 类选择器:.class属性值{}

七、JavaScript

js是一门脚本语言,控制网页行为,使网页可以交互,不需要进行编译

1.引入方式

  1. 内部脚本:将js代码定义在html页面中,用< script>< /script>包裹,一般放于< body>元素底部,这样可以改善显示速度,因为脚本执行会拖慢显示
  2. 外部脚本:将js代码定义在外部js文件中,然后引入到html页面中,< script src=“xxx.js”>< /script>

2.基础语法

输出语句:

  • window.alter();//写入警示框
  • document.write(); //写入html
  • console.log(); //写入控制台

var变量:

  1. 作用域:全局变量
  2. 变量可以重复定义

let变量:

  1. 作用域:只在定义的代码块内有效
  2. 变量不允许重复声明

const变量:声明一个只读常量,无法改变

原始数据类型:number;string;boolean;null;undefined(数据未初始化)

可以使用typeof运算符获取数据类型

==:

  1. 判断类型是否一样,如果不一样,则进行类型转换
  2. 再去比较其值

===:

  1. 判断类型是否一样,如果不一样,直接返回false
  2. 再去比较其值

类型转换:

  • 其他类型转为number:
    1. string:按照字符串中的字面值,转为数字,如果字面值不是数字,则转为NaN。一般用parseInt()
    2. boolean:true 为 1 ;false 为 0
  • 其他类型转为boolean:
    1. number:0和NaN转为false;其他的数字转为true
    2. string:空字符串转为false;其他转为true
    3. null:false
    4. undefined:false

函数定义方式:

  1. function 函数名(参数){}
  2. var 函数名=function(参数){}

3.JavaScript对象

JS数组类似于Java集合,长度、类型都可变

String:

  1. 定义:var 变量名=s 或者 var 变量名=new String(s)
  2. 属性:length
  3. 方法:charAt();indexOf();trim():去除字符串两端空白字符

自定义对象:

var 对象名称={
  属性名称1:属性值1,
  属性名称2:属性值2,
  ...
  函数名称:function(形参列表){}
};

BOM对象(浏览器对象模型):

  • Window对象:
    1. confirm():点击确定按钮,返回true;点击取消按钮,返回false
    2. 定时器:
      • setTimeout(function(){},毫秒值):在一定的时间间隔后执行一个function,只执行一次
      • setInterval(function(){},毫秒值):在一定的时间间隔后执行一个function,循环执行
  • History对象(历史记录):
    1. back()
    2. forward()
  • Location对象
    1. href

DOM(文档对象模型):将标记语言的各个组成部分封装为对象

  • 通过DOM,可以对HTML进行操作:
    1. 改变HTML元素的内容
    2. 改变HTML元素的样式
    3. 对HTML DOM事件做出反应
    4. 添加和删除HTML元素
  • 获取方式:
    1. getElementById:根据id属性值获取,返回一个element对象
    2. getElementsByTagName:根据标签名获取,返回element对象数组
    3. getElementsByName:根据name属性值获取,返回element对象数组
    4. getElementsByClassName:根据class属性值获取,返回element对象数组
  • 对象属性:
    1. style:设置元素css样式
    2. innerHTML:设置元素内容

4.事件监听

JavaScript可以在事件被监测到时执行代码

事件:HTML事件是指发生在HTML元素的"事情",例如

  • 按钮被点击
  • 鼠标移动到元素之上
  • 按下键盘按键

事件绑定:

  • 通过HTML标签中的事件属性进行绑定

  • 通过DOM元素属性绑定

    document.getElementById("btn").onclick=function(){}
    

常见事件:

  1. onblur:元素失去焦点
  2. onfocus:元素获取焦点
  3. onsubmit:返回true,则表单提交;返回false,表单不提交

案例:

<script>
  // 1.验证用户名是否符合规则
  //1.1 获取用户名输入框
  var uInput = document.getElementById("username");
  //1.2 绑定onblur事件,失去焦点
  uInput.onblur = checkUsername;
  function checkUsername() {
    //1.3 获取用户输入的用户名
    var username = uInput.value.trim();
    //1.4 判断用户名是否符合规则:长度6-12
    var flag = username.length >= 6 && username.length <= 12;
    if (flag) {
      //符合规则
      document.getElementById("username_err").style.display = 'none';

    } else {
      //不符合规则
      document.getElementById("username_err").style.display = '';
    }
    return flag;
  };

  //1.获取表单对象
  var regForm = document.getElementById("reg-form");
  //2.绑定onsubmit事件
  regForm.onsubmit = function () {
    var flag = checkUsername();
    return flag;
  }
</script>

5.正则表达式

定义字符串组成的规则

定义:

  1. 直接量:var reg=/^\w{6,12}$/;
  2. 创建RegExp对象:var reg=new RegExp(“^\w{6,12}$”);

语法:

验证手机号是否符合规则:长度11;数字组成;第一位为1

var reg=/^[1]\d{10}$/

八、web核心

使用Java技术来解决相关web互联网领域的技术栈

JavaWeb技术栈:

  • B/S架构:客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取web资源,服务器把web资源发送给浏览器、
    1. 好处:易于维护升级;服务器端升级后,客户端无需任何部署就可以使用到新的版本
  • 静态资源:HTML、CSS、JavaScript、图片等等,负责页面展示
  • 动态资源:servlet、jsp等,负责逻辑处理
  • 数据库:负责存储数据
  • Web服务器:负责解析HTTP协议,解析请求数据,并发送响应数据

1.HTTP

超文本传输协议,规定了浏览器和服务器之间数据传输的规则

HTTP协议的特点:

  1. 基于TCP协议:面向连接,安全
  2. 基于请求-响应模型:一次请求对应一次响应
  3. HTTP协议是无状态的协议:对于事务的处理没有记忆能力,每次的请求-响应是独立的
    ①缺点:多次请求间不能共享数据。Java中使用会话技术(Cookie、Session)来解决这个问题
    ②优点:速度快

1.请求数据格式

  1. 请求行:请求数据第一行,其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本

  2. 请求头:第二行开始,格式为key:value
    ● Host:表示请求的主机名

    ● User-Agent:浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0...Chrime/79,IE浏览器的标识类似Mozilla/5.0(Windows NT...) like Gecko;
    
    ● Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
    
    ● Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
    
    ● Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip,deflate等。
    
  3. 请求体:POST请求的最后一部分,存放请求参数

GET请求和POST请求区别:

  • GET请求的请求参数在请求行中,没有请求体;POST请求的请求参数放在请求体中

  • GET请求的请求参数大小有限制,POST没有

    GET /sample.jsp?username=jinqiao&password=1234 HTTP/1.1
    Accept:image/gif.image/jpeg,/
    Accept-Language:zh-cn
    Connection:Keep-Alive
    Host:localhost
    User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
    Accept-Encoding:gzip,deflate

    POST /sample.jsp HTTP/1.1
    Accept:image/gif.image/jpeg,/
    Accept-Language:zh-cn
    Connection:Keep-Alive
    Host:localhost
    User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
    Accept-Encoding:gzip,deflate

    username=jinqiao&password=1234

2.响应数据格式

  1. 响应行:响应数据第一行,其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述

  2. 响应头:第二行开始,格式为key:value
    ● Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;

    ● Content-Length:表示响应内容长度(字节数);
    
    ● Content-Encoding:表示该响应压缩算法,例如gzip;
    
    ● Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
    
  3. 响应体:最后一部分,存放响应数据

状态码大类:

1xx :响应中 — 临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它

2xx :成功 — 表示请求已经被成功接收,处理已完成

3xx :重定向 — 重定向到其他地方:它让客户端再发起一个请求以完成整个处理

4xx :客户端错误 — 处理发生错误,责任在客户端,如:客户端未被授权,禁止访问等

5xx :服务器端错误 — 处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

常见的响应状态码:

200 OK 客户端请求成功,即处理成功。最想看到的状态码
404 Not Found 请求资源不存在,一般是URL输入有误,或者网站资源被删除
500 Internal Server Error 服务器发生不可预期的错误,服务器出异常,赶紧看日志查找异常

2.Web服务器—tomcat

Web服务器是一个应用程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷;可以将web项目部署到服务器中,对外提供网上浏览服务

tomcat是一个轻量级的web服务器,支持servlet/jsp少量JavaEE规范,也称为web容器,servlet容器

部署项目:

  • 将项目放置到webapps目录下,即可部署完成
  • 一般Javaweb项目会被打成war包,然后将war包放到webapps目录下,tomcat会自动解压缩war文件
  • 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
  • pom.xml中依赖坐标对应的jar包,放入WEB-INF下的lib目录下

tomcat-maven插件:run maven->tomcat7:run

	<build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

3.Servlet

servlet是Java提供的一门动态web资源开发技术

servlet是JavaEE的规范之一,就是一个接口,将来我们需要定义servlet类实现servlet接口,并由web服务器运行servlet

1.快速入门

  1. 创建web项目,导入servlet依赖坐标

    	<dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <version>3.1.0</version>
             <scope>provided</scope>
           </dependency>
    
  2. 创建:定义一个类,实现servlet接口,重写接口方法
    public class ServletDemo1 implements Servlet {}

  3. 配置
    @WebServlet(“/demo1”)
    public class ServletDemo1 implements Servlet {}

  4. 访问:启动tomcat,浏览器输入url访问该servlet

2.servlet生命周期

一个对象从创建到被销毁的整个过程

  • 加载和实例化:默认情况下,当servlet第一次被访问时,由容器创建servlet对象
  • 初始化:调用init()方法
    1. 调用时机:默认情况下,servlet被第一次访问时,调用。loadOnStartup参数修改调用时机:负整数表示第一次被访问时创建servlet对象;0或正整数表示服务器启动时创建servlet对象,数字越小优先级越高
    2. 调用次数:1次
  • 请求处理:提供服务service()
    1. 调用时机:每一次servlet被访问时,调用
    2. 调用次数:多次
  • 服务终止:destroy()
    1. 调用时机:内存释放或者服务器关闭的时候,servlet对象会被销毁,调用
    2. 调用次数:1次

3.体系结构

Servlet——GenericServlet——HttpServlet

servlet体系根接口——servlet抽象实现类——对HTTP协议封装的servlet实现类

urlPattern配置:

  • 精确匹配:
    1. 配置路径:@WebServlet(urlPatterns = “/demo1/add”)
    2. 访问路径:http://localhost:8080/demo1/add
  • 目录匹配:
    1. 配置路径:@WebServlet(urlPatterns = “/demo1/*”)
    2. 访问路径:http://localhost:8080/demo1/aaa或者http://localhost:8080/demo1/bbb
  • 扩展名匹配:
    1. 配置路径:@WebServlet(urlPatterns = “*.do”)
    2. 访问路径:http://localhost:8080/add.do
  • 任意匹配:
    1. 配置路径:@WebServlet( “/*”)或者@WebServlet( “/”)
    2. 访问路径:http://localhost:8080/hhh

/和/*的区别:

  • 当项目中servlet配置了“/”,会覆盖tomcat中的DefaultServlet,当其他url-pattern都匹配不上时会走这个servlet
  • 当项目中配置了"/*",意味着匹配任意访问路径

匹配优先级:精确路径 > 目录路径 > 扩展名路径 > /* > /

4.Request&Response

request获取请求数据;response设置响应数据

Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中

request获取请求数据:

  • 请求行:
    String getMethod():获取请求方式: GET
    String getContextPath():获取虚拟目录(项目访问路径): /request-demo
    StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
    String getRequestURI():获取URI(统一资源标识符): /request-demo/req1
    String getQueryString():获取请求参数(GET方式): username=zhangsan&password=123

  • 请求头:
    String getHeader(String name):根据请求头名称获取值

  • 请求体:
    ServletInputStream getInputStream():获取字节输入流
    BufferedReader getReader():获取字符输入流

GET请求和POST请求获取请求数据的区别:

  • GET请求通过使用getQueryString()方法获取请求参数
  • POST请求通过字符流或者字节流获取参数
    //1.获取字符输入流
    BufferedReader br = req.getReader();
    //2.读取数据
    String readLine = br.readLine();// username=zhangsan&password=123

Request通用方式获取请求参数:

Map<String, String[ ]> getParameterMap():获取所有参数Map集合 
String[ ] getParameterValues(String name) :根据名称获取参数值(数组)
String getParameter(String name):根据名称获取参数值(单个值)

POST请求方式解决中文乱码:

request.setCharacterEncoding("UTF-8");//设置字符输入流的编码

浏览器将请求参数进行URL编码,tomcat将请求参数默认按照ISO-8859-1进行解码:

String username = "张三";
//1.URL编码
String encode = URLEncoder.encode(username, "utf-8");
System.out.println(encode);//%E5%BC%A0%E4%B8%89

//2.URL解码
String decode = URLDecoder.decode(encode, "ISO-8859-1");
System.out.println(decode);//å¼ ä¸

无论怎么编码,得到的字节始终相同:

//3.转换为字节数据,解码
byte[] bytes = decode.getBytes("ISO-8859-1");

//4.将字节数组转为字符串,解码
String s = new String(bytes, "utf-8");
System.out.println(s);//张三

GET请求方式解决中文乱码:

username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

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

  • 实现方式:
    req.getRequestDispatcher(“/req”).forward(req, resp);

  • 请求转发资源间共享数据:使用Request对象
    void setAttribute(String name,Object o);
    Object getAttribute(String name);
    void removeAttribute(String name);

  • 特点:

    1. 浏览器地址栏路径不发生变化
    2. 只能转发到当前服务器的内部资源
    3. 一次请求,可以在转发的资源间使用request共享数据

Response设置响应数据:

  • 响应行:
    void setStatus(in code);//设置响应状态码

  • 响应头:
    void setHeader(String name,String value);//设置响应头键值对

  • 响应体:
    PrintWriter getWriter();//获取字符输出流
    ServletOutputStream getOutputStream();//获取字节输出流

Response重定向:一种资源跳转方式

  • 实现方式
    //重定向
    //1.设置响应状态码
    response.setStatus(302);
    //2.设置响应头 Location
    response.setHeader(“Location”,“/req2”);

    //简化方式
    response.sendRedirect("/req2");
    
  • 特点

    1. 浏览器地址栏发生变化
    2. 可以重定向到任意位置的资源(服务器内部、外部均可)
    3. 两次请求,不能在多个资源使用request共享数据

路径问题:

  • 浏览器使用:需要加载虚拟目录(/request-demo/req),如< a>、< form>、response重定向
  • 服务器使用:不需要加虚拟目录(/req),如请求转发
  • 动态获取虚拟目录:
    String contextPath = request.getContextPath();

Response设置响应字符数据

  • 使用Response对象获取字符输出流
    PrintWriter out = response.getWriter();
    //该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭

  • 写数据
    //中文数据乱码
    response.setContentType(“text/html;charset=utf-8”);
    out.writer(“aaa”);

Response设置响应字节数据(视频、音频、图片…)

	    //1、读取文件
        FileInputStream fis = new FileInputStream("d://a.png");
 
        //2、获取response 字节输出流
        ServletOutputStream os = response.getOutputStream();
 
        //3、完成流的copy
//        byte[] buff = new byte[1024];
//        int len = 0;
//        while((len = fis.read(buff)) != -1){
//            os.write(buff,0,len);
//        }
 
        //3、利用工具类进行copy
        IOUtils.copy(fis,os);
        fis.close();

SqlSessionFactory工具类提取:

  • 代码优化:

    1. 抽取工具类解决代码重复
    2. 对指定代码只需要执行一次的使用静态代码块
  • 工具类实现
    public class SqlSessionFactoryUtils {

        private static SqlSessionFactory sqlSessionFactory;
    
        static {
            //静态代码块会随着类的加载而自动执行,且只执行一次
            try {
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSessionFactory getSqlSessionFactory(){
            return sqlSessionFactory;
        }
    }
    

九、JSP

jsp是一种动态的网页技术,JSP=HTML+Java

作用:简化开发,避免在servlet中直接输出HTML标签

1.jsp原理

  • jsp本质上就是一个servlet
  • jsp在被访问时,由jsp容器(tomcat)将其转换为Java文件(servlet),再由jsp容器(tomcat)将其编译,最终对外提供服务的其实就是这个字节码文件

2.jsp脚本

  • 用于再jsp页面内定义的Java代码
  • 脚本分类
    1,<% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么
    2,<%!代码%>∶定义的java代码,在jsp转换后的java类的成员位置。
    3,<‰%=代码%>:定义的java代码,会输出到页面上。由out.print()输出

jsp缺点:

  1. 书写麻烦:特别是复杂的页面
  2. 阅读麻烦
  3. 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
  4. 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
  5. 调试困难:出错后,需要找到自动生成的.java文件进行调试
  6. 不利于团队协作:前端人员不会Java,后端人员不精HTML

替换jsp中的Java代码:EL表达式和JSTL标签

EL表达式:表达式语言,用于简化jsp页面的Java代码

  • 主要功能:获取数据
  • 语法:${expression}
	<dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>3.0.0</version>
    </dependency>

JavaWeb中的四大域对象:

  1. page:当前页面有效
  2. request:当前请求有效
  3. session:当前会话有效
  4. application:当前应用有效

JSTL:JSP标准标签库,使用标签取代JSP页面上的Java代码

依赖:

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
	<groupId>javax.servlet.jsp.jstl</groupId>
	<artifactId>jstl</artifactId>
	<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.web/jstl-impl -->
<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>jstl-impl</artifactId>
	<version>1.2</version>
</dependency>

常用标签:

<c:if test="${status == 1}">
	启用
</c:if>


<c:forEach items="${brands}" var="brand">
	<p>${brand.name}</p>
</c:forEach>
<c:forEach begin="0" end="10" step="1" var="i">
	<p>${i}</p>
</c:forEach>

MVC模式优点:

  • 职责单一,互不影响
  • 有利于分工合作
  • 有利于组件重用

十、会话跟踪技术

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应

会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便同一次会话的多次请求间共享数据

为什么需要会话跟踪技术:HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,所以需要会话跟踪技术来实现数据共享

实现方式:

  • 客户端会话跟踪技术:Cookie
  • 服务端会话跟踪技术:Session

1.Cookie

客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问

服务端发送cookie:

  • 创建Cookie对象,设置数据
    Cookie cookie = new Cookie(“key”,“value”);

  • 发送Cookie到客户端:使用response对象
    response.addCookie(cookie);

获取cookie:

  • 获取客户端携带的所有Cookie,使用request对象
    Cookie[] cookies = request.getCookies();

  • 遍历数组,获取每一个Cookie对象:for

  • 使用Cookie对象方法获取数据
    cookie.getName();
    cookie.getValue();

  • 在页面获取cookie数据
    ${cookie.key.value}//key指存储在cookie中键名称

原理:

  • Cookie的实现基于HTTP协议:第一次浏览器向服务器发送请求,服务器会设置一个cookie值响应给浏览器,第二次访问服务器时,请求头中会携带这个cookie值,进行会话跟踪
    1. 响应头:set-cookie
    2. 请求头:cookie

Cookie存活时间:

  • 默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被摧毁
  • setMaxAge(int seconds):设置cookie存活时间
    1. 正数:将cookie写入浏览器所在电脑的硬盘,持久化存储,到时间自动删除
    2. 负数:默认值,cookie在当前浏览器的内存中,当浏览器关闭,则cookie被摧毁
    3. 0:删除对应cookie

Cookie存储中文:

  • cookie不能直接存储中文
  • 如果需要存储,则需要进行转码:URL编码(URLEncoder,URLDecoder)

2.Session

将数据保存到服务器

JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能

使用:

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

  • Session对象功能
    void setAttribute(String var1, Object var2);
    Object getAttribute(String var1);
    void removeAttribute(String var1);

Session原理:

  • 基于cookie实现,set-cookie:JSESSIONID
  • 保证了一次会话的多次请求中间为同一个session

Session使用细节:

  • Session钝化、活化
    1. 钝化:在服务器正常关闭后,tomcat会自动将session数据写入硬盘的文件中
    2. 活化:再次启动服务器后,从文件中加载数据到session中
  • session销毁
    1. 默认情况下,无操作,30分钟自动销毁

      	<session-config>
             <session-timeout>30</session-timeout>
          </session-config>
      
    2. 调用session对象的invalidate()方法

3.小结

  • Cookie和Session都是来完成一次会话内多次请求间数据共享的
  • 区别:
    1. 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端
    2. 安全性: Cookie 不安全,Session安全
    3. 数据大小:Cookie最大3KB,Session无大小限制
    4. 存储时间:Cookie可以长期存储,Session默认30分钟
    5. 服务器性能:Cookie不占服务器资源,Session占用服务器资源
  • 应用场景:
    1. session:验证码,一般用于用户登录后的数据
    2. cookie:购物车、“记住我”,一般用于未登录情况下的身份识别

十一、Filter&Listener

1.Filter

Filter表示过滤器,可以对资源的请求拦截下来,从而实现一些特殊的功能:权限控制、统一编码处理、敏感字符处理等

快速入门:

  • 定义类,实现Filter接口,并重写其所有方法:

    public class FilterDemo implements Filter {
              @Override
              public void init(FilterConfig filterConfig) throws ServletException {}
          
              @Override
              public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}
          
              @Override
              public void destroy() {}
          }
    
  • 配置Filter拦截资源的路径:在类上定义@WebFilter注解
    @WebFilter(“/*”)
    public class FilterDemo implements Filter {}

  • 在doFilter方法中进行处理,并放行

    	 @Override
         public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         	//1.放行前,对request数据进行处理
             System.out.println("filterdemo1...");
             //放行
             filterChain.doFilter(servletRequest, servletResponse);
             //2.放行后,对response数据进行处理
             System.out.println("filterdemo3...");
         }
    

Filter执行流程:执行放行前逻辑——放行——访问资源——执行放行后逻辑

Filter拦截路径配置:

  • 具体资源路径拦截:@WebFilter(“/index.jsp”) // 访问index.jsp的时候会经过过滤器
  • 具体目录拦截:@WebFilter(“/user/*”) // 访问user目录下的所有资源时会经过过滤器
  • 具体后缀名拦截:@WebFilter(“*.jsp”) // 访问后缀名为.jsp的资源时会经过过滤器
  • 所有资源拦截:@WebFilter(“/*”) // 访问所有资源的时候都会经过过滤器

过滤器链:配置多个过滤器

  • 如果是注解方式,顺序是由过滤器名字进行升序排序来决定,比如先过滤 filter1再过滤 filter2

案例-登录过滤

@WebFilter("/*")
public class LoginFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {}

    public void destroy() {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest req = (HttpServletRequest) request;
        //判断访问资源的路径是否和登录注册相关
        String[] urls = {"/login.jsp", "/imgs", "/css", "/loginServlet", "/register.jsp", "/registerServlet", "/checkCodeServlet"};
        //获取当前访问的资源路径
        String url = req.getRequestURL().toString();
        //循环判断
        for (String u : urls) {
            if (url.contains(u)) {
                chain.doFilter(request, response);
                return;
            }
        }
        //1.判断session中是否有user
        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");

        //2.判断user是否为空
        if (user != null) {
            chain.doFilter(request, response);
        } else {
            //没有登录
            req.setAttribute("login_msg", "您尚未登录");
            req.getRequestDispatcher("login.jsp").forward(req, response);
        }
    }
}

2.Listener

listener表示监听器,可以监听在application、session和request三个对象的创建、销毁或往其中添加修改删除属性时自动执行代码的功能组件

十二、AJAX

Ajax是异步的JavaScript和XML

Ajax作用:

  • 与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据
    1. 使用Ajax和服务器进行通信,可以使用Ajax+HTML来替换JSP
  • 异步交互:在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如搜索联想、用户名是否可用校验、…

Ajax快速入门:

  • 编写AjaxServlet
  • 创建XMLHttpRequest对象
  • 向服务器发送请求
  • 获取服务器响应数据
   <script>
       //1.创建核心对象
       var xhttp;
       if (window.XMLHttpRequest) {
           xhttp = new XMLHttpRequest();
       } else {
           // code for IE6, IE5
           xhttp = new ActiveXObject("Microsoft.XMLHTTP");
       }
       //2.发送请求
       xhttp.open("GET", "http://localhost:8080/ajaxServlet");
       xhttp.send();
       //3.获取响应
       xhttp.onreadystatechange = function () {
           if (this.readyState == 4 && this.status == 200) {
               alert(this.responseText);
           }
       };
   </script>

Axios:通过promise实现对ajax技术的一种封装

快速入门:

//1.get
axios({
    method: 'get',
    url: "http://localhost:8080/axiosServlet?username=lisi"
}).then(function (resp) {
    alert(resp.data);
})

//2.post
axios({
    method: 'post',
    url: "http://localhost:8080/axiosServlet",
    data:"username=lisi"
}).then(function (resp) {
    alert(resp.data);
})

为了 简化 开发者的 使用过程 ,axios 为所有支持的 请求方法 提供了别名 :

⚫ axios. get (url[, config])

⚫ axios. delete (url[, config])

⚫ axios. post (url[, data[, config]])

⚫ axios. put (url[, data[, config]])

⚫ axios. patch (url[, data[, config]])

axios.get("http://localhost:8080/axiosServlet?username=lisi").then(function (resp) {
    alert(resp.data);
})

axios.get("http://localhost:8080/axiosServlet", "username=lisi").then(function (resp) {
    alert(resp.data);
})

JSON:JavaScript对象表示法,作为数据载体,在网络中进行数据传递

  • 基础语法
    //定义json
    var json = {
    “name”: “lisi”,
    “age”: 22,
    “addr”: [“北京”, “上海”]
    }
    //获取值
    alert(json.name)

  • JSON数据和Java对象转换

    1. 请求数据:JSON字符串转为Java对象
    2. 响应数据:Java对象转为JSON字符串

Fastjson:

  • 导入坐标

     	<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
    
  • Java对象转JSON
    String myJSON = JSON.toJSONString(myObj);

  • JSON字符串转Java对象
    User user = JSON.parseObject(jsonStr,User.class);

十三、Vue

  • vue是一套前端框架,免除原生JavaScript的DOM操作,简化书写

  • 基于MVVM思想,实现数据的双向绑定

快速入门:

  • 新建html页面,引入vue.js文件
    < script src=“js/vue.min.js”></ script>

  • 在js代码区域,创建vue核心对象,进行数据绑定

      <script>
          //1.创建vue核心对象
          new Vue({
              el: "#app",
              data() {
                  return {
                      username: ""
                  }
              }
          })
      </script>
    
  • 编写视图

     <div id="app">
         <input v-model="username">{{username}}
     </div>
    

常用指令:

指令作用
v-bind为HTML标签绑定属性值,如设置href,css样式等
v-model为表单元素上创建双向数据绑定
v-on为HTML标签绑定事件
v-if、v-else-if、v-else条件性的渲染某元素,判定为true时渲染,否则不渲染
v-show根据条件展示某元素,区别在于切换的是display属性的值
v-for列表渲染,遍历容器的元素或者对象的属性

v-bind:href = :href

v-on:click = @click

v-if和v-show的区别:渲染方式不同

  • v-if:条件为true时渲染
  • v-show:页面已经存在该标签,通过display属性进行显示或隐藏

vue生命周期:

  1. beforeCreate(创建前)
  2. created (创建后)
  3. beforeMount (载入前)
  4. mounted (挂载完成):vue初始化成功,HTML页面渲染成功,可以发送异步请求,加载数据
  5. beforeUpdate (更新前)
  6. updated (更新后)
  7. beforeDestroy( 销毁前)
  8. destroyed (销毁后)

查询案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/axios.min.js"></script>
    <script src="js/vue.min.js"></script>
</head>
<body>
<div id="app">
    <div align="center" style="padding: 20px;font-size: 25px">图书列表</div>
    <table id="bookTable">
        <tr>
            <th>序号</th>
            <th>书名</th>
            <th>作者</th>
            <th>价格</th>
            <th>操作</th>
        </tr>
        <!--v-for遍历-->
        <tr v-for="(book,i) in books">
            <td>{{i + 1}}</td>
            <td>{{book.name}}</td>
            <td>{{book.author}}</td>
            <td>{{book.price}}</td>
            <td><a href="">修改</a>&nbsp;<a href="">删除</a></td>
        </tr>
    </table>
</div>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                books: []
            }
        },
        mounted() {
            var _this = this;//作用域不同
            axios({
                method: "get",
                url: "http://localhost:8080/selectAllBooksServlet"
            }).then(function (resp) {
                _this.books = resp.data;
            })
        }
    })
</script>
</body>
</html>

十四、Element

提供一套基于vue的网站组件库,用于快速构建网页

快速入门:

  • 引入element的css、js文件和vue.js
   <script src="js/vue.min.js"></script>
   <!-- 引入组件库 -->
   <script src="element-ui/lib/index.js"></script>
   <!-- 引入样式 -->
   <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
  • 创建vue核心对象
	<script>
        new Vue({
            el: "#app"
        })
    </script>
  • 官网复制element组件代码

布局:

  • Layout布局:通过基础的24分栏,迅速简便地创建布局
<el-row>
  <el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
</el-row>
<el-row>
  <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="12"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
<el-row>
  <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="8"><div class="grid-content bg-purple-light"></div></el-col>
  <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
</el-row>
<el-row>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
<el-row>
  <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
  • Container容器:用于布局的容器组件,方便快速搭建页面的基础结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/148561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【进阶C语言】字符串函数+内存函数

文章目录一.字符串函数1.strlen功能&#xff1a;求字符串长度&#xff08;不包括\0&#xff09;函数模拟实现&#xff1a;2.1 strcmp功能函数模拟实现2.2 strncmp3.1 strcat功能函数模拟实现3.2strncat4.1 strcpy功能函数模拟实现4.2 strncpy5.strstr功能函数模拟实现6.strtok功…

论文《An Effective Consistency Constraint for Sequential Recommendation》

C2Rec: An Effective Consistency Constraint for SequentialRecommendation 这篇文章提出了序列推荐建模中一种有效的一致性约束防范&#xff0c;不用修改模型结构&#xff0c;仅仅添加2个额外的损失函数&#xff0c;就能达到非常好的效果。不像基于对比学习的方法&#xff0…

C++初阶--string

目录 string对象的创建&#xff1a; 遍历修改 const修饰的迭代器(只读)&#xff1a; 反向迭代器&#xff1a; reserve与resize&#xff1a; find&#xff0c;rfind&#xff0c;substr&#xff1a; insert&#xff1a; erase&#xff1a; getchar、getline&#xff1a; string对…

Java基础学习笔记(十一)—— 包装类与泛型

包装类与泛型1 包装类1.1 基本类型包装类1.2 Integer类1.3 自动装箱 / 拆箱2 泛型2.1 泛型概述2.2 泛型的用法2.3 类型通配符1 包装类 1.1 基本类型包装类 基本类型包装类的作用 将基本数据类型封装成对象 的好处在于可以在对象中定义更多的功能方法操作该数据 public stat…

✿✿✿JavaScript --- Ajax异步请求与JSONP 跨域请求

目 录 一、原生的Ajax请求 1.异步和同步 2.Ajax介绍 3.实现方式 (1)原生的JS实现方式&#xff08;了解&#xff09; (2)原生AJax发送Post请求&#xff0c;并携带请求参数 二、JQuery封装后的Ajax 1.JQeury实现方式 2. $.get()&#xff1a;发送get请求 3.$.post()&…

存储随笔2022年度最受欢迎文章榜单TOP15

回首2022感谢各位粉丝朋友的一路支持与陪伴存储随笔为您献上2022年度最受欢迎文章榜单TOP152023&#xff0c;一起向未来&#xff01;TOP1&#xff1a;固态硬盘SSD入门级白皮书主要从固态硬盘的原理/接口形态/寿命/使用场景/等不同角度&#xff0c;来对比不同的人群需要什么样的…

[linux]vim编辑器

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要讲解vim的使用和一些vim的常用操作&#xff0c;以及如何解决…

Flow 转 LiveData 后数据丢了,肿么回事?

翻译自&#xff1a; https://arkadiuszchmura.com/posts/be-careful-when-converting-flow-to-livedata/ 前言 最近我在负责一段代码库&#xff0c;需要在使用 Flow 的 Data 层和仍然依赖 LiveData 暴露 State 数据的 UI 层之间实现桥接。好在 androidx.lifecycle 框架已经提供…

C语言-指针进阶-函数指针数组应用-计算器(9.2)

目录 1. 函数指针 2. 函数指针数组 2.1函数指针数组的定义 2.2函数指针数组应用 3. 指向函数指针数组的指针 思维导图&#xff1a; 1. 函数指针 直接上代码&#xff1a; #include <stdio.h>void test() {printf("hehe\n"); }int main() {printf("%…

【Java】数组的复制、反转、查找、排序

数组的复制、反转、查找、排序 复制 其中最关键的一点是搞清楚为什么数组复制和基本数据类型复制不同&#xff0c;是什么导致了这样的不同&#xff1f; 先来看例子 package com.atguigu.java;public class ArrayTest3 {public static void main(String[] args) {//新建arr数…

【Java数据结构与算法】Day2-高级排序(希尔、归并、快速、计数)

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Java数据结构与算法】 &#…

实验七:555定时器及其应用

答疑解惑用555定时器组成的单稳态电路中&#xff0c;若触发脉冲宽度大于单稳态持续时间&#xff0c;电路能否正常工作&#xff1f;如果不能&#xff0c;则电路应做如何修改&#xff1f;答:若触发脉冲宽度大于单稳态持续时间后&#xff0c;输出脉冲宽度将等于触发脉冲的低电平持…

【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格

【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格 &#x1f345;因发布平台差异导致阅读体验不同&#xff0c;将本文原编写地址贴出&#x1f339;&#xff1a;《【精】EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格》 文章目录【精】EditorConfig 小老鼠…

实时数仓方案

2、实时数仓方案 2.1、为何需要实时数仓架构 随着数据量的增大&#xff0c;传统数据的方案在时效性上和数据维护上变得越来越困难。实时数仓架构应运而生。 具体方案落地上实时数仓有很多方案可以选择&#xff0c;不同的业务和应用场景到底应该选择哪种技术方案&#xff1f;…

React18新特性

React 团队在 2022 年 3 月 29 日正式发布了 React 的第 18 个版本。 在这篇文章里简单介绍 React 18 的新特性&#xff0c;React Concurrent Mode&#xff08;并发模式&#xff09;的实现&#xff0c;以及简要的升级指南。 New Features Automatic Batching 早在 React 18 之…

011-Ensp-实验-配置ACL

实验要求 1.通过ACL 使PC1无法访问PC3 实验结构 实验步骤 基础环境配置: PC间互通 1. PC1 2 3 配置IP网关 2. LSW2 创建三个vlan &#xff0c;g0/0/2 g0/0/3 g/0/04 类型配置为Access 分别加入三个vlan g0/0/1 配置为trunk 并允许所有vlan通过 3. LSW1 g0/0/1 配置trunk …

vector底层实现及深层次拷贝问题

目录 大框架 接口实现 深层次拷贝问题&#xff08;两次深拷贝&#xff09; 大框架 为了与库里实现的更接近一些&#xff0c;先来看一下STL中是如何实现vector的&#xff08;这里不是PJ版&#xff0c;PJ版稍微晦涩一点不容易理解&#xff0c;这里采用Linux下g的版本&#xf…

VectorNet: Encoding HD Maps and Agent Dynamics from Vectorized Representation

Paper name VectorNet: Encoding HD Maps and Agent Dynamics from Vectorized Representation Paper Reading Note URL: https://arxiv.org/pdf/2005.04259.pdf TL;DR waymo 出品的 CVPR2020 论文 &#xff0c;关注在自动驾驶场景&#xff08;复杂多智能体系统&#xff0…

【算法自由之路】快慢指针在链表中的妙用(下篇)

【算法自由之路】快慢指针在链表中的妙用&#xff08;下篇&#xff09; 继上篇之后&#xff0c;链表这块还有两个相对较难的问题我们继续举例。 问题 1 给定具有 random 指针的 next 方向无环单链表&#xff0c;复制该链表 单听这个问题可能有点懵&#xff0c;这个链表结构我…

PCB封装创建(CHIP类)

PCB封装要有以下内容 PCB焊盘管脚序号丝印阻焊1脚标识目录 CHIP类&#xff08;电阻 电容 电感 三极管&#xff09; 0805C 0805R 0805L SOT-23 1.CHIP类&#xff08;电阻 电容 电感 三极管&#xff09; 1.新建一个PCB元件库 打开PCB Library 以下以0805为例。 创建080…