JavaWeb笔记

1、MySQL

分页查询语法
SELECT 字段列表 FROM 表名 LIMIT 起始索引 , 查询条目数 ;
计算公式:起始索引 = ( 当前页码 -1) * 每页显示的条数

2、Maven

Maven配置步骤
在这里插入图片描述

<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
	  <id>aliyunmaven</id>
	  <mirrorOf>*</mirrorOf>
	  <name>阿里云公共仓库</name>
	  <url>https://maven.aliyun.com/repository/public</url>
	</mirror>
    <mirror>
      <id>maven-default-http-blocker</id>
      <mirrorOf>external:http:*</mirrorOf>
      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
      <url>http://0.0.0.0/</url>
      <blocked>true</blocked>
    </mirror>

Maven常用命令:
compile :编译
clean :清理
test :测试
package :打包
install :安装
Idea配置Maven:
:setting环境配置:
在这里插入图片描述

错误:Error java 错误 不支持发行版本5
参考:解决方案
在这里插入图片描述

错误:java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.
参考:解决方案

java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.exception.ComponentLookupException: com.google.inject.ProvisionException: Unable to provision, see the following errors:
 
1) Error injecting constructor, java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V not found
  at org.jetbrains.idea.maven.server.embedder.CustomModelValidator.<init>(Unknown Source)
  while locating org.jetbrains.idea.maven.server.embedder.CustomModelValidator
  at ClassRealm[maven.ext, parent: ClassRealm[plexus.core, parent: null]] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule)
  while locating org.apache.maven.model.validation.ModelValidator annotated with @com.google.inject.name.Named(value=ide)
 
 
	... 24 more
 

依赖管理:
在这里插入图片描述

3、MyBatis

MyBatis官方网址:点我进入
用于简化JDBC

  • 快速入门

在这里插入图片描述1、创建user表,添加数据

create database mybatis;
use mybatis;

drop table if exists tb_user;

create table tb_user(
	id int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	gender char(1),
	addr varchar(30)
);



INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');

2、创建Maven模块,并配置环境,在pom.xml中添加导入MyBatis依赖和各种jar包的坐标
在这里插入图片描述3、编写MyBatis核心配置文件,也就是解决数据库连接的问题,有固定的格式
对应官网这部分:
在这里插入图片描述新建一个mybatis-config.xml,将上面的内容copy下来,然后换成自己的数据库连接信息。
在这里插入图片描述但是要注意,下面是SQL映射
在这里插入图片描述4、编写SQL映射文件,这部分也有固定格式,可以去官网copy,对应的是这部分,将这部分放在UserMapper.xml文件当中,因为是对User类操作的,还要改为自己的信息
官方网址对应的信息:
在这里插入图片描述copy到UserMapper.xml中
在这里插入图片描述改为自己想要的操作:
在这里插入图片描述写完UserMapper.xml后要记得回来写SQL映射:
在这里插入图片描述

要不然会报这个错误:

D:\IDEA\jdk\bin\java.exe "-javaagent:D:\IDEA\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=62305:D:\IDEA\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=GBK -classpath E:\MyJava\MavenTest02\target\classes;E:\Maven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn-resp\org\mybatis\mybatis\3.5.5\mybatis-3.5.5.jar;E:\Maven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn-resp\mysql\mysql-connector-java\5.1.32\mysql-connector-java-5.1.32.jar;E:\Maven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn-resp\org\slf4j\slf4j-api\1.7.20\slf4j-api-1.7.20.jar;E:\Maven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn-resp\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;E:\Maven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn-resp\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar test.Test
[DEBUG] 13:24:11.326 [main] o.a.i.l.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. 
[DEBUG] 13:24:11.343 [main] o.a.i.d.p.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 
[DEBUG] 13:24:11.343 [main] o.a.i.d.p.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 
[DEBUG] 13:24:11.343 [main] o.a.i.d.p.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 
[DEBUG] 13:24:11.343 [main] o.a.i.d.p.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in org/mybatis/example/BlogMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource org/mybatis/example/BlogMapper.xml
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
	at test.Test.main(Test.java:18)
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource org/mybatis/example/BlogMapper.xml
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:122)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78)
	... 2 more
Caused by: java.io.IOException: Could not find resource org/mybatis/example/BlogMapper.xml
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:374)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:120)
	... 4 more

Process finished with exit code 1

在这里插入图片描述5、写测试代码:

package test;

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 pojo.User;

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

public class Test {
    public static void main(String[] args) throws IOException {
        //1、获取MyBatis核心配置文件对象,sqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2、获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3、执行sql语句
        List<User> users = sqlSession.selectList("test.selectAll");
        System.out.println(users);
        //4、释放资源
        sqlSession.close();
    }
}

在这里插入图片描述注意:第一步获取MyBatis核心配置文件对象,也就是前三句代码,这个是固定格式的,直接去官网复制,对应这个部分:
在这里插入图片描述

  • Mapper代理开发
    在这里插入图片描述1、定义与配置文件同名的Mapper接口,并将两者放在同一目录内:
    原来目录:
    在这里插入图片描述修改后的目录:
    在这里插入图片描述

2、修改namespace的参数为接口的全类名(包名+接口名)

在这里插入图片描述
3、在新定义的Mapper接口中写方法,方法名就是配置文件中id的参数,返回类型根据具体的SQL语句操作灵活变更。
这里是返回全部User信息,所以用集合接收。
在这里插入图片描述
4、由于配置文件UserMapper路径发生了变更,所以MyBatis核心配置文件里面的加载SQL映射的路径也应该修改。
路径为:Path from source Root.
在这里插入图片描述在这里插入图片描述

还有一种Mapper代理的映射方式:
在这里插入图片描述这个路径就是UserMapper接口所在的包的路径,直接是mapper,采用这种映射的好处是日后再有类似于UserMapper放在mapper包,也不需要修改SQL映射了。
更改UserMapper配置文件中的resultType属性值别名:开启之后不需要写包名加类名这种格式,只需要写类名就可以了,并且不区分大小写。
在这里插入图片描述

5、编码测试:
在这里插入图片描述

  • 配置文件实现增删改查
    准备环境:
    在这里插入图片描述tb_brand:
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
    -- id 主键
    id           int primary key auto_increment,
    -- 品牌名称
    brand_name   varchar(20),
    -- 企业名称
    company_name varchar(20),
    -- 排序字段
    ordered      int,
    -- 描述信息
    description  varchar(100),
    -- 状态:0:禁用  1:启用
    status       int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1);


SELECT * FROM tb_brand;

Brand:

package pojo;

/**
 * 品牌
 *
 * alt + 鼠标左键:整列编辑
 *
 * 在实体类中,基本数据类型建议使用其对应的包装类型
 */

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

