JavaWeb学习

目录

一、路线

前端

web核心

二、数据库

1、事务

(1)事务简单理解:

(2)事务的四大特征:原子性、一致性、隔离性、持久性

三、JDBC

1、概念​编辑

2、深入理解JDBC

3、JDBC使用步骤

(1)导入jar包

(2)编写代码

4、 JDBC的API详解

5、数据库连接池

(1)Driud使用步骤(性能优秀的数据库连接池)

6、JDBC练习

(1)准备环境:

(2)测试用例

(3)测试用例总代码:


本文章根据黑马程序员陈老师Javaweb教程所作学习总结

一、路线

1、数据库Mysql

2、JDBC

3、maven

4、Mybatis

前端

5、HTML+CSS

6、javascript

7、ajax+vue+elementul

web核心

8、tomcat+http+servlet

9、request+response

10、jsp

11、cookie+session

12、filter+listener

b3c5be7a0128473fb2c15c67bf9c7c98.png

二、数据库

1、事务

  • 事务是一种机制、一个操作序列,包含了一组数据库操作命令
  • 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失效
  • 事务是一个不可分割的工作逻辑单元

 

(1)事务简单理解:

        张三给李四借了500块钱,现在李四要还给张三。本身两人账户都有1000元,李四给张三转账500元,最后张三有1500元,李四500元,这个转账操作要经历以下三个步骤:

①查询李四账号余额

②李四账号金额-500

③张三账号金额+500

        但是为了避免出现李四金额减少,张三金额没有增加的情况出现,所以要将这个转账操作作为一个整体,要么同时成功,要么同时失败。这个时候在转账操作前开启事务(START TRANSACTION;或者 BEGIN),中途如果出现异常则回滚事务(POLLBACK;),没有异常就提交事务(ROLLBACK;)

d928c5519ebc44b7ac5d1c2ee953f02f.png

 

(2)事务的四大特征:原子性、一致性、隔离性、持久性

0bc4ce10274a4a07917c25395e425abc.png

 

三、JDBC

1、概念b1d09d982d304c9dbfe3ac1f73d4a695.png

2、深入理解JDBC

39ca778e5e45493d825b606208c17f89.png

 

3、JDBC使用步骤

 51b4c30369734b5ebf60486d88370b8e.png

(1)导入jar包

创建一个空项目(项目结构中配置jdk和对应的编译版本、创建Java模块modules)->导入驱动jar包放入新建的目录lib里面(jar包下载网址:​​​​​​MySQL :: Download MySQL Connector/J (Archived Versions) )->让当前工程识别jar包(add as library -> modules library),如果不识别的话,后面无法完成驱动的注册。

(2)编写代码

b52fb9e464dd4a629a6fd7cb11fd16d0.png

 

4、 JDBC的API详解

参考博客

5、数据库连接池

df8e5a9b5b7940e4a32cc088cb0cbb77.png

 

(1)Driud使用步骤(性能优秀的数据库连接池)

 ①导入jar包(driud jar包)

下载jar包并导入进idea,跟jdbc的jar包一样的操作

②定义配置文件

        配置properties文件

        30a70b3277744d5a91a2a4d53d905a24.png

③加载配置文件

        加载配置时可以有以下两种方法:

51f77dbeba9a4f4e813b5dc54c0363ba.png

        如果出现【系统找不到指定文件】错误时,可以直接右键点击properties文件复制路径,解决          问题来源:http://t.csdn.cn/AWv89;

        如果出现【url not set】错误时,则是加载配置文件代码没有弄全,可能是缺少load()方法;或者是连接池版本过低;

④获取数据库连接池对象

⑤获取连接

 

6、JDBC练习

(1)准备环境:

①创建数据库表tb_brand

677871312fa047ef9a4314395a236675.png

②编写实体类Brand

  • 写出成员变量(数据库表中的属性)
  • IDEA中使用快捷键 Alt + Insert 快捷方式生成get/set方法和toString方法

9948f161a7e74564bfa675ef807258a2.png

 

(2)测试用例

①查询所有数据

d8a66945262b4d5799bc048c6dc435dd.png

②第6步封装数据,将结果装载到list集合中,最后输出list集合

dc8cdeba974d4f23909988a7104bdf39.png

③添加、修改、删除数据

        举一反三,跟查询的区别就是需要参数,返回boolean类型

 

(3)测试用例总代码:

aad33b7ca4a2478580224bcf39c8e7d0.png

df2c13e8aaea40c4aa8097d56c8b93f2.png  9ee5de0605b2461fad4c8c03dd64c59c.png

 

四、Maven

1、Maven简介

        maven本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型。提供标准的、跨平台的自动化项目构建方式;方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题;提供标准的、统一的项目结构,使得在各个编程软件上正常运行。

 

2、Maven本身构造及其统一的项目开发目录结构

1c4cfe2d3eae42c8843f835fb44c203c.jpeg

4f91d702ba2e4bf7b6c39d8103da5b72.jpeg

        src文件里面有main和test两个文件,其中main是用来写程序的,test是用来写测试程序的。在main和test文件中各有java和resources两个文件,其中java是写Java源程序的,resources是用于写配置文件的 

 

3、Maven下载与安装

(1)下载地址:

5290da8de1fb42b5a83804e6a0279b8f.jpeg

 (2)配置环境变量

2550dce003044aebb24572aded4bd07d.jpeg

 (3)用MVN命令检验是否配置好

50940279c5da4dfe9db7146007667b68.png

 

4、配置国内源

        博客搜索方法

5、Maven功能

  • 提供了一套标准化的项目结构
  • 提供了一套标准化的构建流程(编译、测试、打包、发布.....)
  • 提供了一套依赖管理机制     

   依赖管理其实就是管理你项目所依赖的第三方资源(jar包、插件...)

        ①Maven使用标准的坐标配置来管理各种依赖

        ②只需要简单的配置就可以完成依赖

 

6、IDEA配置Maven

(1)IDEA配置Maven环境

①在IDEA中创建一个空项目

②按照以下步骤进行配置

08763fe232cc4d9f98d88f8a48ba1a9a.png

(2)Maven坐标详解

bf72ddebc230441dbe1d8057710f45e7.png

(3)IDEA创建Maven项目

2624ec8f419a46ce97cbd66d70860747.png

(4)IDEA导入Maven项目

d28d84a6963d495cb7416d0bcc44c69c.png

        

(5) 配置Maven — Helper插件

插件的作用:

①鼠标右键点击项目名称,可以直接点击Run Maven进行编译、测试、打包等操作,就不用去另外点击右边的maven

②最方便的是,鼠标右键点击项目名称,点击Debug Maven进行断点调试

a91996c418b9431297e1623eec1e8d8f.png

 

7、依赖管理

(1)使用坐标导入jar包(加注释快捷键:CTRL + /)

9c25d658f96849cb94b52eab6b04adf0.png

 (2)依赖范围

b16a9b6808be4ab9829b28352f81938e.png

 

五、MyBatis

1、MyBatis简介

b287fed7eb4a42fa96c2ff7fa4df3c8a.png

 921fb3ddb7794898a68b35de7c125798.png

 

2、MyBatis快速入门

查询user表中的所有数据:

4bf3922a3e0a4079a924a4f3378d212c.png