查询所有:
在这里插入图片描述先在BrandMapper中写一个查询所有的方法:
在这里插入图片描述
然后到对应的BrandMapper.xml中写相应的SQL语句:
在这里插入图片描述最后在测试环境里面写一个测试方法:
在这里插入图片描述实体类属性名 和 数据库表列名 不一致,不能自动封装数据,以下两种解决办法:
第一种解决方式:起别名,起别名,对不同的列名另起一个与实体类属性相同的名。缺点就是每一次都要写一次很长的数据库字段名.解决方式;使用SQL片段
在这里插入图片描述

<!--SQL片段-->
        <sql id="brand_column">
            id,brand_name as brandName,company_name as companyName,ordered,description,status
       </sql>
        <select id="selectAll" resultType="pojo.Brand">
           select <include refid="brand_column"></include>
            from tb_brand;
        </select>

第二种解决方式:resultMap
第一步,定义一个resultMap标签,其中,column是数据库列名,property是实体类属性名
第二步,将resultType替换为resultMap
在这里插入图片描述

<resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
        <select id="selectAll" resultMap="brandResultMap">
            select * from tb_brand;
        </select>

查询详情:
在这里插入图片描述在BuildMapper接口中定义一个方法:
在这里插入图片描述
然后在BuildMapper配置文件中写SQL语句:
在这里插入图片描述最后写一个测试方法:
在这里插入图片描述

细节问题:
1、 参数占位符:
1 ) #{} :执行 SQL 时,会将 #{} 占位符替换为 ?, 将来自动设置参数值
2 ) ${} :拼 SQL 。会存在 SQL 注入问题
3 ). 使用时机:

  • 参数传递,都使用 #{}
  • 如果要对表名、列名进行动态设置,只能使用 ${} 进行 sql 拼接。
    2、 parameterType :
  • 用于设置参数类型,该参数可以省略
    3、 SQL 语句中特殊字符处理:
  • 转义字符
  • <![CDATA[ 内容 ]]>:CD 提示

条件查询:
1)多条件查询:
在这里插入图片描述SQL 语句设置多个参数有三种方式
1 散装参数:需要使用 @Param("SQL 中的参数名称 ")
该方式需要将param括号中的字符串与SQL占位符一致。
brandMapper中的方法:

List<Brand> selectByCondition(@Param("status")int status,@Param("companyName")String companyName,@Param("brandName")String brandName);

2实体类封装参数

  • 只需要保证 SQL 中的参数名 和 实体类属性名对应上,即可设置成功
  • 这种方法要求SQL占位符的参数与实体类的属性名一致。
    在这里插入图片描述

3map 集合

  • 只需要保证 SQL 中的参数名 和 map 集合的键的名称对应上,即可设置成功
  • 要求Map集合的键需要与SQL占位符参数名一致。
  • 在这里插入图片描述
    三种可共用一种SQL占位符参数名,BrandMapper.xml中SQL语句代码:
<select id="selectByCondition" resultMap="brandResultMap">
        select * from tb_brand where status = #{status} and company_name like #{companyName} and brand_name like #{brandName};
    </select>

一般来讲,SQL语句占位符参数不要乱写,一般写实体类的属性名就行,与数据库列名不一致的使用resultMap处理。
测试方法:

@Test
    public void testSelectByCondition() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

//        Brand brand = new Brand();
//        brand.setStatus(1);
//        brand.setBrandName("%华为%");
//        brand.setCompanyName("%华为%");
        Map map = new HashMap();
        map.put("status",1);
        map.put("companyName","%华为%");
        map.put("brandName","%华为%");
        //List<Brand> brands = brandMapper.selectByCondition(1, "%华为%", "%华为%");
        List<Brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);

        sqlSession.close();
    }

2)多条件-动态查询
在这里插入图片描述这部分主要是对BrandMapper.xml中SQL语句的修改:

<!--动态SQL查询-->
    <select id="selectByCondition" resultMap="brandResultMap">
        select * from tb_brand 
<!--        where 1 = 1-->
        <where>
        <if test="status != null">
            status = #{status}
        </if>
        <if test="company_name != null and company_name != ''">
            and company_name like #{companyName}
        </if>
        <if test="band_name != null and band_name != '' ">
            and brand_name like #{brandName}
        </if>;
        </where>
    </select>

动态 SQL
if :用于判断参数是否有值,使用 test 属性进行条件判断

  • 存在的问题:第一个条件不需要逻辑运算符
  • 解决方案:
    1 使用恒等式让所有条件格式都一样
    2 标签替换 where 关键字
    3)单条件-动态查询:
    在这里插入图片描述在BrandMapper接口中新建方法:

在这里插入图片描述
在BrandMapper配置文件中写SQL语句:

<select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from tb_brand
        where
        <choose><!--相当于switch-->
            <when test="status != null"><!--相当于case-->
                status = #{status}
            </when>
            <when test="companyName != null and companyName != ''">
                company_name like #{companyName}
            </when>
            <when test="bandName != null and bandName != ''">
                brand_name like #{brandName}
            </when>
            <otherwise><!--相当于default-->
                1=1
            </otherwise>
        </choose>
    </select>

注:这段代码也可以将otherwise去掉然后把where换成where标签
编写测试代码:

@Test
    public void testSelectByConditionSingle() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        Brand brand = new Brand();
        brand.setStatus(1);
        //brand.setBrandName("%华为%");
        //brand.setCompanyName("%华为%");
//        Map map = new HashMap();
//        map.put("status",1);
        //map.put("companyName","%华为%");
//        map.put("brandName","%华为%");
        //List<Brand> brands = brandMapper.selectByCondition(1, "%华为%", "%华为%");
        List<Brand> brands = brandMapper.selectByConditionSingle(brand);
        System.out.println(brands);

        sqlSession.close();
    }

添加:
在这里插入图片描述先在BrandMapper接口中写一个方法:
在这里插入图片描述
然后再BrandMapper.xml配置文件中写对应的SQL语句:
在这里插入图片描述再写测试类:

@Test
    public void testAdd() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        Brand brand = new Brand();
        brand.setBrandName("波导");
        brand.setDescription("手机中的战斗机");
        brand.setCompanyName("波导有限公司");
        brand.setOrdered(100);
        brand.setStatus(1);
//        brand.setStatus(1);
//        brand.setBrandName("%华为%");
//        brand.setCompanyName("%华为%");
//        Map map = new HashMap();
//        map.put("status",1);
        //map.put("companyName","%华为%");
//        map.put("brandName","%华为%");
        //List<Brand> brands = brandMapper.selectByCondition(1, "%华为%", "%华为%");
        brandMapper.add(brand);

        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }

注意添加更新等操作需要提价事务:
如果openSession()置为true,则自动提交事务,无需手动提交,如果没有置为true,需要写上sqlSession.commit();
进行手动提交事务,否则会添加失败。
异常:Could not retrieve transation read-only status server
解决方法:点我进入
添加-主键返回:
在这里插入图片描述返回添加数据的主键

在这里插入图片描述注意:这里可以直接brand.getId()来获取id,不需要通过修改方法返回值,这个方法仍然是无返回值
动态修改:
在这里插入图片描述

先在BrandMapper接口中写一个方法
在这里插入图片描述
然后在BrandMapper.xml配置文件中写SQL语句:

<update id="update">
        update tb_brand
        <set>
            <if test="status != null">
                status = #{status},
            </if>
            <if test="brandName != null and brandName !=''">
                brand_name = #{brandName},
            </if>
            <if test="companyName != null and companyName !=''">
                company_name = #{companyName},
            </if>
            <if test="ordered != null">
                ordered = #{ordered},
            </if>
            <if test="description != null and description !=''">
                description = #{description}
            </if>
        </set>
        where id = #{id}
    </update>

最后再写测试方法:

@Test
    public void testUpdate() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        Brand brand = new Brand();
        String brandName = "波导";
        String description = "波导手机,手机中的战斗机";
        String companyName = "波导有限公司";
        int ordered = 200;
        int id = 6;
        int status = 0;

//        brand.setBrandName(brandName);
//        brand.setDescription(description);
//        brand.setCompanyName(companyName);
//        brand.setOrdered(ordered);
        brand.setStatus(status);
        brand.setId(id);
//        brand.setStatus(1);
//        brand.setBrandName("%华为%");
//        brand.setCompanyName("%华为%");
//        Map map = new HashMap();
//        map.put("status",1);
        //map.put("companyName","%华为%");
//        map.put("brandName","%华为%");
        //List<Brand> brands = brandMapper.selectByCondition(1, "%华为%", "%华为%");
        brandMapper.update(brand);
        //System.out.println(brand.getId());
        //提交事务
//        sqlSession.commit();

        sqlSession.close();
    }

删除一个:
在这里插入图片描述

BrandMaper接口:
在这里插入图片描述

BrandMapper.xml配置文件:
在这里插入图片描述

测试方法:

 @Test
    public void testDeleteById() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        int id = 6;
        brandMapper.deleteById(id);

        sqlSession.close();
    }

批量删除:
在这里插入图片描述
BrandMapper接口:
在这里插入图片描述
BrandMapper.xml配置文件:
在这里插入图片描述测试方法:

 @Test
    public void testDeleteByIds() throws IOException {

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

        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        int[] ids = {5,7,8};
        brandMapper.deleteByIds(ids);

        sqlSession.close();
    }

注意:mybatis会将数据组封装为Map集合
默认情况下:array = 数组
可以使用param注解来修改map集合原始键的名称array为想要的名称。
separator:将每个元素通过“,”隔开
open:开始的时候拼一个“(”,close:结束的时候拼一个“)”。
参数传递:
MyBatis 参数封装:
* 单个参数:
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集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put(“arg0”,参数值1)
map.put(“param1”,参数值1)
map.put(“param2”,参数值2)
map.put(“agr1”,参数值2)
---------------@Param(“username”)
map.put(“username”,参数值1)
map.put(“param1”,参数值1)
map.put(“param2”,参数值2)
map.put(“agr1”,参数值2)
注解开发:
在这里插入图片描述在这里插入图片描述

例子:在这里插入图片描述

4、JavaScript

  • 基本语法
    输出语句:
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="../JS/demo.js"></script>
</head>
<body>
<script>
  window.alert("hello js1");//写入警告框
  document.write("hello js1");//写入html文件
  console.log("hello js1");//写入浏览器控制台
</script>
</body>
</html>

变量:
• 变量名需要遵循如下规则:
组成字符可以是任何字母、数字、下划线( _ )或美元符号( $ )
数字不能开头
建议使用驼峰命名
• ECMAScript 6 新增了 let 关键字来定义变量。它的用法类似于 var ,但
是所声明的变量,只在 let 关键字所在的代码块内有效,且不允许重复声明
• ECMAScript 6 新增了 const 关键字,用来声明一个只读的常量。一旦声
明,常量的值就不能改变。
在这里插入图片描述
数据类型:
在这里插入图片描述
运算符:
在这里插入图片描述
在这里插入图片描述

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

</head>
<body>
<script>
  /*
    ==:
        1、如果两者类型不一致,则先转为相同的类型
        2、再比较值
    ===:全等于
        1、如果两者类型不一致,则直接返回false
        2、如果类型一致在比较值
 * */
  // var a = 20;
  // var b = "20";
  // alert(a == b)//true
  // alert(a === b)//false
  /*
   类型转换:
         其他类型转为number:
            1、String:按照字面值转为数字,如果字面值不是数字,则转为NAN
            2、boolean:true转为1,false转为0.
 * */
   var s = "20"
  // var s1 = +s;//第一种方式
  // var s2 = parseInt(s)//第二种方式
  // alert(typeof s1)
  // alert(typeof s2)

  //健壮性判断
  //if(s!=null&&s.length>0)
  if(s){
    alert("转为true")
  }else{
    alert("转为false")
  }
</script>
</body>
</html>

函数:
在这里插入图片描述

  • JavaScript对象
    Array对象:
    在这里插入图片描述在这里插入图片描述
    自定义对象:
    在这里插入图片描述

  • BOM

在这里插入图片描述

Window:
在这里插入图片描述
定时器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
//定时器
//1、setTimeout(function,毫秒值),过一段时间执行function,执行一次
setTimeout(function (){
  alert("hello")
},3000)
//2、setInterval(function,毫秒值),过一段时间执行function,循环执行
setInterval(function (){
  alert("world")
},2000)
</script>
</body>
</html>

案例:

在这里插入图片描述

代码:
在这里插入图片描述
在这里插入图片描述
History:
在这里插入图片描述
Location
在这里插入图片描述案例:三秒后跳回百度首页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>

for (let i = 3; i > 0; i--) {
  document.write(i+"秒后跳入百度首页......\n");
}
setTimeout(function (){
  window.location.href = "https://www.baidu.com";
},3000)
</script>
</body>
</html>
  • DOM

在这里插入图片描述获取ELement:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<img id = "img" src="../images/1.jpg" width="500px" height="500px">

<div class = "cls">123</div>
<div class = "cls">456</div>

<input type = "checkbox" name = "hobby">电影
<input type = "checkbox" name = "hobby">音乐
<input type = "checkbox" name = "hobby">美术

<script>
    //获取img对象
    var img = document.getElementById("img");
    img.src = "../images/2.jpg";

    var divs = document.getElementsByTagName("div");
    for (let i = 0; i < divs.length; i++) {
        //设置元素CSS样式
        divs[i].style.color = 'red';
        //改变文本内容
        divs[i].innerHTML = "hello"
    }
    var hobbys = document.getElementsByName("hobby");
    for (let i = 0; i < hobbys.length; i++) {
        hobbys[i].checked = true;
    }

</script>
</body>
</html>
  • 事件监听
    事件绑定:
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type = "button" value = "点我" onclick = "dot()"><br>
<input type = "button" value = "再点我" id = "btn">
</body>
<script>
  //第一种方式
  function dot(){
    alert("点了一下")
  }
  //第二种方式
  document.getElementById("btn").onclick = function on(){
    alert("又点了一下")
  }
</script>
</html>