bec048c36117480ea8ee796a92cd4219.png

 

 (1)创建user表,添加数据

b5c2f62804194d678bd1dc61a90a5879.png

(2)创建模块,导入坐标

        1.坐标的导入(在pom.xml文件中导入mybatis依赖、mysql驱动、junit单元测试等坐标)

        可以在网上查mybatis的坐标,也可以登录官网直接复制(mybatis – MyBatis 3 | 入门),下面mybatis核心配置文件和sql映射文件的代码也在这个里面可以找到。

        问题及解决:在新创建的项目中,里面的maven可能是默认的配置(不是自身配置了国内源的maven,所以会出现下载依赖速度缓慢的问题。这个时候可以根据我们前面在maven在idea中的配置内容中学习到的知识,点击settings...中的maven界面,将其中的maven文件地址改为自身设置过的地址,setting.xml也改为自己的.xml地址,从而解决问题)

        2.具体代码

<dependencies>
        <!--mybatis的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.13</version>
        </dependency>

        <!--mysql 的驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>

        <!--junit 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!--添加slf4j日志api-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.5</version>
        </dependency>

        <!--添加logback—classic依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.6</version>
        </dependency>

        <!--添加logback-core依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.4.6</version>
        </dependency>


    </dependencies>

 

(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>
    <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:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="lmq15*******17"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--
    加载SQL的映射文件
    UserMapper.xml表示数据库映射文件地址
-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

 

(4)编写SQL映射文件(UserMapper.xml文件)

1659649e9b544887bca1b44efdf2bbd0.png

 

(5)编码

  1. 定义POJO类

2d018e73852642b28333da006336255f.png

  1. 加载核心配置文件,配置SqlSessionFactory对象
  2. 获取SqlSessionFactory对象,执行SQL语句
  3. 释放资源
public class MybatisDemo {
    public static void main(String[] args) throws IOException {
        // 加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 执行sql,test.selectAll表示这个sql语句的唯一标识,这个根据UserMapper.xml映射文件中的找到
        List<User> users = sqlSession.selectList("test.selectAll");

        System.out.println(users);

        // 释放资源
        sqlSession.close();
    }
}

 

3、Mapper代理开发

a311469159c941369bcd3620d9d2e945.png

 (1)遵守三大规则

        1.定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一个目录下

        defa2efd8cea4aadac38929ab143340b.png

        怎么放到同一目录下?直接将映射文件拖到mapper目录下吗?不行!因为在Maven项目编写过程中,.xml配置文件应该放到resources文件里面。

        正确做法:在resources下再创建一个跟UserMapper接口一样的目录,注意!在resources里创建目录是应该用com/itheima/mapper,中间应该用 “/” 而不是 “.”,不然无法创建成功。 

        27e0b990ebd94c04a58a0cee65ade1bc.png

        细节:此时映射文件地址已经改变,前面提起的mybatis核心配置文件里面的映射文件地址也要相应的改变

        e9c533b4261f4f668f92160868025e62.png

 

        2.设置SQL映射文件的namespace属性(空间名称)为Mapper接口全限定名

        解释:在前面,映射文件里面的namespace我们是随便写的一个名称,但是现在要将其改为UserMapper接口的全限定名

        b05d3f97b0314ffa911c4b668b915b66.png

 

        3.在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

        Mapper接口代码:

package com.itheima.mapper;

import com.itheima.pojo.User;

import java.util.List;

// 这里是UserMapper接口,所以要用接口的关键词interface
public interface UserMapper {
    /* 根据映射文件里面的SQL语句来判断,如果要返回多个集合就用集合List<>
       如果只返回一个,则使用User对象
     */
    List<User> selectAll();
}

        UserMapper映射文件代码:

3e82540bde1748bf96da240955f308a5.png

 

(2)编码

        1.通过SqlSwssion的getMapper方法获取Mapper接口的代理对象

        2.调用对应方法完成sql的执行

        代码:

package com.itheima;

import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/*
Mybatis 的代理开发
 */

public class MybatisDemo2 {
    public static void main(String[] args) throws IOException {
        // 加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 执行sql,test.selectAll表示这个sql语句的唯一标识,这个根据UserMapper.xml映射文件中的找到
        // List<User> users = sqlSession.selectList("test.selectAll");

        // 获取UserMapper接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        System.out.println(users);

        // 释放资源
        sqlSession.close();
    }
}

        细节:在mybatis核心配置文件中如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载

        原本写法:

5ba97953028143d4a85c9257c7ffa7cc.png

         缺点:如果有多个SQL映射文件,还需要一个一个去复制映射文件的地址并添加到mybatis的核心配置文件中,过于繁琐

        改进后:

75355fa05f2c4b91a669c8c2082b6cc6.png

         改进后,会自己直接扫描对应目录下的mapper接口,就不用一个一个的去复制映射文件地址,直接全部加载

 

4、MyBatis核心配置文件

在官网文档可以查看学习(mybatis – MyBatis 3 | 配置

5、配置文件完成增删改查

(1)准备环境

  • 数据库表tb_brand
  • 实体类Brand
  • 测试用例

        e8a88fc1102c42328bb22254aae7e895.png

  • 安装MyBatisX插件

        b381baa13a724d0fbb366ac8b584d2db.png

 (2)查询所有

        2d7326e54c5d498ca0957c9171865275.png

        代码:

package com.itheima.test;

import com.itheima.mapper.BrandMapper;
import com.itheima.pojo.Brand;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisTest {
    @Test
    public void testSelectAll() throws IOException {
        // 1.获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3.获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        // 4.执行方法
        List<Brand> brands = brandMapper.selectAll();
        System.out.println(brands);

        // 5.释放资源
        sqlSession.close();
    }
}

        出现的错误:因为数据库表(tb_brand)的字段名称 和 实体类(Brand)的属性名称不一致,则不能自动封装数据

        070817448d494933a8df95453ae4ad30.png

         解决办法:在映射文件中可以采用起别名(但是每次查询都要定义一次别名)、sql片段(但是不灵活)解决,

        根据最优解决办法,采用resultMap的解决办法解决

        3bbe4291b0b442e980fc5c77b4a3eae1.png

        resultMap:

        8db32612ec684a37bfe638cfa504d536.png

 

         改良后的BrandMapper.xml映射文件:

        66c1a02003ba43d88238686143127d8b.png

(3)查询详情

        大体步骤跟前面【查询所有】基本一样,改动点是以下几点:

        映射文件中的SQL语句改变(相应的接口也要修改、测试文件里面重新定义方法并添加了参数)

        1d4b07cd1b0e4c64b1e422ed44c1f083.png        

         红框里表示参数占位符

        c9b7f26eb9094c5bba8b040cfcc2c1d5.png

 总的代码:

public class MyBatisTest {
    /*
    查询所有
     */
    @Test
    public void testSelectAll() throws IOException {
        // 1.获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3.获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        // 4.执行方法
        List<Brand> brands = brandMapper.selectAll();
        System.out.println(brands);

        // 5.释放资源
        sqlSession.close();
    }

    /*
    查询详情
     */
    @Test
    public void testSelectById() throws IOException {
        // 定义一个参数
        int id = 1;
        // 1.获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3.获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        // 4.执行方法
        Brand brand = brandMapper.selectById(id);
        System.out.println(brand);

        // 5.释放资源
        sqlSession.close();
    }

    /*
    条件查询
     */
    @Test
    public void testSelectByCondition() throws IOException {
        // 定义一个参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";

        //处理参数,这里要注意,模糊查询要相应的处理一下参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";

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

        // 2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3.获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        // 4.执行方法
        List<Brand> brands = brandMapper.selectByConditon(status, companyName, brandName);
        System.out.println(brands);

        // 5.释放资源
        sqlSession.close();
    }
}

 

6、动态SQL(SQL映射文件里面操作)

(1)多条件动态查询

04f76c50d5354e9397c2b6caa33e2b0b.png

 

325911ea266349e48b8d421e638f53e3.png

         当我不想查询第一条,想查询第一条之后的,但是像上面这样写就会报错,因为and直接接到where命令后面的,SQL语法错误,该怎么办?

        解决1:采用恒等式

        9931e48c37de40c3a2222a57ca706b42.png

        解决2:使用<where><where>标签替换where关键字

        a5340ebeb4224fd4b26819dfd4e1e77b.png

 

(2)单条件动态查询

 

7b92ee29ab6741fb99576abca84a004e.png

 

7、注解完成增删改查

 

六、HTML(官方教程w3school 在线教程

1、HTML简介

4bf9d1d95a8d4aa28c91935e06821c62.png

2、HTML快速入门

(1)新建文本文件,后缀名改为.html 

(2)编写HTML结构标签

(3)在<body>中定义文字

        79894a585ba24325b382dc0a529326aa.png

        e2b739bd7d8c4e948f283240a4ab1ece.png

         head表示头,加载一些资源信息和展示title标题;body表示体,浏览器正文要显示的内容就写在这个里面

0d168efb6344486396bb78f85ac83c64.png

<font color="blue"> 正文 </font>,标签可以修改正文的属性

 

 

 

3、基础标签(可以自己在网页上选中检查来查看网页所用的标签)

664df6f453d2485096140e1d1a6f0013.png

(1) 代码:

<!--html5 的版本表示-->
<!DOCTYPE html>
<html lang="en">
<head>
    <!--当前页面的字符集-->
    <meta charset="UTF-8">
    <title>小小修士修炼空间</title>
</head>
<body>
<center>
    <h1> 欢迎来到小小修士修炼场地</h1>
</center>

<hr>
<font color="blue">
    <h3> 该修士目前修为: 练气期</h3>
</font>

<p>
    修炼中~
</p>
<p>
    静心修炼三小时,<font color="red"><b>经验+20</b></font>;此时小小修士觉得肚子有一点儿饿了,果然在练气层还是无法做到不食五谷。于是小小修士决定再修炼一会儿后就去吃饭,然后散散心,毕竟一直修炼也怕走火入魔
</p>
</body>
</html>

(2)运行效果:

        c59f3470bdac4e7b8737a9bcb5bb0a5c.png

 

4、图片、音频、视频标签

dfa58ac7604f44178537986349e1e7d3.png

 

cf533ac8620b4a7bad2f54b8e300241b.png

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>小小修士的日常空间</title>
</head>
<body>
<!--
    src: 表示文件的路径
    ./退回的上一级
    .//退回到上一级的上一级
    例如在这个文件中 ./会退回到html文件这一级,../会退回到html2_demo文件这一级
    根据此文件目录来看,如果是同一目录则直接 ./a.jpg或者a.jpg
    如果是上一级目录则 ./img/a.jpg
    如果还在上一目录则 ../img/a.jpg
-->
<img src="../img/a.jpg" width="500" height="550">
<!--
    音频标签
    controls 表示属性,例如 宽度长度等
    -->
<audio src="" controls></audio>
<!--
    视频标签
    controls 表示属性
-->
<video src="" controls></video>

</body>
</html>

5、超链接标签

5ab4613983e6448a83bfd8feabe6623f.png

 

6、列表标签

06b2a5cb877240d9b852eb8b4b40a996.png

 

7、表格标签

2634ebce14ad40ae97eeaf77f8139920.png

 

8、布局标签

3f8ca0d6568442acabe31fcbe609cb01.png

 

9、表单标签

(1)定义:

2a987127cb0c4945b2f13d08b1af194d.png

94df3e9760134e63a72e4ff8524cac3a.png

 注意:

在<form>标签定义的表单中 method属性有以下注意点:

 

method:指定表单提交的方式
    1.get:默认值
        *请求参数出现在请求行当中
        *请求参数(name属性名=输入数据值的键值对)会拼接在url后边
        *rul的长度有限制 4kb
    2.post:
        *请求参数会隐藏在http请求协议的请求体中
        *请求参数无限制

(2)实现代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>小小修士的修炼空间</title>
</head>
<body>

<!--
form:
    action:指定表单数据提交的URL,将数据提交到指定的服务端数据库路径中去(目前没有指定服务端,所以用#代替,它表示将数据提交到当前html页面里面)
        *表单项数据要想被提交,必须指定其name属性

    method:指定表单提交的方式
        1.get:默认值
            *请求参数(name属性名=输入数据值的键值对)会拼接在url后边
            *rul的长度有限制 4kb
        2.post:
            *请求参数会隐藏在http请求协议的请求体中
            *请求参数无限制
-->
<center>
    <font color="blue">
        <h1>
            &emsp;&emsp;
            修士信息注册页面
        </h1>
    </font>
</center>
<hr>
<br>
<br>
<br>
<center>
    <form action="#" method="post">
        <!--
        &emsp; 表示全角空格
        &ensp; 表示半角空格
        -->
        <!--input 定义表达项,通过type属性控制输入形式-->
        <!--
        定义文本输入框
            通过label标签将【姓名:】与文本框连接起来,让用户可以通过点击属性名来输入文本框内容
                *label中的for属性必须要跟input中的id属性对应起来,这样才能连接
        -->

        <p>
        &emsp;&emsp;&emsp;&emsp;&emsp;<label for="username">姓名:</label>
        <input type="text" name="username" id="username">
        <br>
        </p>

        <!--定义密码字段-->
        <p>
        &emsp;&emsp;&emsp;&emsp;&emsp;<label for="userId">密码:</label>
        <input type="password" name="password" id="userId">
        <br>
        </p>

        <!--定义下拉列表-->
        <p>
        &emsp;&ensp;何地开始修行:
        <select name="address">
            <option value="重庆">重庆</option>
            <option value="成都">成都</option>
            <option value="北京">北京</option>
            <option value="上海">上海</option>
            <option value="杭州">杭州</option>
        </select>
        <br>
        </p>

        <!--定义文件上传按钮-->
        <p>
        &ensp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&ensp;
        头像上传:
        <input type="file">
        <br>
        </p>

        <!--
        定义单选按钮
            *如果要将两个单选内容绑定在一起(互斥),则将他们的name属性要命名一致
            *如果没有使用value属性,则单选内容传送到服务端的数据不会变化,value属性定义的什么内容,则选这个单选时传送的就是什么内容
        -->
        <p>
        性别:
        <input type="radio" name="gender" value="男" id="male">
        <label for="male">男</label>

        <input type="radio" name="gender" value="女" id="female">
        <label for="female">女</label>
        <br>
        </p>

        <!--
        定义复选框内容
            *如果要将选项内容绑定在一起,则将他们的name属性要命名一致
        -->
        <p>
        &ensp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; &emsp;&emsp;&emsp;&emsp;
        修仙杂艺:
        <input type="checkbox" name="hobby" value="炼丹">炼丹
        <input type="checkbox" name="hobby" value="炼器">练气
        <input type="checkbox" name="hobby" value="阵法">阵法
        <input type="checkbox" name="hobby" value="制符">制符
        <input type="checkbox" name="hobby" value="灵植">灵植
        <input type="checkbox" name="hobby" value="御兽">御兽
        <input type="checkbox" name="hobby" value="其他">其他
        <br>
        </p>

        <!--定义提交按钮,value 属性定义按钮名-->
        <p>
        &ensp;
        <input type="submit" value="注册">
        <!--定义重置按钮-->
        <input type="reset">
        <!--定义点击按钮-->
        <input type="button" value="按钮">
        </p>
    </form>
</center>

</body>
</html>

(3)运行效果:

 

e4e8c21f650840cc91b32e40d0d24d2a.png

fbf7a4ad976141b0841baa29d8412e08.png

 

七、CSS

什么是CSS?

0393088f034149389b3ec16e8224d1bc.png

1、CSS的导入方式

8e7ccc021943493292353d4a4f583e9d.png

 

2、CSS选择器

b9673035710f4321ad19a74668b4f229.png

 

3、CSS属性

详细请看官方教程:CSS 教程

 

八、JavaScript

什么是JavaScript?

51a1afcea73f4c529b456cd9e4c30d95.png

1、JavaScript的引入方式

(1)内部脚本:将js代码定义在HTML页面中

098cce1e75bd4995a83984b943c72683.png

1.alert()是一个弹出警告框,括号里面可以书写弹出内容

 

(2)外部脚本:将js代码定义在外部js文件中,然后引入到HTML页面中

e56bab0c92d8402d81a2296ab6c7d89f.png

 

2、JavaScript的基础语法

(1)书写语法

f9f13c54aeac49b9b34b1ad176f6c1c1.png

 

(2)输出语句

43fc1ca194554b8ba26e41a0d2b8e37d.png

 

(3)变量

fea0471e374140b8b7f4a51df3a20b1c.png

var关键字 :

  1. 作用域:全局变量(定义在局部的变量在局部外面也可以正常执行)
  2. 变量可以重复定义
  3. 下图可以正常运行,20覆盖了30而不会报错

        a1f3204c41d74d8194065324dbe8d0fb.png

let关键字:

  1. 作用域:局部变量不能当成全局变量使用,只在当前代码块有效
  2. 变量不可以重复定义

 

(4)数据类型

a6b9b1d7b31748cda545dfd7976ffede.png

具体代码演示:

        aa24b11ef5664f0ab94a8a06fae01dc4.png

 

(5)运算符

4683a2ae33914e328c164813ed277d65.png

==与===的区别: 

        02381a137d29452490d0852b7a6475dc.png

 

类型转换:

        fe9b5b6d377c4a52ab5932a372ffd2d3.png

        代码:

         10bd3856cb1a4add8e948969fec6766a.png

 总结:

        067a498518874ebfb07c4baa3716d112.png

 

(6)流程控制语句

4458ce5811304824a3afa7480ed54276.png

具体演示代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>小小修士</title>

</head>
<body>


<!--  在HTML中的JavaScript代码必须位于 <script></script>
      之间,且一般情况下,将JavaScript脚本放在</body>前面
      -->
<script >
    // 1.if
    var count = 3;
    if(count == 3){
        alert(count);
    }

    //2.switch
    var num = 3;
    switch (num){
        case 1:{
            alert("星期一");
            break;
        }
        case 2:{
            alert("星期二");
            break;
        }
        case 3:{
            alert("星期三");
            break;
        }
        case 4:{
            alert("星期四");
            break;
        }
        case 5:{
            alert("星期五");
            break;
        }
        case 6:{
            alert("星期六");
            break;
        }
        case 7:{
            alert("星期天");
            break;
        }
        default:{
            alert("输入的星期有误");
            break;
        }
    }

    //3.for
    var sum = 0;
    for(let i = 1; i <= 100; i++){
        sum += i;
    }
    alert(sum);

    //4.while
    var sum = 0;
    var i = 1;
    while(i <= 100){
        sum += i;
        i++;
    }
    alert(sum);
</script>
</body>
</html>

(7)函数

3cb4ed37b20841d788126592dced3c40.png

d7bd3d55a6af470a8b04ee7d7fd2dd90.png

 

3、JavaScript常用对象

(1)Array

        bf3902b659e94c768d66e471ffbd1993.png

 实现代码:

        9c213034395a4817b673fd7fdedfa3c6.png

         681e3c4d235b4fdfb1512e5671eb65c0.png

 

(2)String

        600b03ef78254109b32725cac9da5635.png

 实现代码:

        aa904bf985db44cc967bef343d872d0c.png

 

 trim()方法:去除字符串前后两端的空白字符,在以后表单验证的时候可能需要去除两端空白字符

 

(3)自定义对象

        d367f5f74bce49c69135ae7fe5d813d1.png

 实现代码:

        e4b594d766084858ac78a3992b7a708b.png

 

4、BOM(JavaScript 和 HTML DOM 参考手册)

788a9cf1e9e04b549c49a8bb315372e7.png

(1)Window浏览器窗口对象

        89730c6c2dee4dafb861987ea59cf18e.png 

 实现代码:

        9bd68ab368c84eb08807ec84ca2242be.png

定时器实现代码:

         18ff6414f91b4b6fb10a64eb9640d896.png

 案例:b2eeeaa167064b73bcecf6dcefb446a0.png

 

具体代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>小小修士修炼空间</title>
</head>
<body>
<center>
    <font color="#ff4500">
        <h1>
            小小修士进阶场
        </h1>
    </font>
</center>
<hr>
<br>
<br>
<br>

<center>
    <input type="button" onclick="on()" value="开灯">
    <img id="myImage" border="0" src="../img/off.gif" style="text-align:center";>
    <input type="button" onclick="off()" value="关灯">
</center>



<!--JavaScript代码-->
<script>
    function on(){
        document.getElementById('myImage').src='../img/on.gif';
    }
    function off(){
        document.getElementById('myImage').src='../img/off.gif';
    }

    // 定时器
    // 更近所需变化值的个数采用求余产生固定的值,例如需要两个变化的数:x%2,需要三个变化的数:x%3
    var x = 0;
    setInterval(function (){
        if(x%2 == 0){
            on();
        }else{
            off();
        }
        x++;
        if(x==100){
            x=0;
        }
    },1000);
</script>
</body>
</html>

效果图:

        4fe11e3d61f54d60b8fae2bc0a3c7d78.gif

 

(2)Navigator浏览器对象

(3)Screen屏幕对象

 

(4)History历史记录对象

b1c2d40a028e4e5288c97034543f2612.png

 

(5)Location地址栏对象

6658a2c289e5460889567bc6a93bf5f6.png

 代码:

        387abf50961244b299f51069c96fb94e.png

 案例:

        f6b966f7fdf043088ea2f4c9911b9f24.png

 

5、DOM(获取对象,后面通过对象来调用相应的方法)

50bc355cbb4545e8820bdaebeee3ee13.png

a5c6a499b91e48d4a7344e1595c3bad5.png

 ab869f821359463184ae1918bfdfea59.png

 

(1)获取Element对象

ee91d5a97cd445ad8106f3741f31bb6d.png

代码仿写:

         b60aeb0a6f6c4630b82e528bcb5a54dd.png

         f23ff5e1d7374a498b3c4fbc2b8ccb77.png

         fd3211a932c9422ba235e0113e9ff556.png

 

 

(2)常见的HTML Element对象的使用 

          自行查阅官方文档:JavaScript 和 HTML DOM 参考手册

 

6、事件监听 

d1fc7b83f7d04f53939eb36cb418a607.png

(1)事件绑定

        4e8ab496ad5a4e57b92fe074297c3008.png

 

(2)常见事件(官网:HTML DOM 事件

 

7、正则表达式

42333083bcc14baa9d4d9472d32492a3.png

 

九、Web核心 

b3c5be7a0128473fb2c15c67bf9c7c98.png

 

1、HTTP

2aeec57f1f7b4f2081d9168a74ca3567.png

         浏览器向服务端传输请求数据,服务端接收请求数据后响应数据传输给浏览器,浏览器接收响应数据。但是怎么识别呢?请求数据和响应数据要按照一定的规则来书写,这样浏览器和服务端就能按照这种规则来解析数据。

 

(1)请求数据格式

        f2a7ec727d9f4e848137d427b970534c.png

 

(2)响应数据格式

        e84c10cca8e84540b2e4d075888366e7.png

 

2、Web服务器—Tomcat

f30287c740144432994dcb0ae8604c11.png

 

(1)Tomcat的基本使用(Apache Tomcat® - Welcome!)

        安装、卸载、启动、关闭、配置、部署项目(自行博客搜寻)

(2)在idea上创建maven web 项目

        93d02ae0defd40358e7a0d7e7cc412d8.png

         20b89275bcd64757b6bd487ec28c7f93.png

         92d80c4695694fdc8155e2483aec913b.png

 

(3)在idea上使用Tomcat

        (1)集成方法

        de078e0d5a6b438c9662477ee537c827.png

         (2)pom.xml 添加插件方法

        02aab08717054260aadc14ac542461c3.png

 

 

3、Servlet

002a35e2ef524af0a1c576f44af95e5f.png

        Servlet 提供了动态 Web 资源开发技术,一种可以将网页数据提交到 Java 代码,并且将 Java 程序的数据返回给网页的技术,使用 Servlet 技术实现了不同用户登录之后在页面上动态的显示不同内容等的功能。

(1)快速入门

        ac4ef14dabd5475887f2ec0cc3115c4d.png

依照前面所学创建maven web项目:

        67dee59eab504ca1a224593791ff6d17.png

 

        注意:

                在步骤1修改pom.xml文件时,记得导入tomcat插件。

        遇到的问题:

                在配置Tomcat插件时右侧没有出现tomcat7标志

                7b23baa4257c4a22ab224e2dbcd4761f.jpeg

         解决办法:

  1.  检查pom文件中的jdk配置(与自己的jdk版本是否一样)
  2. 在pom文件中,不要将tomcat插件plugin放到<pluginManagement>中(大部分是这个问题)

        2c6f1ecab12146149e8a50c9355a3bd6.png

 

(2)Servlet执行流程

9297e302333d466ba3362f16e5faea4d.png

 

(3)Servlet生命周期

fa9143b893df4468aa882acb8b89dccc.png

 代码:

package com.itheima.web;

import javax.jws.WebService;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

// Servlet要想被访问,必须要配置一个访问路径@WebServlet("/demo1")
@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
public class ServletDome1 implements Servlet {
    /*
    初始化方法:
    1.调用时机:默认情况下,Servlet被第一次访问时,调用
        *loadOnStartup:为-1时,创建对象的时候才会调用;为0或正整数时,服务器启动时就会被调用
    2.调用次数:1次
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init被调用");
    }

    /*
    提供服务:
    1.调用时间:每一次Servlet被访问时,调用
    2.调用次数:多次
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("servlet你好,小小修士来报道了");
    }

    /*
    销毁方法:
    1.调用时间:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
    2.调用次数:1次
     */
    @Override
    public void destroy() {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
}

 

(4)Servlet体系结构

a6c236ad358946298c549020ce06c553.png1.如何实现doGet方法?

        通过浏览器直接输入URL路径来访问资源的方法就是get的请求方式(实现了doGet方法)

2.如何实现doPost方法?

        第一步:写一个HTML页面表单来请求当前servlet资源(HTML在webapp文件里面)

        第二步:HTML浏览器页面提交数据,通过post请求方式访问资源并提交(实现了doPost方法)

3.思考:

        ①HttpServlet中为什么要根据请求方式的不同,调用不同的方法?(各个请求方式的请求消息不一样,要根据不同的请求方式进行不同的处理)

        ②如何调用?(通过不同的逻辑方式进行调用)

 

下面通过探究官方文档原理来加深理解:

        编写一个实现servlet接口的类,编写service方法中的逻辑代码,如下:

package com.itheima.web;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class ServletDome3 implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        // 根据请求方式的不同,进行分别的处理
        // 将servletRequest强转为HTTPServletRequest对象,因为请求方式只有在HTTP的协议下才能获取出来
        HttpServletRequest request = (HttpServletRequest)servletRequest;

        // 1.获取请求方式
        String method = request.getMethod();

       // 2.判断
        if("GET".equals(method)){
            // get方式处理逻辑
        }else if("POST".equals(method)){
            // post方式的处理逻辑
        }
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

         为了避免重复在实现servlet接口的类中重复写代码,可以单独写一个实现servlet接口的类(下图第一张截图),将请求方式的逻辑判断写成方法,后面需要的类(下图第二个截图)继承单独写的这个类就行(继承的时候需要重写请求方式的逻辑判断方法),改写如下:

                66bbb57a912e442ebc6e002d7547e692.png

                 e71ce9a691b148c1a3ace62f7edf01cf.png

 

(5)Servlet urlPattern配置

7b3ee1c3c5b94cd996f2976d3f48ceab.png

fc37ffe68a3248729dca308c031fe939.png

cc2ee9c4153246d5adfd56d6ecd53f9c.png

 

(6)XML配置方式编写Servlet

132350e2c78741b88a91dbedfd1c958f.png

 

4、Request(请求)&Response(响应)

(1)Request:

        浏览器向服务端发送请求(HTTP协议请求数据),请求数据被tomcat解析后被放到一个对象里面来保存,这个对象就是Request对象。当我们使用Request对象时就是获取这些请求数据

c4fee7d5064a4ae4b6fb20409d069b5a.png

 

①Request继承体系

        86efa9b2e3cf4a519e15cfccf196ee8c.png

 

 

②Request获取请求数据

        a0d734675a4e4235991b5562781a05c7.png

 请求体步骤:

        1.创建一个HTML页面编写表单代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/web-dem/demo4" method="post">
    <input name="username">
    <input type="submit">
</form>
</body>
</html>

        2. 在servlet文件dopost方法中获取post 请求体参数

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取post      请求体:请求参数

        // 1.获取字符输入流
        BufferedReader bufferedReader = req.getReader();

        // 2.读取数据
        String line = bufferedReader.readLine();
        System.out.println(line);
    }

最后HTML表单数据提交后,Request就会获取到数据

思考:

        GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?

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

        5421a423c2874275a8c590e1eb5eb5b5.png

        f05acb12366c4635add7afce53158289.png

package com.itheima.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@WebServlet("/req1")
public class RequestDome1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // GET请求逻辑
        // System.out.println("get请求获取参数~");

        // 1.获取所有参数的map集合
        Map<String,String[]> map = req.getParameterMap();
        for(String key : map.keySet()){
            // 获取键
            System.out.print(key + ":");

            // 获取值
            String[] values = map.get(key);
            for(String  value : values){
                System.out.print(value+" ");
            }
            System.out.println();
        }

        System.out.println("-----------------------------------");

        // 2.根据key获取参数值,数组
        String[] hobbies = req.getParameterValues("hobby");
        for(String hobby : hobbies){
            System.out.println(hobby);
        }

        System.out.println("-----------------------------------");

        // 3.根据key获取单个参数值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doGet(req,resp);
        
        /*
        // POST请求逻辑
        System.out.println("post请求获取参数~");

        // 1.获取所有参数的map集合
        Map<String,String[]> map = req.getParameterMap();
        for(String key : map.keySet()){
            // 获取键
            System.out.print(key + ":");

            // 获取值
            String[] values = map.get(key);
            for(String  value : values){
                System.out.print(value+" ");
            }
            System.out.println();
        }

        System.out.println("-----------------------------------");

        // 2.根据key获取参数值,数组
        String[] hobbies = req.getParameterValues("hobby");
        for(String hobby : hobbies){
            System.out.println(hobby);
        }

        System.out.println("-----------------------------------");

        // 3.根据key获取单个参数值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);

         */
    }
}

在tomcat8之前出现的中文乱码问题:

        47f5eb9bee8b4d6c80ecc719123ff106.png

 为什么会乱码?

        post提交乱码:通过字符输入流来获取数据,输入流默认编码为ISO-8859-1,

        解决办法:在获取输入流之前将编码设置为utf-8

        fc50224cd365407face15f08e2144483.png

         get提交乱码:字符串通过HTTP协议由浏览器传输到服务器(URL编码形式传输),然后到了tomcat后(URL解码),但是因为编解码字符集不一样,所以产生乱码情况。

        解决办法:将ISO-8859-1编码转换为字节,然后将字节转换为utf-8编码就行。

        eff5d8a2641e42aa879372890ffbbc61.png

         c9f2ee26f63444fb92e2aec19394a468.png

代码:

package com.itheima.web.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@WebServlet("/demo4")
public class ServletDome4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 使用request对象 获取请求数据
        String name = req.getParameter("name");       // url?name=小小修士

        // 将URL解码后的【ISO-8859-1】转换为字节数据
        byte[] bytes = name.getBytes("ISO-8859-1");

        // 再将字节数组转换为字符串
        String s = new String(bytes, "utf-8");

        // 使用response对象 设置响应数据
        resp.setHeader("content-type","text/html;charset=utf-8");
        // 输出流默认的编码是ISO-8859-1,不支持中文;此时将流的编码设置为utf-8 "text/html;charset=utf-8"
        resp.getWriter().write("<h1>"+s+",欢迎您!<h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

 

③Request请求转发

        6a5ac3dfb82242bb8111b3fec949fb1e.png

 

(2)Response:

        将请求数据处理后,服务端中的tomcat会发送一些响应的字符串给浏览器,浏览器解析响应数据。我们通过Response对象来设置响应数据,tomcat会在响应前会将对象里面设置好的字符串发送给浏览器。

997ab80d641142649566459e5fd41876.png

 

①Response 设置响应数据功能介绍

        6bec8e6f1d29413493e0427002975198.png

 

②Response 完成重定向(重定向需要虚拟目录,可以采取动态的方式获取,降低耦合性)

        b157544be60d44fab8a9ad8f56510e3a.png

package com.itheima.web.response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1~~");

        /*
        // 重定向
        // 1.设置响应状态码 302
        resp.setStatus(302);
        // 2.设置响应头 Location
        resp.setHeader("Location","/web-dem/resp2");
         */

        // 简化方式定义重定向
        //resp.sendRedirect("/web-dem/resp2");

        // 使用动态获取虚拟路径-->请求数据
        String contextPath = req.getContextPath();
        resp.sendRedirect(contextPath+"/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

 关于路径问题:

        7874a04f970c441eb1e98da762022bd6.png

 

③Response 响应字符数据

        65d78bd398ea438899d1fc630d155c0a.png

        d1ee46688ee8414699a22b86362e7d9b.png    

 

④Response 响应字节数据

        a9491a61c347493b9761e947b34bc39f.png

取代第三步:

        配置pom.xml文件

         3f34a19aaa0741d186e38c2e345c5448.png

        修改文件代码: 

         37e35ebf896f4bb199ed9f268c9c3960.png

 

(3)案例

用户登录:

38cc170dd67f4840a1e4d66c793ff774.png

f7e82203056d4561959b1eafb837f744.png

详情可以看:案例(用户登录与注册文章)

 

用户注册:

b34dca281d5046dc8046b95230e91b87.png

 

代码优化:

20d0b2f411bf49a4bbf6961f3cabc6bc.png

        创建一个工具类,每次要获取SqlSessionFactory对象时,就调用这个工具类里面的方法,但是工厂只能创建一次(如果创建多次增加了负担),所以不能重复创建,采用静态代码块的方法

工具类代码:

package com.xiulian.util;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


import java.io.IOException;
import java.io.InputStream;

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;
    }
}

 

5、JSP 

8cdd851e8aa6419cb3a9c82fe21eb779.png

 

(1)JSP快速入门

        68185aed65d340df9a49b6c023838480.png

(2)JSP原理

        6e3769c03799472882cfd1f509bc3fa2.png

(3)JSP脚本

        edb50a69b0c549fe976c7a3d0b44b63d.png

        85726d0ecf74478fbb54818e8b76be61.png

 

(4)EL表达式

        6ead2045b7c44878af1b8086d1e6f7bc.png

 

(5)JSTL标签

        45e2c189fc8c4aa9a4eef3bf7cc861e5.png

 

(6)MVC模式和三层架构

        MVC:

                servlet充当控制器,从模型里面获取数据存储到域中(例如request域),然后转发到jsp里面做页面展示。

                04ecb587bc4645e791cbe55a5a0eee11.png


          三层架构:

                375c4a9176ad4c1f809e92e25947f3ec.png

 

 


两者的关系:

                cd50078671d943978de0ff150ba57d10.png

 

(7)案例

准备环境:

755a24ece00c4756b5aabdec359ff68d.png


 查询所有:

5e428f05314d4fffa1783a98b760a350.png

         ①编写Dao层(在mapper包下)

                接口:

                331354e0c002418b9939d66bb4e5759b.png

 

                映射文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.BrandMapper">

<!--    数据库别名修改,当数据库属性名跟实体类变量不同时,做此修改   -->
    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>
</mapper>

         ②编写service层(在service包下)

package com.itheima.service;

import com.itheima.mapper.BrandMapper;
import com.itheima.pojo.Brand;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

/*
   Service 层,调用接口方法,返回结果
 */
public class BrandService {
    // 获取连接工厂对象,因为工厂要被多次调用,所有设置成成员变量
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /*
    *查询所有
    * @return
     */
    public List<Brand> selectAll(){
        /*
        *   这个里面是调用BrandMapper.selectAll();(运用mybatis)
        *借用封装的工具类SqlSessionFactoryUtils,调用里面的方法获取
        * SqlSession
         */

        // 1.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 2.获取BrandMapper,[BrandMapper.class]是接口
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 3.调用接口里面的方法
        List<Brand> brands = mapper.selectAll();

        // 4.释放资源
        sqlSession.close();

        return brands;
    }
}

        ③编写web层代码(在web包下)

                *编写HTML页面代码(超链接)(访问web下编写的SelectAllServlet文件)

                *编写jsp页面代码(页面展示)(web下SelectAllServlet文件从Dao层得到的数据转发到jsp页面里然后在网页展示)

        HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--超链接(访问到href所对应的虚拟目录)-->
    <a href="/brand-demo/selectAllServlet">查询所有</a>

</body>
</html>

        jsp代码:

<%@ page isELIgnored="false" %>
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>筑基层</title>
</head>

<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>

    <c:forEach items="${brands}" var="brand" varStatus="status">
        <tr align="center">
            <td>${status.count}</td>
            <td>${brand.brandName}</td>
            <td>${brand.companyName}</td>
            <td>${brand.ordered}</td>
            <td>${brand.description}</td>
            <c:if test="${brand.status == 1}">
                <td>启用</td>
            </c:if>
            <c:if test="${brand.status != 1}">
                <td>禁用</td>
            </c:if>
            <td>
                <a href="#">修改</a><a href="#">删除</a>
            </td>
        </tr>
    </c:forEach>

</table>

</body>
</html>

        web层文件代码:

package com.itheima.web;

import com.itheima.pojo.Brand;
import com.itheima.service.BrandService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    private  BrandService service = new BrandService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.调用BrandService
        List<Brand> brands = service.selectAll();

        // 2.存入request域中
        req.setAttribute("brands",brands);

        // 3.转发到brand.jsp
        req.getRequestDispatcher("/brand.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

        问题及解决:

        分别出现了404问题和500问题,在执行项目后,点击超链接出现的两个问题

        404问题:web浏览器tomcat没有配置好,按照要求重写配置

        500问题:数据库连接出了错,分别检查实体类Brand中的参数名是否和数据库依据jsp文件代码一致(我就是这个问题),检查mybatis核心配置文件里面数据库连接信息是否正确,检查映射文件sql语句是否有误等等~~

        回顾主要流程:

        1.首先准备好项目环境(导入对应的依赖、搭建文件结构、创建相应的数据库表、编写表的实体类、然后用mybatis完成与数据库的连接【mybatis核心配置文件(还有扫描执行映射文件的功能)】以及实现对数据库的操作【映射文件和对应的接口】)

        2.编写Dao层,对数据库数据的操作就是Dao层(有的写成mapper层,里面就是mapper接口,拥有执行操作的方法)

        3.编写service层,里面就是获取连接工厂而进一步获取sqlsession对象从而获取Dao层的mapper接口,进一步调用其中的方法,从而书写完毕一个操作的方法selectAll()方便web层调用这个方法得到数据(为了避免多次且浪费进程的情况,所以并不直接写获取连接的代码,而是单独创建一个util包里面写工具类代码SqlSessionFactoryUtils类)

        4.  编写web层,首先在webapp下编写页面代码(HTML,jsp等),然后web层里面书写的类就是接收HTML的访问(超链接的跳转),这个类调用service层的操作方法获取数据存到request域中,并将数据转发到jsp页面里,然页面展现数据。


添加:

8cfc194f249745b8b396b7ce333cff03.png

        ①编写Dao层(在mapper包下)

                接口:

                ad37264485da4393b60c29abd80cff52.png

                 映射文件:不变

        ②编写service层(在service包下)

                3f45d6a4d9e24c9186cbe8254e160ffc.png

          ③编写web层代码(在web包下)

                *编辑jsp文件(按钮事件绑定)(在原有展现页面的jsp里面声明按钮,然后新建一个让  按钮跳转的jsp页面【一个可以添加数据的表单页面,这个页面提交路径是web层的【AddServlet】)

                *编写web层AddServlet代码(注意修改POST乱码问题)


修改:

        回显数据:

83f2585a49af4a279ce0a6cae182856a.png

         ①编写Dao层(在mapper包下)

                接口:

                        ca00c4970ef446d49344a2f18d2beb19.png

                 映射文件:不变

         ②编写service层(在service包下)

                b9ab1edbfd914bfb882228199f593ade.png

         ③编写web层代码(在web包下)

                *在brand.jsp页面中书写【修改】的跳转路径

                c7638158880e48c99b12525650ea4c90.png

                 *书写uptade.jsp页面,起到回显的作用,通过id显示对应的信息页面

                *书写web层的selectByIdServlet代码,接收id,通过id调用对应的service方法获取对应数据,存到域中,将数据转发到uptade.jsp页面,让页面回显数据

               

        修改数据:

a66c3c3a040c4b20b783641db6282b9a.png

         ①编写Dao层(在mapper包下)

                接口:

                        060fbcf9a9ba4d0fb419a40960706170.png

         ②编写service层(在service包下)

                b2351b02ff26467785bbff850fcd2dc4.png

         ③编写web层代码(在web包下)

                将update.jsp页面数据提交到web层下的UpdateServlet,此层代码将数据接收封装后转发到查询所有的web层代码里,然后显示出修改后的所有数据页面

        c628e4b4245d40a3a0963cdccf6fbe18.png


删除:

        ①编写Dao层(在mapper包下)

                接口:

                        6e7a90cadf76410995d15957cec43e75.png

                映射文件:

                        6a548db49e254ef58d446f44cc159edc.png

        ②编写service层(在service包下)

                1fa1f63758c9493eae3fab42573d3a09.png

        注意:一定不要忘记提交事务,否则会报错

 

        ③编写web层代码(在web包下)

                015d919444474fc089c0e8ff54d80393.png

        ④删除时显示是否确认删除的提示框

                在brand.jsp页面的删除跳转路径中加入confirm()方法

                        2c6f080d0bcf40c99fb4b918652676ce.png


brand-demo案例完全结构:

0839589c1da4463dbd3bd5bd212ff81a.png

 

6、会话跟踪技术 

78ae13591cc049a695fc6e6c59e2997d.png

(1)Cookie基本使用

        735ade4ad6f0488a886a5cda091b07c3.png

 

(2)Cookie原理

        在servlet创建cookie对象和保存的键值对,然后将其响应到客户端,客户端就会保存该cookie。在另外一个servlet里面接收cookie的请求,获取到对应的cookie的值。在浏览器未被关闭的情况下,访问第一个servlet后再访问第二个servlet就能验证cookie共享(如果关闭浏览器还想共享cookie就要设置cookie的保存时间)

        a073c435c11947ac818fba2ba4f095cd.png

 

(3)Cookie使用细节(cookie的持久化保存)

        ecff857b72f2455ba6f76997d5313344.png

 

(4)Session基本使用

        23ee65b6e4aa49d2bca45e7c9b84f913.png

        demo1网页 

        bff2a82c2e1947a39e2f445442d44535.png

        demo2网页 

         541f798b066d485cbb7ced5a29246c05.png

         

(5)Session原理

        9b56b4a0400f4661ae4d7565a0a3d87e.png

        一个servlet获取session对象并存储值。另一个servlet也获取该session对象,并去获取对应的值。如何保证它们获取的session对象是同一个?这就涉及到了cookie,在第一个servlet中,客户端会将服务端传来的session的id用cookie保存下来,当该客户端再次请求服务端时会将session的id值传到服务端,服务端会根据对应id去获取session对象,以此保证一次会话不同请求中获取到的session的对象是同一个(其他客户端请求服务端时获取到的session对象时不同的)

(6)Session使用细节

        8005d33453ed4e6bad3ec91f77af3fd8.png

 

(7)案例

项目名为RewriteBrand-demo

f8b66701e18148fd8c044510b9876a06.png


  用户登录

        d0a8c5ddc007404d9fa7af0b6e7ed9ec.png 

 

流程:

前期准备:mybatis核心配置文件、映射文件、实体类等代码书写

        按照三层架构模式进行编写

        1.书写dao层(mapper层)

                书写mapper接口方法,跟映射文件对应

        2.书写service层

                书写与接口中对应的方法,通过工具类获取连接工厂,通过mybatis利用映射文件数据库操作语句操作数据库,创建方法(一定要注意,每次都要清除对象(close),除了查询操作,其他操作要记得提交事务)

        3.书写web层(准备相应的跳转前端页面或者前端展示页面)

                获取网页提交过来的请求数据(username,password),调用service层对应方法返回user对象,通过判断user是否为空做出对应的操作。不为空,则登录成功,因为是一次会话多次请求,所以要用到会话跟踪技术(将登录成功的user对象存储到session),这样在跳转的页面里面也可以调用user对象的值,利用重定向跳转到selectAllServlet查询所有的功能,为什么要用重定向?因为登录请求和跳转的查询请求没有数据要共享,所以用重定向。为空,则登录失败,提示“用户名或密码错误”并转发到login.jsp页面,在request域中存入键值对(名,“用户名或密码错误”),后面通过jsp页面调用request的键来获取值。


记住用户

        73528b3f245d444f93eb65d4121fc52c.png

        dbdce6a81ea846b49616f85d4c0db9ea.png

 

         判断是否勾选记住用户:给复选框定义一个值value,如果不等于这个值则没有勾选(通过request域获取值,然后在登录成功的代码块中通过这个值去判断是否勾选记住用户)。如果判断为勾选,则为用户名和密码创建cookie对象,设置其存活时间,并发送给网页,这样每次用户勾选复选框后,服务端会自动将其保存在服务端,方便其调用。

        获取cookie:服务器再次访问浏览器会自动携带cookie,所以我们要在页面获取到cookie数据后,设置到用户名和密码框中,分别在jsp页面中的username、password中设置value值(就是cookie.username.value)

        问题及解决:

                1.请求数据与响应数据不支持中文传输,所以要根据请求方式的不同进行转换

                2.cookie不支持中文,所以要使用URL编码转换后再创建cookie

         代码:

                6ec79b0f02e444c6b32c5c1d022f29bf.png


用户注册:

流程:

前期准备:mybatis核心配置文件、映射文件、实体类等代码书写

        按照三层架构模式进行编写

        1.书写dao层(mapper层)

                书写mapper接口方法,跟映射文件对应

        2.书写service层

                判断是否注册成功,首先判断从浏览器传输回来的封装对象的数据是否存在,如果不存在则添加创建并返回true,如果存在则返回false。

        3.书写web层(准备相应的跳转前端页面或者前端展示页面)

                接收请求数据并封装为user对象,然后调用service层的判断注册方法返回一个Boolean类型的值,通过这个值判断是否创建成功,如果成功则转发到登录页面并显示“注册成功,请登录”的字样,如果没有成功则转发到注册页面并显示“用户名已存在”。

45b1c05fd099451abd154731153f6445.png


展示验证码:

        23363933020b4cf8ac8f727f795a0817.png

 大体流程:

        在工具类包中加入生成验证码工具类,然后web层编写CheckCodeServlet能够对验证码进行前后端数据的转换;再去注册页面的jsp中去展现验证码输入框、验证码图片和单击换一张的按钮,其中验证码图片的路径(src)就是web层书写的对应文件代码,对验证码图片和按钮设置onclick绑定事件(根据绑定所写函数方法来进行验证码图片的更换),所设id的目的之一也是为了根据验证码的id获取验证码对象,把此对象的地址进行变更就会使得验证码图片改变(在函数方法的src里面将原有地址后面加一个参数,参数为随时在变化的时间,这样就达到了点击按钮或图片验证码更新的效果)

897328f6378a493bba471c1d89de7d7b.png


校验验证码: 

        531d146d2708447587b1eed4e90b0047.png

 大体流程:

        首先在web层中的CheckCodeServlet代码文件中将生成的验证码存入到session中(因为时一次会话两次请求,所以要进行会话请求,不然验证码将会不一样),然后在web层的RegisterServlet代码文件中去获取用户输入的验证码(通过文本框name去获取)、获取程序随机生成的验证码(通过session原先保存的键值对获取),然后比较他们是否相等,如果不等,要显示验证码错误,然后跳转到注册页面。

        c4a8826241c240318604f1c29483fb96.png 

 

7、Filter(过滤器)

03fdf55c692a4dac896c8b879d978fe1.png

      可以将web资源里面重复书写的功能代码写在Filter里面,例如用户没有登录就不能访问登录后的页面,所以web资源里面要一个一个判断用户是否登录,如果没有登录就拒绝访问,这个时候就可以将这个判断写在Filter里面。

(1)Filter快速入门

        881a70eb62db44d49060ab1741e563bd.png

 

(2)Filter执行流程

        2daae6f5d9d04f5b8f687b9559055220.png

 

(3)Filter使用细节

        eb2b4b6c85cf42909ee9a8a5439b25bb.png

         491524a182e24854a881a8ac3b8e4dc6.png

8、Listener 

e256455c7af3440bbc81a73e2274f263.png

 

9、AJAX

2128251cd7724197a9e5fa7aad002b99.png

在没有接触ajax的时候,我们响应数据是通过将数据存在域里面,然后前端页面通过jsp进行数据调用实现动态的展示,使用ajax可以替换掉jsp,如下图:

ea2e337090e447e3b29015fec2bf0c92.png

 

Ajax的作用:

3195ce7ea9604d66b6dfd7ebe74858a5.png

同步和异步: 

同步:客户端发送请求到服务端,服务端处理请求(在这个期间客户端只有等待),服务端处理完毕后响应给客户端

69706163dac24c37b8b5e3028da915d9.png

异步:同样是客户端发送请求到服务端,服务端处理请求(在这个过程中,客户端不用等待服务器端,不会刷新页面,客户端可以去进行其他操作), 服务端处理完毕后响应给客户端

 

10.JSON

(1)基本语法

bd3871b1f0c440c587bf1d967b5995ea.png

 

(2)数据转换

837ed37ad598448a891db792945dbc5d.png

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小修士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值