常见事件:
在这里插入图片描述
案例1:
在这里插入图片描述思路:
在这里插入图片描述代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form id="form" method="post" autocomplete="off" action="#">
    <label>用户名:</label>
    <input id="username" type="text" name="username" placeholder="请输入长度在6-12位的用户名" required="required">
    <br>
    <span id="userNameError" style="color: red;display:none">用户名格式不正确!</span>
    <br>


    <label>密码:</label>
    <input id="password" type="password" name="password" placeholder="请输入长度在6-12位的密码" required="required">
    <br>
    <span id="passwordError" style="color: red;display: none">密码格式不正确!</span>
    <br>


    <label>手机号:</label>
    <input id="phone" type="text" name="phone" placeholder="请输入符合格式的手机号" required="required">
    <br>
    <span id="phoneError" style="color: red;display: none">手机号格式不正确!</span>
    <input type="submit" value="提交">
</form>
<script>
    //登录
    //获取用户输入框
    var usernameInput = document.getElementById("username");
    //绑定事件
    usernameInput.onblur = checkUserName;

    function checkUserName() {
        //获取用户输入的用户名
        var username = usernameInput.value.trim();
        //判断用户输入的用户名是否符合规则:长度6-12
        var flag = (username.length >= 6 && username.length <= 12);
        if (flag) {
            document.getElementById("userNameError").style.display = "none";
        } else {
            document.getElementById("userNameError").style.display = "initial";
        }
        return flag;
    }


    var passwordInput = document.getElementById("password");
    //绑定事件
    passwordInput.onblur = checkPassWord;

    function checkPassWord() {
        //获取用户输入的用户名
        var password = passwordInput.value.trim();
        //判断用户输入的用户名是否符合规则:长度6-12
        var flag = (password.length >= 6 && password.length <= 12);
        if (flag) {
            document.getElementById("passwordError").style.display = "none";
        } else {
            document.getElementById("passwordError").style.display = "initial";
        }
        return flag;

    }


    var phoneInput = document.getElementById("phone");
    //绑定事件
    phoneInput.onblur = checkPhone;

    function checkPhone() {
        //获取用户输入的用户名
        var phone = phoneInput.value.trim();
        //判断用户输入的用户名是否符合规则:长度6-12
        var flag = phone.length == 11 ;
        if (flag) {
            document.getElementById("phoneError").style.display = "none";
        } else {
            document.getElementById("phoneError").style.display = "initial";
        }
        return flag;
    }

    //获得表单对象
    var form = document.getElementById("form");
    form.onsubmit = function () {
        var flag = checkPhone() && checkUserName() && checkPassWord();

        return flag;
    }


</script>
</body>
</html>

正则表达式:
在这里插入图片描述用正则表达式修改登录案例:
用户名:
在这里插入图片描述

密码:
在这里插入图片描述

手机号:

在这里插入图片描述

5、Http&Tomcat&Servlet

创建Maven Web项目:
使用骨架:
在这里插入图片描述
将pom中的多余坐标删除,然后新建Java和resource文件夹
在这里插入图片描述

错误:Plugin ‘maven-clean-plugin:3.1.0’ not found
解决方案:点击进入
不适用骨架:
在这里插入图片描述使用Tomcat Maven插件来启动Tomcat
在pom中使用快捷键Alt+Insert,创建插件模板,配置Tomcat插件:


  <build>
    <plugins>
      <!--Tomcat 插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <!--端口号-->
          <port>9999</port>
          <!--路径-->
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>

运行:
在这里插入图片描述

错误:IDEA中找不到maven插件Plugin ‘org.apache.tomcat.maventomcat7-maven-plugin2.2‘ not found
两种方法结合使用:第一种:点击进入
第二种:点击进入
给webapp文件夹添加小蓝点:点击进入
Servlet快速入门:

在这里插入图片描述错误:Dependency ‘javax.servlet:servlet-api:3.1.0’ not found
Cannot resolve javax.servlet:servlet-api:3.1.0
解决方法:点击进入
错误:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project MavenWebTest: Fatal error compiling
注意:把该解决方案里面的所以配置全部配成一个版本的,然后重启,大概率解决疑难杂症等问题。
解决方案:点击进入
如果servlet依赖不添加< scope > provided < scope > 属性会出现这个错误:
Failed to execute goal org.apache.tomcat.maven:tomcat7-maven-plugin:2.2:run (default-cli) on project mybatis-demo: Could not start Tomcat
解决方案:添加上< scope > provided < scope >
URL配置规则:

在这里插入图片描述request通用方式获取参数:
在这里插入图片描述
关于IDEA直接创建Servlet程序时找不到new Servlet按钮的解决方法
点击进入
修改Idea中的Servlet模板:
在这里插入图片描述

5、JSP&EL&JSTL

  • JSP

快速入门:
在这里插入图片描述
案例:
在这里插入图片描述
index.jsp

<%@ page import="pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<%
    List<Brand> brands = new ArrayList<Brand>();
    brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
    brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
    brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));
%>
<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>


    <%
        for (int i = 0; i < brands.size(); i++) {
    %>
    <tr align="center">
        <td><%=brands.get(i).getId()%></td>
        <td><%=brands.get(i).getBrandName()%></td>
        <td><%=brands.get(i).getCompanyName()%></td>
        <td><%=brands.get(i).getOrdered()%></td>
        <td><%=brands.get(i).getDescription()%></td>

        

        <%
            if(brands.get(i).getStatus() == 1){
                //显示启用

        %>
        <td>启用</td>
        <%
            }else{
                //显示禁用
           %>
        <td>禁用</td>

        <%
            }
        %>

        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>

    <%
        }
    %>


</table>

</body>
</html>

Brand:

package pojo;

/**
 * 品牌实体类
 */

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;


    public Brand() {
    }

    public Brand(Integer id, String brandName, String companyName, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }

    public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

  • EL表达式

在这里插入图片描述
代码:

<%@ page isELIgnored="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>

    </title>
</head>
<body>
         ${brands}
</body>
</html>

注意:一般JSP页面默认关闭对EL表达式的检测,所以得打开,用这句代码:<%@ page isELIgnored=“false” %>实现,
双重否定表肯定。

  • JSTL
    在这里插入图片描述
    依赖:
<dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

标签库:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

< c:if >与EL表达式结合:

<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        <c:if test="true">
            <h1>true</h1>
        </c:if>


        <c:if test="false">
            <h1>false</h1>
        </c:if>


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

        <c:if test="${status == 0}">
            <h1>禁用</h1>
        </c:if>

</body>
</html>

< c: foreach >的使用:
前端:

<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
       <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="sort">
                <tr>
                    <%--<td>${brand.id}</td>--%>
                    <%--
                    sort.index从0开始
                    sort.count从1开始
                    --%>
                    <td>${sort.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>
                </tr>
           </c:forEach>
       </table>


<c:forEach begin="0" end = "10" step = "1" var = "i">
    <a href="#">${i}</a>
</c:forEach>
</body>
</html>

servlet:

package servlet;

import pojo.Brand;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/el")
public class ELServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        List<Brand> brands = new ArrayList<Brand>();
        brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
        brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
        brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));

        request.setAttribute("brands",brands);
        request.setAttribute("status",1);
        request.getRequestDispatcher("JSTL.jsp").forward(request,response);
    }

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

效果图:
在这里插入图片描述
案例练习:
在这里插入图片描述

6、Cookie&Session

Cookie与Session都是会话追踪技术,不同的是Cookie是面向客户端的,数据存储在浏览器中,而Session是面向服务器的,数据存储在服务器中,而Cookie数据默认随着浏览器的关闭而销毁,所以想要长久的保留Cookie数据,就需要设置Cookie的setMaxAge(),而数据存储在服务器中的Session,不会随着服务器的关闭而销毁。如果重启服务器再次访问Session数据,还是可以访问到的,但是前提是同一个浏览器。

  • Cookie
    Cookie的基本使用:
    在这里插入图片描述AServlet:创建Cookie
package servlet;

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

@WebServlet("/a")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie

        //创建Cookie对象
        Cookie cookie = new Cookie("username","zs");
        //发送Cookie,浏览器自动存储Cookie数据
        response.addCookie(cookie);
    }

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

BServlet:获取Cookie

package servlet;

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

@WebServlet("/b")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Cookie

        //通过request向浏览器请求Cookie数据
        Cookie[] cookies = request.getCookies();
        //遍历Cookies,获取想要的Cookie
        for (Cookie cookie : cookies) {
            //获取每一个Cookie的name
            String name = cookie.getName();
            if("username".equals(name)){
                String value = cookie.getValue();
                System.out.println(name+":"+value);
                break;
            }
        }
    }

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

Cookie细节:
存活时间与存储中文:
在这里插入图片描述设置Cookie的存活时间:
单位是秒

//设置存活时间    一周
        cookie.setMaxAge(60*60*24*7);

存储中文:
发送Cookie:

package servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet("/a")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie

        //创建Cookie对象
        String value = "张三";
        //URL编码
         value = URLEncoder.encode(value, "UTF-8");
        Cookie cookie = new Cookie("username",value);
        System.out.println("value:"+value);
        //设置存活时间
        cookie.setMaxAge(60*60*24*7);
        //发送Cookie,浏览器自动存储Cookie数据
        response.addCookie(cookie);
    }

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

获取Cookie:

package servlet;

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

@WebServlet("/b")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Cookie

        //通过request向浏览器请求Cookie数据
        Cookie[] cookies = request.getCookies();
        //遍历Cookies,获取想要的Cookie
        for (Cookie cookie : cookies) {
            //获取每一个Cookie的name
            String name = cookie.getName();
            if("username".equals(name)){
                String value = cookie.getValue();
                //URL解码
                value = URLDecoder.decode(value, "UTF-8");
                System.out.println(name+":"+value);
                break;
            }
        }
    }

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

  • Session
    基本使用:
    在这里插入图片描述
    Session存储数据:
package servlet;

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

@WebServlet("/s1")
public class Session1Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Session
        HttpSession session = request.getSession();
        //存储数据
        session.setAttribute("username", "zs");
    }

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

Session获取数据:

package servlet;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/s2")
public class Session2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session
        HttpSession session = request.getSession();
        //获取数据
        Object username = session.getAttribute("username");
        System.out.println(username);
    }

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

Session原理:Session是基于Cookie实现的
Session细节:
在这里插入图片描述
Cookie与Session的区别:
在这里插入图片描述
记住密码案例:
在这里插入图片描述Servlet:

package web;

import pojo.User;
import service.UserService;

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

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        String remember = request.getParameter("remember");

        UserService userService = new UserService();

        User user = userService.login(username, password);

        if (user != null) {
            //登录成功

            //存储登录成功的user信息
            HttpSession session = request.getSession();
            session.setAttribute("user", user);

            //记住密码功能
            if ("1".equals(remember)) {
                //勾选了记住密码
                //创建Cookie对象
                Cookie cookie1 = new Cookie("username", username);
                Cookie cookie2 = new Cookie("password", password);
                //设置Cookie存活时间      一周
                cookie1.setMaxAge(60 * 60 * 24 * 7);
                cookie2.setMaxAge(60 * 60 * 24 * 7);
                //发送Cookie
                response.addCookie(cookie1);
                response.addCookie(cookie2);
            } else {
                //没有勾选记住密码,清除所有的用户名、密码Cookie数据
                Cookie[] cookies = request.getCookies();
                //for循环,将每个用户名、密码Cookie数据的存活时间置为0
                for (Cookie cookie : cookies) {
                    String name = cookie.getName();
                    System.out.println(name);
                    if ("username".equals(cookie.getName())) {
                        cookie.setMaxAge(0);
                        response.addCookie(cookie);
                    }
                    if ("password".equals(cookie.getName())) {
                        cookie.setMaxAge(0);
                        response.addCookie(cookie);
                    }
                }
            }

            response.sendRedirect("selectAll");


        } else {
            //登录失败
            //存储登录失败信息
            HttpSession session = request.getSession();
            session.setAttribute("login_err", "用户名或密码错误!");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }

    }

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

在这里插入图片描述
login.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>

<div id="loginDiv" style="height: 350px">
    <form action="login" id="form" method="post">
        <h1 id="loginMsg">LOGIN IN</h1>
        <div id="errorMsg" style="color: red;text-align: center">${login_err}</div>
        <p>Username:<input id="username" name="username" type="text" value="${cookie.username.value}"></p>

        <p>Password:<input id="password" name="password" type="password" value="${cookie.password.value}"></p>
        <p>Remember:<input id="remember" name="remember" type="checkbox" value="1"></p>
        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">没有账号?</a>
        </div>
    </form>
</div>

</body>
</html>

实现验证码功能
第一步:展示验证码
在这里插入图片描述
首先引入checkCodeUtil类:

package util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;

/**
 * 生成验证码工具类
 */
public class CheckCodeUtil {

    public static final String VERIFY_CODES = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static Random random = new Random();



    /**
     * 输出随机验证码图片流,并返回验证码值(一般传入输出流,响应response页面端,Web项目用的较多)
     *
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }

    /**
     * 使用系统默认字符源生成验证码
     *
     * @param verifySize 验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize) {
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }

    /**
     * 使用指定源生成验证码
     *
     * @param verifySize 验证码长度
     * @param sources    验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String sources) {
        // 未设定展示源的字码,赋默认值大写字母+数字
        if (sources == null || sources.length() == 0) {
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for (int i = 0; i < verifySize; i++) {
            verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
        }
        return verifyCode.toString();
    }

    /**
     * 生成随机验证码文件,并返回验证码值 (生成图片形式,用的较少)
     *
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }



    /**
     * 生成指定验证码图像文件
     *
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
        if (outputFile == null) {
            return;
        }
        File dir = outputFile.getParentFile();
        //文件不存在
        if (!dir.exists()) {
            //创建
            dir.mkdirs();
        }
        try {
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 输出指定验证码图片流
     *
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 创建颜色集合,使用java.awt包下的类
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW};
        float[] fractions = new float[colors.length];
        for (int i = 0; i < colors.length; i++) {
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
        // 设置边框色
        g2.setColor(Color.GRAY);
        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);
        // 设置背景色
        g2.setColor(c);
        g2.fillRect(0, 2, w, h - 4);

        // 绘制干扰线
        Random random = new Random();
        // 设置线条的颜色
        g2.setColor(getRandColor(160, 200));
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }

        // 添加噪点
        // 噪声率
        float yawpRate = 0.05f;
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            // 获取随机颜色
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
        // 添加图片扭曲
        shear(g2, w, h, c);

        g2.setColor(getRandColor(100, 160));
        int fontSize = h - 4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for (int i = 0; i < verifySize; i++) {
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
        }

        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }

    /**
     * 随机颜色
     *
     * @param fc
     * @param bc
     * @return
     */
    private static Color getRandColor(int fc, int bc) {
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }

    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }

    private static void shear(Graphics g, int w1, int h1, Color color) {
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }

    private static void shearX(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(2);

        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);

        for (int i = 0; i < h1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(0, i, w1, 1, (int) d, 0);
            if (borderGap) {
                g.setColor(color);
                g.drawLine((int) d, i, 0, i);
                g.drawLine((int) d + w1, i, w1, i);
            }
        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(40) + 10; // 50;

        boolean borderGap = true;
        int frames = 20;
        int phase = 7;
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }

        }

    }
}


然后写一个Servlet:

package web;

import util.CheckCodeUtil;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletOutputStream os = response.getOutputStream();
        CheckCodeUtil.outputVerifyImage(100,50,os,4);
    }

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

最后给图片绑定事件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎注册</title>
    <link href="css/register.css" rel="stylesheet">
</head>
<body>

<div class="form-div">
    <div class="reg-content">
        <h1>欢迎注册</h1>
        <span>已有帐号?</span> <a href="login.html">登录</a>
    </div>
    <form id="reg-form" action="register" method="get">

        <table>

            <tr>
                <td>用户名</td>
                <td class="inputs">
                    <input name="username" type="text" id="username">
                    <br>
                    <span id="username_err" class="err_msg">${register_msg}</span>
                </td>

            </tr>

            <tr>
                <td>密码</td>
                <td class="inputs">
                    <input name="password" type="password" id="password">
                    <br>
                    <span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
                </td>
            </tr>


            <tr>
                <td>验证码</td>
                <td class="inputs">
                    <input name="checkCode" type="text" id="checkCode">
                    <img src="checkCode" id = "checkCodeImg">
                    <a href="#" id="changeImg">看不清?</a>
                </td>
            </tr>

        </table>

        <div class="buttons">
            <input value="注 册" type="submit" id="reg_btn">
        </div>
        <br class="clear">
    </form>

</div>
<script>
    /*点击文字更换验证码照片*/
    document.getElementById("changeImg").onclick = function (){
        document.getElementById("checkCodeImg").src = "checkCode?"+new Date().getMilliseconds();
    }
    /*点击图片更换验证码照片*/
    document.getElementById("checkCodeImg").onclick = function (){
        document.getElementById("checkCodeImg").src = "checkCode?"+new Date().getMilliseconds();
    }
</script>
</body>
</html>

在这里插入图片描述
第二步校验验证码:
将系统生成的验证码用Session的域进行保存
在这里插入图片描述

package web;

import util.CheckCodeUtil;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //生成验证码
        ServletOutputStream os = response.getOutputStream();
        String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);

        //校验验证码
        //存入Session中
        HttpSession session = request.getSession();
        session.setAttribute("checkCodeGen",checkCode);
    }

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

然后在注册的时候获取用户输入的验证码将这者进行验证,校验验证码要在注册前面:
在这里插入图片描述

package web;

import pojo.User;
import service.UserService;

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

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = new User(username,password);

        //获取用户输入的验证码
        String checkCode = request.getParameter("checkCode");
        //获取系统生成的验证码
        HttpSession session = request.getSession();
        String checkCodeGen = (String) session.getAttribute("checkCodeGen");

        //将两个验证码进行比对
        if(!checkCodeGen.equals(checkCode)){
            //不允许注册
            request.setAttribute("register_msg","验证码输入有误!");
            request.getRequestDispatcher("register.jsp").forward(request,response);
            return;
        }



        UserService userService = new UserService();
        boolean flag = userService.register(user);
        if(flag){
            //注册成功
            request.setAttribute("register_msg","注册成功,请登录!");
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }else{
            //注册失败
            request.setAttribute("register_msg","用户名已存在!");
            request.getRequestDispatcher("register.jsp").forward(request,response);
        }
    }

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

7、Filter&Listener

  • Filter
    快速入门:

在这里插入图片描述执行流程:
放行前:对request数据进行处理
放行
放行后:对response数据进行处理
在这里插入图片描述拦截路径配置:
在这里插入图片描述过滤器链:
多个过滤器,优先级是按照类名字符串进行自然排序
在这里插入图片描述

案例:
这里要分两步走,第一步是要先将有关注册登录的资源进行无条件放行,比如登录页面、CSS、Servlet、验证码等等
第二步就是判断Session域里面的是否存在登录应存入的数据,如果没有则说明还未登录,需要跳转到登录页面。
在这里插入图片描述LoginFilter:

package web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.http.HttpRequest;

@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //判断访问的路径是否和登录注册相关,凡是和登录注册资源相关的,全部放行
        String [] urls = {"login.jsp","/css/","/imgs/","register.jsp","checkCode","register","login"};
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获取当前访问的资源路径
        String url = request.getRequestURL().toString();
        for (String u : urls) {
            //访问资源与登录注册相关,无条件放行
            if(url.contains(u)){
                filterChain.doFilter(request,servletResponse);
                //由于放行后,响应数据回来的时候还需要经过过滤器,
                //但是后面的代码是有关登录过滤的,所以此时用户已经在这放行登录过了,所以应该return掉这个方法
                return;

            }
        }


        //判断Session里面有没有user来进行判断是否过滤

        //获取Session
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        if (user != null) {
            //登录过了
            //放行
            filterChain.doFilter(request, servletResponse);
        } else {
            //还未登录,存储提示信息,跳转到登录页面
            request.setAttribute("login_msg", "您还未登录!");
            request.getRequestDispatcher("login.jsp").forward(request, servletResponse);
        }
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void destroy() {

    }
}

  • Listener
    在这里插入图片描述

在这里插入图片描述

8、AJAX&Axios&JSON

  • AJAX
    在这里插入图片描述

快速入门:

在这里插入图片描述AjaxDemo.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
  /*1、创建核心对象*/
  var xhttp = new XMLHttpRequest();
  /*2、发送请求*/
  xhttp.open("GET", "http://localhost:9999/ajax");
  xhttp.send();
  /*3、获取响应*/
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {

              alert(this.responseText)
    }
  };
</script>
</body>
</html>

AjaxServlet:

package servlet;

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

@WebServlet("/ajax")
public class AjaxServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //响应数据
        response.getWriter().write("hello AJAX!");
    }

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

案例:
在这里插入图片描述SelectUserServlet:
在这里插入图片描述这里将flag写死了,表示用户名已存在

package servlet;

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

@WebServlet("/selectUser")
public class SelectUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //接收用户名
        String username = request.getParameter("username");

        //调用service方法查看用户名是否存在
        boolean flag = true;

        //响应标记
        response.getWriter().write(""+flag);

    }

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

register.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎注册</title>
    <link href="css/register.css" rel="stylesheet">
</head>
<body>

<div class="form-div">
    <div class="reg-content">
        <h1>欢迎注册</h1>
        <span>已有帐号?</span> <a href="login.html">登录</a>
    </div>
    <form id="reg-form" action="#" method="get">

        <table>

            <tr>
                <td>用户名</td>
                <td class="inputs">
                    <input name="username" type="text" id="username">
                    <br>
                    <span id="username_err" class="err_msg" style="display: none;color: red">用户名已存在!</span>
                </td>

            </tr>

            <tr>
                <td>密码</td>
                <td class="inputs">
                    <input name="password" type="password" id="password">
                    <br>
                    <span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
                </td>
            </tr>


            <tr>
                <td>验证码</td>
                <td class="inputs">
                    <input name="checkCode" type="text" id="checkCode">
                    <img src="imgs/a.jpg">
                    <a href="#" id="changeImg">看不清?</a>
                </td>
            </tr>

        </table>

        <div class="buttons">
            <input value="注 册" type="submit" id="reg_btn">
        </div>
        <br class="clear">
    </form>

</div>
<script>
    //给用户名输入框绑定失去焦点事件
    document.getElementById("username").onblur = function (){
            //发送ajax请求
        //获取用户名的值
        var username = this.value;

        /*1、创建核心对象*/
        var xhttp = new XMLHttpRequest();
        /*2、发送请求*/
        xhttp.open("GET", "http://localhost:9999/selectUser?username="+username);
        xhttp.send();
        /*3、获取响应*/
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                //
                // alert(this.responseText)
                //判断
                if(this.responseText == "true"){
                    //用户名已存在  给出提示信息
                    document.getElementById("username_err").style.display = '';
                }else{
                    //用户名不存在  清除提示信息
                    document.getElementById("username_err").style.display = 'none';
                }
            }
        };
    }

</script>
</body>
</html>
  • Axios
    使用之前需要先导入文件Axios文件:
    在这里插入图片描述

在这里插入图片描述
AxiosDemo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src = "js/axios-0.18.0.js"></script>
<script>
  //GET请求方式
  // axios({
  //   method:"get",
  //   url:"http://localhost:9999/axios?username=zhangsan"
  // }).then(function (response){
  //   alert(response.data)
  // })
  //POST请求方式
  axios({
    method:"post",
    url:"http://localhost:9999/axios",
    data:"username=zhangsan"
  }).then(function (response){
    alert(response.data)
  })

</script>
</body>
</html>

AxiosServlet:

package servlet;

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("/axios")
public class AxiosServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("get............");
        //接收请求参数
        String username = request.getParameter("username");

        System.out.println(username);

        //响应数据
        response.getWriter().write("hello Axios!");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("post................");
        this.doGet(request, response);
    }
}

Axios实现对用户名的检测:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎注册</title>
    <link href="css/register.css" rel="stylesheet">
</head>
<body>

<div class="form-div">
    <div class="reg-content">
        <h1>欢迎注册</h1>
        <span>已有帐号?</span> <a href="login.html">登录</a>
    </div>
    <form id="reg-form" action="#" method="get">

        <table>

            <tr>
                <td>用户名</td>
                <td class="inputs">
                    <input name="username" type="text" id="username">
                    <br>
                    <span id="username_err" class="err_msg" style="display: none;color: red">用户名已存在!</span>
                </td>

            </tr>

            <tr>
                <td>密码</td>
                <td class="inputs">
                    <input name="password" type="password" id="password">
                    <br>
                    <span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
                </td>
            </tr>


            <tr>
                <td>验证码</td>
                <td class="inputs">
                    <input name="checkCode" type="text" id="checkCode">
                    <img src="imgs/a.jpg">
                    <a href="#" id="changeImg">看不清?</a>
                </td>
            </tr>

        </table>

        <div class="buttons">
            <input value="注 册" type="submit" id="reg_btn">
        </div>
        <br class="clear">
    </form>

</div>
<script src="js/axios-0.18.0.js"></script>
<script>
    //给用户名输入框绑定失去焦点事件
    document.getElementById("username").onblur = function () {
        //发送axios请求
        //获取用户名的值
        var username = this.value;
        //Get方式
        axios.get("http://localhost:9999/selectUser?username="+username).then(function (response){
            alert(typeof response.data);
            if(response.data == "true"){
                document.getElementById("username_err").style.display = '';

            }else{
                document.getElementById("username_err").style.display = 'none';
            }
        });
        //Post方式
        // axios.post("http://localhost:9999/selectUser", "username=" + username).then(function (response) {
        //     alert(typeof response.data)
        //     if (response.data) {
        //         document.getElementById("username_err").style.display = '';
        //     } else {
        //         document.getElementById("username_err").style.display = 'none';
        //     }
        // });

    }

</script>
</body>
</html>
  • JSON
    基础语法:
    在这里插入图片描述
    JSON数据与Java对象的相互转换:
    在这里插入图片描述
<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.62</version>
    </dependency>
package test;

import com.alibaba.fastjson.JSON;
import pojo.User;

public class Test {
    public static void main(String[] args) {
        User user =new User(1,"cfl","123");
        //Java对象转为JSON数据
        String jsonString = JSON.toJSONString(user);
        System.out.println(jsonString);
        //JSON数据转为Java对象
        User u = JSON.parseObject("{\"id\":1,\"password\":\"123\",\"username\":\"cfl\"}", User.class);
        System.out.println(u);
    }
}

使用Axios+JSON完成对品牌列表的查询和添加:
在这里插入图片描述查询:
SelectAllServlet:

package web;

import com.alibaba.fastjson.JSON;
import pojo.Brand;
import 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("/selectAll")
public class SelectAllServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //调用BrandService方法
        BrandService brandService = new BrandService();
        List<Brand> brands = brandService.selectAll();
        //数据中可能存在中文,需要转码为JSON格式
        response.setContentType("text/json;charset=utf-8");
        //将集合转为JSON格式  序列化
        String jsonString = JSON.toJSONString(brands);
        //用response写回去
        response.getWriter().write(jsonString);
    }

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

brand.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="addBrand.html"><input type="button" value="新增"></a><br>
<hr>
<table id="brandTable" border="1" cellspacing="0" width="100%">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <tr align="center">
        <td>1</td>
        <td>三只松鼠</td>
        <td>三只松鼠</td>
        <td>100</td>
        <td>三只松鼠,好吃不上火</td>
        <td>启用</td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>

    <tr align="center">
        <td>2</td>
        <td>优衣库</td>
        <td>优衣库</td>
        <td>10</td>
        <td>优衣库,服适人生</td>
        <td>禁用</td>

        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>

    <tr align="center">
        <td>3</td>
        <td>小米</td>
        <td>小米科技有限公司</td>
        <td>1000</td>
        <td>为发烧而生</td>
        <td>启用</td>

        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
</table>
<script src = "js/axios-0.18.0.js"></script>
<script>
    //当页面加载完成后,发送Axios请求
    window.onload = function (){
        axios.post("http://localhost:9999/selectAll",).then(function (response){
            //获取数据,response返回的是JSON数组
            var brands = response.data;
            let tableData = "<tr>\n" +
                "        <th>序号</th>\n" +
                "        <th>品牌名称</th>\n" +
                "        <th>企业名称</th>\n" +
                "        <th>排序</th>\n" +
                "        <th>品牌介绍</th>\n" +
                "        <th>状态</th>\n" +
                "        <th>操作</th>\n" +
                "    </tr>";
            for (let i = 0; i < brands.length; i++) {
               let brand =  brands[i];
                tableData+="<tr align=\"center\">\n" +
                    "        <td>"+(i+1)+"</td>\n" +
                    "        <td>"+brand.brandName+"</td>\n" +
                    "        <td>"+brand.companyName+"</td>\n" +
                    "        <td>"+brand.ordered+"</td>\n" +
                    "        <td>"+brand.description+"</td>\n" +
                    "        <td>"+brand.status+"</td>\n" +
                    "        <td><a href=\"#\">修改</a> <a href=\"#\">删除</a></td>\n" +
                    "    </tr>";
            }
            //设置表格数据
            document.getElementById("brandTable").innerHTML = tableData;

        })
    }
</script>
</body>
</html>

添加:
AddServlet:

package web;

import com.alibaba.fastjson.JSON;
import pojo.Brand;
import service.BrandService;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.BufferedReader;
import java.io.IOException;

@WebServlet("/add")
public class AddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //getParameter不能接收JSON数据
        //String brandName = request.getParameter("brandName");
        //System.out.println(brandName);
        //获取请求体数据
        BufferedReader reader = request.getReader();
        //获得JSON数据
        String s = reader.readLine();
        //JSON数据转为Java对象
        Brand brand = JSON.parseObject(s, Brand.class);
        System.out.println(brand);

        //调用Service方法
        BrandService brandService = new BrandService();
        brandService.add(brand);
        //响应成功标识
        response.getWriter().write("true");


    }

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

addBrand.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>添加品牌</title>
</head>
<body>
<h3>添加品牌</h3>
<form action="" method="post">
    品牌名称:<input id="brandName" name="brandName"><br>
    企业名称:<input id="companyName" name="companyName"><br>
    排序:<input id="ordered" name="ordered"><br>
    描述信息:<textarea rows="5" cols="20" id="description" name="description"></textarea><br>
    状态:
    <input type="radio" name="status" value="0">禁用
    <input type="radio" name="status" value="1">启用<br>
    <input type="button" id="btn"  value="提交">
</form>

<script src = "js/axios-0.18.0.js"></script>
<script>
    document.getElementById("btn").onclick = function (){
        //将表单数据转为JSON
        var formData = {
            brandName:"",
            companyName:"",
            ordered:"",
            description:"",
            status:""
        };
        //获取表单数据
        let brandName = document.getElementById("brandName").value;
        formData.brandName = brandName;

        let companyName = document.getElementById("companyName").value;
        formData.companyName = companyName;

        let ordered = document.getElementById("ordered").value;
        formData.ordered = ordered;

        let description = document.getElementById("description").value;
        formData.description = description;

        var status = document.getElementsByName("status");
        for (let i = 0; i < status.length; i++) {
            if(status[i].checked){
                formData.status = status[i].value;
            }
        }
        alert(formData);
        //发送Axios请求
        axios.post("http://localhost:9999/add",formData).then(function (response) {
            //判断响应数据是否为true,为true说明添加成功
            if(response.data){
                //添加成功,跳转到查询全部页面
                location.href = "http://localhost:9999/brand.html";
            }else{
                alert("添加失败!");
            }
        })
    }
</script>
</body>
</html>

错误:Cannot invoke java.lang.Integer.intValue() because this.status is null
如果是查询全部数据,看看数据库中是否存在各个参数均为为空的数据。

9、Vue

快速入门:
在这里插入图片描述先导入Vue文件
在这里插入图片描述
还要安装vue.js插件
在这里插入图片描述

vue-demo1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id = "app">
  <input v-model = "username">
  <!--插值表达式-->
  {{username}}
</div>



<script src = "js/vue.js"></script>
<script>
    //创建Vue核心对象
    new Vue({
      el:"#app",
      data(){
        return{
            username:""
        }
      }
    })

</script>
</body>
</html>

常用指令:
在这里插入图片描述
在这里插入图片描述
vue-demo2:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id = "app">
  <a v-bind:href="url">百度</a><br>
    <!--简化格式-->
    <a :href="url">百度</a>
    <input v-model="url">
</div>



<script src = "js/vue.js"></script>
<script>
    //创建Vue核心对象
    new Vue({
      el:"#app",
      data(){
        return{
            username:"",
            url:"https://www.baidu.com"
        }
      }
    })

</script>
</body>
</html>

在这里插入图片描述vue-demo3:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<div id="app">
    <input type="button" v-on:click="show()" value="点击"><br>
    <!--另一种写法-->
    <input type="button" @click="show()" value="点击">
</div>


<script src="js/vue.js"></script>
<script>
    //创建Vue核心对象
    new Vue({
        el: "#app",
        data() {
            return {
                username: "",
                url: "https://www.baidu.com"
            }
        },
        methods: {
            show() {
                alert("点了一下");
            }
        }
    });

</script>
</body>
</html>

在这里插入图片描述

vue-demo4

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<div id="app">
    <div v-if="count == 3">div1</div>
    <div v-else-if="count == 4">div2</div>
    <div v-else>div3</div>
    <div v-show="count==3">div4</div>
    <input v-model="count">
</div>


<script src="js/vue.js"></script>
<script>
    //创建Vue核心对象
    new Vue({
        el: "#app",
        data() {
            return {
                username: "",
                url: "https://www.baidu.com",
                count:3
            }
        },
        methods: {
            show() {
                alert("点了一下");
            }
        },

    });

</script>
</body>
</html>

在这里插入图片描述vue-demo5:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<div id="app">
    <div v-for="addr in addrs">
        {{addr}}<br>
    </div>
    <hr>
    <div v-for="(addr,i) in addrs">
        {{i}}--{{addr}}<br>
    </div>
</div>


<script src="js/vue.js"></script>
<script>
    //创建Vue核心对象
    new Vue({
        el: "#app",
        data() {
            return {
                username: "",
                url: "https://www.baidu.com",
                count:3,
                addrs:["北京","上海","西安"]
            }
        },
        methods: {
            show() {
                alert("点了一下");
            }
        },

    });

</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值