后端学习 Java Web 下半部分(JSP~Vue&Element)

10 JSP

10.1 JSP概述&快速入门&原理

Java Server Pages Java服务端页面

  • 一种动态的网页技术,其中既可以定义HTML、CSS、JS等静态内容,还可以定义Java代码的动态内容

  • JSP = HTML + Java

快速入门

  1. 导入JSP坐标
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2</version>
  <scope>provided</scope>
</dependency>
  1. 创建JSP文件

  2. 编写HTML标签和Java代码

<body>
    <h1>hello jsp</h1>
    <% System.out.printf("hello jsp ~"); %>
</body>

原理

JSP本质上就是一个Sevlet

10.2 JSP脚本
  • <%...%>:内容会直接放到_jspService()方法中

  • <%=...%>:内容会放到out.print()中,作为out.print()的参数

  • <%!...%>:内容会放到_jspService()方法之外,被类直接包含

10.3 JSP缺点

现在主流开发是Servlet + html + ajax

不过作为发展的一环,还是需要学习JSP

不要直接在JSP里写Java代码

10.4 EL表达式

Expression Language 表达式语言,用于简化JSP页面内的Java代码

  • 主要功能:获取数据

  • 语法:${expression}

    例如,${brands}表示获取域中存储的key为brands的数据

示例

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1.准备数据
    List<Brand> brands = new ArrayList<>();
    brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
    // 2.存储到request域中
    request.setAttribute("brands", brands);
    // 3.转发到el-demo.jsp
    request.getRequestDispatcher("/el-demo.jsp").forward(request, response);
}
<body>
${brands}
</body>
10.5 JSTL
  1. 导入坐标
<!--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>
  1. 在JSP页面上引入JSTL标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  1. 使用
  • <c:if>

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

    类似于 Java 中的增强for循环。涉及到的 <c:forEach> 中的属性如下

    • items:被遍历的容器

    • var:遍历产生的临时变量

    • varStatus:遍历状态对象

    如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值

    <c:forEach items="${brands}" var="brand">
        <tr align="center">
            <td>${brand.id}</td>
            <td>${brand.brandName}</td>
            <td>${brand.companyName}</td>
            <td>${brand.description}</td>
        </tr>
    </c:forEach>
    
  • <c:foreach>另一种用法

    类似于 Java 中的普通for循环。涉及到的 <c:forEach> 中的属性如下

    • begin:开始数

    • end:结束数

    • step:步长

    实例代码:

    从0循环到10,变量名是 i ,每次自增1

    <c:forEach begin="0" end="10" step="1" var="i">
        ${i}
    </c:forEach>
    
10.6 MVC模式和三层架构

MVC模式

  • M:Model,业务模型,处理业务

  • V:View,视图,界面展示

  • C:Controller,控制器,处理请求,调用模型和试图

M==>    JavaBean

V==>    JSP

C==>    Servlet

三层架构(体现了MVC思想)

表现层、业务逻辑层、数据访问层

  • 数据访问层:对数据库的CRUD基本操作    com.cookies.mapper

  • 业务逻辑层:对业务逻辑进行封装,组合数据访问层中基本功能,形成复杂的业务逻辑 com.cookies.service

  • 表现层:接受请求、封装数据、调用业务逻辑层、响应数据 com.cookies.web

SSM

浏览器==>表现层(SpringMVC)>业务逻辑层(Spring)>数据访问层(MyBatis)

10.7 案例-环境准备
  • 创建新的模块brand_demo,引入坐标

  • 创建三层架构的包结构

  • 数据库表tb_brand

  • 实体类Brand

  • MyBatis基础环境

    • MyBatis-config.xml

    • BrandMapper.xml

    • BrandMapper接口

创建新的模块 brand_demo ,引入坐标

在项目结构中创建空白模块

修改pom.xml

<packaging>war</packaging>

在项目结构中为brand-demo补齐部署描述符Web资源目录

修改pom.xml

<!--mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>
<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.34</version>
</dependency>
<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>
<!--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>

使用Alt + Insert插入插件

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

创建三层架构的包结构

|--|brand-demo
|--|--|src
|--|--|--|main
|--|--|--|--|java
|--|--|--|--|--|com.cookies
|--|--|--|--|--|--|mapper          //数据访问层
|--|--|--|--|--|--|pojo //实体类
|--|--|--|--|--|--|service         //业务逻辑层
|--|--|--|--|--|--|util //工具类
|--|--|--|--|--|--|web             //表现层

数据库表 tb_brand

实体类 Brand

放入com.cookies.pojo中

MyBatis 基础环境

MyBatis-config.xml放入brand-demo.src.main.resources中

按住Ctrl检查Mapper是否亮起

通过com\cookies\mapper在resources中创建文件夹

将BrandMapper.xml放入其中

在src/main/java/com/cookies/mapper文件夹中创建BrandMapper接口

10.8 案例-查询所有
|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|java //Java代码
|--|--|--|--|--|com.cookies //包目录
|--|--|--|--|--|--|mapper //数据访问层
|--|--|--|--|--|--|--|BrandMapper.class //访问数据库tb_brand的接口
|--|--|--|--|--|--|pojo //实体类
|--|--|--|--|--|--|--|Brand.class //存储访问的brand
|--|--|--|--|--|--|service //业务逻辑层
|--|--|--|--|--|--|--|BrandService.class //包装BrandMapper.class提供的函数
|--|--|--|--|--|--|util //工具类
|--|--|--|--|--|--|--|SqlSessionFactoryUtils //提供工厂函数
|--|--|--|--|--|--|web //表现层
|--|--|--|--|--|--|--|selectAllServlet //将得到的数据推送给jsp页面完成整套业务
|--|--|--|--|resources //资源代码
|--|--|--|--|--|com.cookies //目录
|--|--|--|--|--|--|mapper //数据访问
|--|--|--|--|--|--|--|BrandMapper.xml //与BrandMapper.class对应,提供SQL语句
|--|--|--|--|--|mybatis-config.xml //对于MyBatis的设置
|--|--|--|--|webapp //网页代码
|--|--|--|--|--|WEB-INF //默认自带,不用管
|--|--|--|--|--|index.html //默认访问的网页
|--|--|--|--|--|brand.jsp //最终呈现的页面
|--|--|--|test //测试代码
|--|--|pom.xml //maven环境配置
10.8.1 数据访问层

BrandMapper.xml

一般在写SQL代码前不必修改

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|resources //资源代码
|--|--|--|--|--|com.cookies //目录
|--|--|--|--|--|--|mapper //数据访问
|--|--|--|--|--|--|--|BrandMapper.xml //与BrandMapper.class对应,提供SQL语句
<?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.cookies.mapper.BrandMapper">

</mapper>

BrandMapper.class

此处因为SQL代码量不大,使用注解

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|java //Java代码
|--|--|--|--|--|com.cookies //包目录
|--|--|--|--|--|--|mapper //数据访问层
|--|--|--|--|--|--|--|BrandMapper.class //访问数据库tb_brand的接口
public interface BrandMapper {
    /**
     * 查询所有
     * @return
     */
    @Select("select * from tb_brand")
    List<Brand> selectAll();
}
10.8.2 业务逻辑层

SqlSessionFactoryUtils.class

为业务逻辑层提供工厂函数

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|java //Java代码
|--|--|--|--|--|com.cookies //包目录
|--|--|--|--|--|--|util //工具类
|--|--|--|--|--|--|--|SqlSessionFactoryUtils //提供工厂函数
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;
    }
}

BrandService.class

业务逻辑层,用以封装BrandMapper通过SQL实现的功能

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|java //Java代码
|--|--|--|--|--|com.cookies //包目录
|--|--|--|--|--|--|service //业务逻辑层
|--|--|--|--|--|--|--|BrandService.class //包装BrandMapper.class提供的函数
public class BrandService {
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /**
     * 查询所有
     * @return
     */
    public List<Brand> selectAll() {
        // 调用BrandMapper.selectAll

        // 2.获取SqlSession
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 4.调用方法
        List<Brand> brands = mapper.selectAll();
        sqlSession.close();
        return brands;
    }
}
10.8.3 表现层

SelectAllServlet.java

调用业务逻辑层获得数据,存入request域中转发到JSP页面

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|java //Java代码
|--|--|--|--|--|com.cookies //包目录
|--|--|--|--|--|--|web //表现层
|--|--|--|--|--|--|--|selectAllServlet //将得到的数据推送给jsp页面完成整套业务
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.调用BrandService完成查询
        List<Brand> brands = service.selectAll();

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

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

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

index.html

用户看到的初始界面

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|webapp //网页代码
|--|--|--|--|--|index.html //默认访问的网页
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/brand-demo/selectAllServlet">查询所有</a>
</body>
</html>

brand.jsp

用户看到的业务主体页面

|--|brand-demo
|--|--|src
|--|--|--|main //源代码
|--|--|--|--|webapp //网页代码
|--|--|--|--|--|brand.jsp //最终呈现的页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入jstl--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

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

<input type="button" value="新增"><br>

<hr>

<table border="1" cellspacing="0" width="80%">
    <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>${brand.id}</td>--%>
            <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>>
10.8.4 代码优化

因为数据库和实体类变量名不一致,导致无法显示;修改BrandMapper

BrandMapper.xml

<?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.cookies.mapper.BrandMapper">

    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>

</mapper>

BrandMapper.java

public interface BrandMapper {
    /**
     * 查询所有
     * @return
     */
    @Select("select * from tb_brand")
    @ResultMap("brandResultMap")
    List<Brand> selectAll();
}
10.9 案例-添加数据
10.9.1 数据访问层

BrandMapper.java

public interface BrandMapper {
    /**
     * 查询所有
     * @return
     */
    @Select("select * from tb_brand")
    @ResultMap("brandResultMap")
    List<Brand> selectAll();

    /**
     * 添加数据
     * @param brand
     */
    @Insert("insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    void add(Brand brand);
}
10.9.2 业务逻辑层

BrandService.java

public class BrandService {
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /**
     * 查询所有
     * @return
     */
    public List<Brand> selectAll() {
        // 调用BrandMapper.selectAll

        // 2.获取SqlSession
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 4.调用方法
        List<Brand> brands = mapper.selectAll();
        sqlSession.close();
        return brands;
    }

    /**
     * 添加数据
     * @param brand
     */
    public void add(Brand brand) {

        // 2.获取SqlSession
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 4.调用方法
        mapper.add(brand);

        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}
10.9.3 表现层

修改brand.jsp

<input type="button" value="新增" id="add"><br>


<script>
    document.getElementById("add").onclick = function () {
        location.href = "/brand-demo/addBrand.jsp";
    }
</script>

addBrand.jsp

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

    <input type="submit" value="提交">
</form>
</body>

AddServlet

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理POST乱码问题
        request.setCharacterEncoding("utf-8");

        // 1.接受表单提交的数据,封装为一个Brand对象
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");
        String description = request.getParameter("description");
        String status = request.getParameter("status");

        // 封装为一个Brand对象
        Brand brand = new Brand();
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setOrdered(Integer.parseInt(ordered));
        brand.setDescription(description);
        brand.setStatus(Integer.parseInt(status));

        // 2.调用service,完成添加
        service.add(brand);

        // 3.转发到查询所有Servlet
        request.getRequestDispatcher("/selectAllServlet").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
10.10 案例-修改-回显数据
10.10.1 数据访问层

BrandMapper.java

/**
 * 根据id查询
 * @param id
 * @return
 */
@Select("select * from tb_brand where id = #{id}")
@ResultMap("brandResultMap")
Brand selectById(int id);
10.10.2 业务逻辑层

BrandService.java

/**
 * 根据id查询
 * @return
 */
public Brand selectById(int id) {
    // 2.获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 3.获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 4.调用方法
    Brand brand = mapper.selectById(id);
    // 释放资源
    sqlSession.close();
    return brand;
}
10.10.3 表现层

修改brand.jsp

<td><a href="/brand-demo/selectByIdServlet?id=${brand.id}">修改</a> <a href="#">删除</a></td>

SelectByIdServlet

@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收id
        String id = request.getParameter("id");
        // 2.调用service
        Brand brand = service.selectById(Integer.parseInt(id));
        // 3.存储到request中
        request.setAttribute("brand",brand);

        // 4.转发到update.jsp
        request.getRequestDispatcher("/update.jsp").forward(request,response);
    }

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

update.jsp

<head>
    <meta charset="UTF-8">
    <title>修改</title>
</head>
<body>
<h3>修改</h3>
<form action="/brand-demo/addServlet" method="post">
    品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    企业名称:<input name="companyName" value="${brand.companyName}"><br>
    排序:<input name="ordered" value="${brand.ordered}"><br>
    描述信息:<textarea rows="5" cols="20" name="description">${brand.description}</textarea><br>
    状态:
    <c:if test="${brand.status == 0}">
        <input type="radio" name="status" value="0" checked>禁用
        <input type="radio" name="status" value="1">启用<br>
    </c:if>
    <c:if test="${brand.status == 1}">
        <input type="radio" name="status" value="0">禁用
        <input type="radio" name="status" value="1" checked>启用<br>
    </c:if>
    <input type="submit" value="提交">
</form>
</body>
</html>
10.11 案例-修改-修改数据
10.11.1 数据访问层

BrandMapper.java

/**
 * 修改
 * @param brand
 */
@Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id}")
@ResultMap("brandResultMap")
void update(Brand brand);
10.11.2 业务逻辑层

BrandService.java

public void update(Brand brand) {
    // 2.获取SqlSession
    SqlSession sqlSession = factory.openSession();
    // 3.获取BrandMapper
    BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    // 4.调用方法
    mapper.update(brand);
    // 提交事务
    sqlSession.commit();
    // 释放资源
    sqlSession.close();
}
10.11.3 表现层

UpdateServlet

@WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {
    private BrandService service = new BrandService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理POST乱码问题
        request.setCharacterEncoding("utf-8");

        // 1.接受表单提交的数据,封装为一个Brand对象
        String id = request.getParameter("id");
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");
        String description = request.getParameter("description");
        String status = request.getParameter("status");

        // 封装为一个Brand对象
        Brand brand = new Brand();
        brand.setId(Integer.parseInt(id));
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setOrdered(Integer.parseInt(ordered));
        brand.setDescription(description);
        brand.setStatus(Integer.parseInt(status));

        // 2.调用service,完成修改
        service.update(brand);

        // 3.转发到查询所有Servlet
        request.getRequestDispatcher("/selectAllServlet").forward(request, response);
    }

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

update.jsp

<form action="/brand-demo/updateServlet" method="post">
    <%--隐藏域--%>
    <input type="hidden" name="id" value="${brand.id}"> 

11 会话技术

11.1 会话跟踪技术概述

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

实现方式

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

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

11.2 Cookie基本使用

发送Cookie

  1. 创建Cookie对象,设置数据
Cookie cookie = new Cookie("key", "value");
  1. 发送Cookie到客户端:使用response对象
response.addCookie(cookie);

获取Cookie

  1. 获取客户端携带的所有Cookie,使用request对象
Cookie[] cookies = request.getCookies();
  1. 遍历数组,获取每一个Cookie对象:for

  2. 使用Cookie对象方法获取数据

cookie.getName();
cookie.getValue();

示例

发送 Cookie

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
          发送Cookie
         */
        // 1.创建Cookie对象,设置数据
        Cookie cookie = new Cookie("username", "zs");
        // 2.发送Cookie到客户端:使用response对象
        response.addCookie(cookie);
    }

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

接收 Cookie

@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
        获取Cookie
        */
        // 3.获取客户端携带的所有Cookie,使用request对象
        Cookie[] cookies = request.getCookies();
        // 4.遍历数组,获取每一个Cookie对象:for
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if (name.equals("username")) {
                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);
    }
}
11.3 Cookie原理

基于HTML,在请求和响应中携带

存活时间

  • 默认情况下,当浏览器关闭,内存释放,Cookie被销毁

  • setMaxAge(int seconds):设置Cookie存活时间

    • 正数:持久化存储,到指定时间再删除

    • 负数:默认,浏览器关闭时销毁

    • 零:删除该Cookie

存储中文

  • 如果需要存储,需要转码,常用URL编码

示例

发送

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
          发送Cookie
         */
        // 1.创建Cookie对象,设置数据
        // 存储中文
        String value = "张三";
        value = URLEncoder.encode(value, StandardCharsets.UTF_8);
        System.out.println(value);
        Cookie cookie = new Cookie("username", value);
        // 设置存活时间:7天
        cookie.setMaxAge(7*24*60*60);
        // 2.发送Cookie到客户端:使用response对象
        response.addCookie(cookie);
    }

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

接收

@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
        获取Cookie
        */
        // 3.获取客户端携带的所有Cookie,使用request对象
        Cookie[] cookies = request.getCookies();
        // 4.遍历数组,获取每一个Cookie对象:for
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if (name.equals("username")) {
                String value = cookie.getValue();
                // URL解码
                value = URLDecoder.decode(value, StandardCharsets.UTF_8);
                System.out.println(name+":"+value);
                break;
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
11.4 Session基本使用

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

  1. 获取Session对象
HTTPSession session = request.getSession();
  1. Session对象功能
  • void setAttribute(String name, Object o) 存储数据到session域中

  • Object getAttribute(String name) 根据key,获取值

  • void removeAttribute(String name) 根据key,删除该键值对

11.5 Session原理

Session是基于Cookie实现的

Session钝化、活化

钝化:服务器重启时,会自动存储

活化:重启后会自动读取

Session销毁

默认情况下,30分钟后自动销毁

可调用Session对象中的invalidate()方法进行销毁

示例

发送

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

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

接收

@WebServlet("/demo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 从Session中获取数据
        // 1.获取Session对象
        HttpSession session = request.getSession();
        // 销毁
        session.invalidate();
        // 2.获取数据
        Object username = session.getAttribute("username");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
11.6 小结
CookieSession
存储位置客户端服务端
安全性不安全安全
数据大小3KB无大小限制
存储时间长期默认30分钟
服务器性能不占用资源占用资源
11.8 案例-用户登录

login.jsp

<%@ 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="/brand-demo/loginServlet" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
        <div id="errorMsg">${login_msg}</div>
        <p>Username:<input id="username" name="username" type="text"></p>
        <p>Password:<input id="password" name="password" type="password"></p>
        <p>Remember:<input id="remember" name="remember" type="checkbox"></p>
        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">   
            <a href="register.html">没有账号?</a>
        </div>
    </form>
</div>
</body>
</html>

LoginServlet.java

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    private UserService service = new UserService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 2.调用service查询
        User user = service.login(username, password);

        // 3.判断
        if (user != null) {
            // 登陆成功,跳转到查询界面

            // 登陆成功后的user对象,存储到session
            HttpSession session = request.getSession();
            session.setAttribute("user", user);

            String contextPath = request.getContextPath();
            response.sendRedirect(contextPath + "/selectAllServlet");
        } else {
            // 登陆失败
            // 存储错误信息
            request.setAttribute("login_msg", "用户名或密码错误");
            // 跳转到login.jsp
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
11.9 案例-记住用户

如何自动填充?

  1. 将用户名和密码写入Cookie中

  2. 在页面内获取Cookie数据后,设置到用户名和密码框中

${cookie.key.value} // key指存储在cookie中的键名称

何时写Cookie?

  1. 登陆成功

  2. 用户勾选记住用户复选框

示例

RegisterServlet.java

@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    private UserService service = new UserService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        // 2.调用service
        boolean flag = service.register(user);
        // 3.判断成功与否
        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);
    }
}

register.jsp

<%@ 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="/brand-demo/registerServlet" method="post">

        <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="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>
</body>
</html>
11.11 案例-验证码

生成验证码

  1. 使用工具类CheckCodeUtil

  2. CheckCodeServlet

@WebServlet("/checkCodeServlet")
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);
    }

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

校验验证码

  • 判断程序生成与用户输入是否一致,如果不一样,则组织注册

  • 验证码图片访问和提交注册表单是两次请求,所以要将程序生成的验证码存入Session中

register.jsp

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

register.jsp

<script>
    document.getElementById("changeImg").onclick = function () {
        document.getElementById("checkCodeImage").src = "/brand-demo/checkCodeServlet?"+new Date().getMilliseconds();
    }
</script>

CheckCodeServlet.java

@WebServlet("/checkCodeServlet")
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);
    }
}

RegisterServlet.java

// 1.获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 获取用户输入的验证码
String checkCode = request.getParameter("checkCode");
// 获取程序生成的验证码
HttpSession session = request.getSession();
String checkCodeGen = (String) session.getAttribute("checkCodeGen");
User user = new User();
user.setUsername(username);
user.setPassword(password);
// 比对
if (!checkCodeGen.equalsIgnoreCase(checkCode)) {
    request.setAttribute("register_msg", "验证码错误");
    request.getRequestDispatcher("/register.jsp").forward(request, response);
    // 不允许登录
    return;
}

12 Filter&Listener&Ajax

12.1 Filter(过滤器)

快速入门

过滤器一般完成通用操作,比如:权限控制、统一编码处理、敏感字符处理等等…

  1. 定义类,实现Filter接口,并重写所有方法
public class FilterDemo implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}
  1. 配置Filter拦截资源的路径:在类上定义@WebFilter注解
@WebFilter("/*")
public class FilterDemo implements Filter {
  1. doFilter方法中输出一句话,并放行
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("FilterDemo...");
    // 放行
    chain.doFilter(request, response);
}

执行流程

public class FilterDemo implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1.放行前,对request进行处理
        System.out.println("1.FilterDemo...");

        // 放行
        chain.doFilter(request, response);

        // 2.在放行后对response进行处理
        System.out.println("3.FilterDemo...");
    }
}
<body>
<h1>hello</h1>
<%
    System.out.println("2.hello...");
%>
</body>
12.2 Filter-拦截路径设置&过滤器链

拦截路径设置

  • 具体资源:/index.jsp

  • 目录拦截:/user/*

  • 后缀名拦截:*.jsp

  • 拦截所有:/*

过滤器链

Filter1=>Filter2=>Filter2=>Filter1

过滤器排序按照名字自然排序

12.3 案例

LoginFilter.java

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

    public void destroy() {
    }

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

        // 2.判断user是否为null
        if (user != null) {
            // 登录过了
            // 放行
            chain.doFilter(request, response);
        } else {
            // 传输信息
            req.setAttribute("login_msg", "尚未登录");
            req.getRequestDispatcher("/login.jsp").forward(req, response);
        }
    }
}
12.4 Listener

JavaWeb三大组件之一

Servlet、Filter、Listener

添加、修改、删除等操作时自动执行的代码

以后Spring框架会用到,此处省略

12 AJAX

12.1 AJAX-概述

AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML

作用

  1. 与服务器进行数据交互;通过AJAX可以给服务器发送请求,并获取服务器响应的数据
  • 使用了AJAX和服务器进行通信,就可以使用HTML+AJAX来替换JSP页面了

这样一来,后端工程师只需要考虑业务逻辑层和数据访问层即可;

前端工程师负责表现层。从而实现前后端分离。

  1. 异步交互:可以在不重新加载整个页面的情况下,与服务器交互数据并更新部分网页的技术,如:搜索联想、用户名是否可用检验,等等…

同步和异步

同步:客户端与服务端只能进行一个

异步:在请求服务端数据时,不影响客户端的操作

12.2 AJAX-快速入门
  1. 编写AjaxServlet,并使用response输出字符串

  2. 创建XMLHttpRequest对象:用于和服务器交换数据

// 直接从https://www.w3school.com.cn/js/js_ajax_http.asp复制即可
var xhttp;
if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xhttp = new XMLHttpRequest();
} else {
    // code for IE6, IE5
    xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
  1. 向服务器发送请求
// 同样复制即可,第三个参数可省略
xhttp.open("GET", "http://localhost:8080/ajax-demo/ajaxServlet"); // URL建议使用全路径
xhttp.send(); // 发送请求
  1. 获取服务器响应数据
xhttp.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        alert(this.responseText);
    }
};

示例

AjaxServlet.java

src/main/java/com/cookies/web/servlet/AjaxServlet.java

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

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

01-ajax-demo1.html

src/main/webapp/01-ajax-demo1.html

<body>
<script>
    // 1.创建核心对象
    var xhttp;
    if (window.XMLHttpRequest) {
        xhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    // 2.发送请求
    xhttp.open("GET", "http://localhost:8080/ajax-demo/ajaxServlet"); // URL建议使用全路径
    xhttp.send();

    // 3.获取响应
    xhttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            alert(this.responseText);
        }
    };
</script>
</body>
12.3 案例-验证用户是否存在

需求:当用户名输入框失去焦点时,校验用户名是否在数据库存在

客户端

  1. 给用户名输入框绑定事件onblur

  2. 发送ajax请求,携带username参数

  3. 处理响应:是否提示信息

服务端

  1. 接收用户名

  2. 调用service查询User

  3. 返回标记

示例

SelectUserServlet.java

src/main/java/com/cookies/web/servlet/SelectUserServlet.java

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

        // 2.调用service查询User对象
        boolean flag = true; // 暂时不考虑后端

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

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

register.html

src/main/webapp/register.html

<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">用户名已存在</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>
    // 1.给给用户名输入框绑定失去焦点事件
    document.getElementById("username").onblur = function () {
        // 2.发送AJAX请求
        // 获取用户名的值
        var username = this.value;
        // 2.1.创建核心对象
        var xhttp;
        if (window.XMLHttpRequest) {
            xhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        // 2.2.发送请求
        xhttp.open("GET", "http://localhost:8080/ajax-demo/selectUserServlet?username="+username); // URL建议使用全路径
        xhttp.send();
        // 2.3.获取响应
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                // 判断
                if (this.responseText == "true") {
                    // 用户名存在,显示提示信息
                    document.getElementById("username_err").style.display = '';
                } else {
                    // 用户名不存在,清除提示信息
                    document.getElementById("username_err").style.display = 'none';
                }
            }
        };
    }
</script>
</body>
12.4 Axios-基本使用&请求方式别名

快速入门

  1. 引入axios的js文件
<script src="js/axios-0.18.0.js"></script>
  1. 使用axios发送请求,并获取响应结果
axios({
    method:"get",
    url:"http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
}).then(function (resp) {
    alert(resp.data)
})
axios({
    method: "post",
    url: "http://localhost:8080/ajax-demo/axiosServlet",
    data: "username=zhangsan"
}).then(function (resp) {
    alert(resp.data)
})

请求方式别名

方法名作用
get(url)发起GET方式请求
post(url, 请求参数)发起POST方式请求

示例

AxiosServlet.java

src/main/java/com/cookies/web/servlet/AxiosServlet.java

@WebServlet("/axiosServlet")
public class AxiosServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("get...");
        // 1.接收请求参数
        String username = request.getParameter("username");
        System.out.println(username);

        // 2.响应数据
        response.getWriter().write("hello axios~");
    }

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

02-axios-demo.html

src/main/webapp/02-axios-demo.html

<script src="js/axios-0.18.0.js"></script>
<script>
    // 1.get
    /*axios({
        method:"get",
        url:"http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
    }).then(function (resp) {
        alert(resp.data)
    })*/

    /*axios.get("http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan").then(function (resp) {
        alert(resp.data)
    })*/

    // 2.post
    /*axios({
        method: "post",
        url: "http://localhost:8080/ajax-demo/axiosServlet",
        data: "username=zhangsan"
    }).then(function (resp) {
        alert(resp.data)
    })*/

    /*axios.post("http://localhost:8080/ajax-demo/axiosServlet", "username=zhangsan").then(function (resp) {
        alert(resp.data)
    })*/
</script>
12.5 JSON-概述和基础语法

JavaScript Object Notation JavaScript对象表示法

基础语法

  • 定义:

    var 变量名 = {
        "key1": value1,
        "key2": value2,
        "key3": value3,
        ...
    };
    
    var json = {
        "name": "zhangsan"
        "age": 24,
        "addr": ["","",""]
    };
    
  • 获取数据:

    变量名.key
    // 示例
    json.name
    
12.6 JSON-JSON数据和Java对象转换
  • 请求数据:JSON字符串转为Java对象

  • 响应数据:Java对象转为JSON字符串

Fastjson

阿里提供的JSON库

  1. 导入坐标
<!--fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
  1. Java对象转JSON

  2. JSON字符串转为Java对象

示例

public class FastJsonDemo {
    public static void main(String[] args) {
        // 1.将Java对象转为JSON
        User user = new User();
        user.setId(1);
        user.setUsername("zhangsan");
        user.setPassword("123");

        String jsonString = JSON.toJSONString(user);
        System.out.println(jsonString); // {"id":1,"password":"123","username":"zhangsan"}

        // 2.将JSON转为Java对象
        User u = JSON.parseObject("{\"id\":1,\"password\":\"123\",\"username\":\"zhangsan\"}", User.class);
        System.out.println(u);
    }
}
12.7 案例-查询所有

示例

SelectServlet.java

src/main/java/com/itheima/web_20211019_160554/SelectServlet.java

@WebServlet("/selectServlet")
public class SelectServlet extends HttpServlet {
    private BrandService brandService = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.调用Service查询
        List<Brand> brands = brandService.selectAll();

        // 2.将集合转换为JSON数据 序列化
        String jsonString = JSON.toJSONString(brands);

        // 3.响应数据
        response.setContentType("text/json; charset=utf-8");
        response.getWriter().write(jsonString);
    }

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

brand.html

src/main/webapp/brand.html

<body>
<a href="addBrand.html"><input type="button" value="新增"></a><br>
<hr>
<table id="brandTable" border="1" cellspacing="0" width="100%"></table>

<script src="js/axios-0.18.0.js"></script>
<script>
    // 1.当页面加载完成后,发送ajax请求
    window.onload = function () {
        axios({
            method: "get",
            url: "http://localhost:8080/brand-demo/selectServlet"
        }).then(function (resp) {
            let brands = resp.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>
12.8 案例-添加品牌

addBrand.html

src/main/webapp/addBrand.html

<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>
    // 1.绑定单击事件
    document.getElementById("btn").onclick = function () {
        // 将表单数据转为json
        let 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;

        let status = document.getElementsByName("status");
        for (let i = 0; i < status.length; i++) {
            if (status[i].checked) {
                formData.status = status[i].value;
            }
        }

        console.log(formData)

        // 2.发送ajax请求
        axios({
            method: "post",
            url: "http://localhost:8080/brand-demo/addServlet",
            data: formData
        }).then(function (resp) {
            // 判断响应数据是否为success
            if (resp.data === "success") {
                location.href = "http://localhost:8080/brand-demo/brand.html";
            }
        })
    }
</script>
</body>

AddServlet.java

src/main/java/com/itheima/web_20211019_160554/AddServlet.java

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    private BrandService brandService = new BrandService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收数据
        // 获取请求体数据
        BufferedReader reader = request.getReader();
        String params = reader.readLine();
        // 将JSON字符串转为Java对象
        Brand brand = JSON.parseObject(params, Brand.class);
        System.out.println(brand);

        // 2.调用service添加数据
        brandService.add(brand);

        // 3.响应成功标识
        response.getWriter().write("success");
    }

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

13 Vue&Element

13.1 Vue-概述&快速入门

Vue时一套前端框架,免除原生JavaScript中的DOM操作,简化书写

  • 基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上

  • 官网:https://cn.vuejs.org

快速入门

  1. 新建HTML页面,引入Vue.js文件

  2. 在JS代码区域,创建Vue核心对象,进行数据绑定

  3. 编写视图

示例

<body>
<div id="app">
    <input v-model="username">
    <!--插值表达式-->
    {{username}}
</div>

<script src="js/vue.js"></script>
<script>
    // 1.创建Vue核心对象
    new Vue({
        el: "#app",
        data() {
            return {
                username: ""
            }
        }
    })
</script>
</body>
13.2 Vue常用指令&生命周期
指令作用
v-bind为HTML标签绑定属性值
v-model在表单元素上创建双向数据绑定
v-on为HTML标签绑定事件
v-if
v-else条件性的渲染某元素,判定为true时渲染,否则不渲染
v-else-if
v-show根据条件展示某元素,区别在于切换的是display属性的值
v-for列表渲染,遍历容器的元素或者对象的属性

v-bind

<a v-bind:href="url">点击</a>
<a :href="url">点击</a>

v-model

<input v-model="username">
<!--插值表达式-->
{{username}}

v-on

<input type="button" value="弹出" v-on:click="show()">
<input type="button" value="弹出" @click="show()">
<script>
    // 1.创建Vue核心对象
    new Vue({
        el: "#app",
        data() {
            return {

            }
        },
        methods: {
            show() {
                alert("弹出");
            }
        }
    })
</script>

v-if 系列 v-show

<body>
<div id="app">
    <input type="button" value="统计点击次数" @click="btn()"><br>
    <input type="button" value="提示信息开/关" @click="judge()"><br>
    <input type="button" value="归零" @click="zero()">
    <hr>
    <input type="text" v-model="count">
    <h1 v-if="count>0&&count%2===0" v-show="show">偶数</h1>
    <h1 v-else-if="count%2===1" v-show="show">奇数</h1>
    <h1 v-else v-show="show">未点击</h1>
</div>

<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                count: 0,
                show: true
            }
        },
        methods: {
            btn() {
                this.count++
            },
            judge() {
                this.show = !this.show
            },
            zero() {
                this.count = 0
            }
        }
    })
</script>
</body>

v-for

  • v-for

    <div v-for="addr in addrs">
        {{addr}}<br>
    </div>
    
  • 加索引

    <div v-for="(addr,i) in addrs">
        {{i+1}}:{{addr}}<br>
    </div>
    

示例

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

<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                addrs: ["北京", "上海", "石家庄"]
            }
        }
    })
</script>
</body>

Vue 生命周期

生命周期有八个阶段,只需记住mounted即可

  • mounted:挂载完成,Vue初始化完成,HTML页面渲染成功

    • 发送异步请求,加载数据

示例

<body>
<div id="app"></div>

<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        mounted() {
            alert("vue挂载完毕,发送异步请求")
        }
    })
</script>
</body>
13.3 案例-查询所有&新增品牌

使用Vue简化品牌列表数据查询和添加功能

查询所有

<body>
<div id="app">
    <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>
        <!--使用v-for遍历tr-->
        <tr v-for="(brand, i) in brands" align="center">
            <td>{{i+1}}</td>
            <td>{{brand.brandName}}</td>
            <td>{{brand.companyName}}</td>
            <td>{{brand.ordered}}</td>
            <td>{{brand.description}}</td>
            <td>{{brand.statusStr}}</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    </table>
</div>

<script src="js/axios-0.18.0.js"></script>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                brands: []
            }
        },
        mounted() {
            // 页面加载完成后,发送异步请求,查询数据
            const _this = this; // 改变axios中this的作用域
            axios({
                method: "get",
                url: "http://localhost:8080/brand-demo/selectServlet"
            }).then(function (resp) {
                _this.brands = resp.data;
            })
        }
    })
</script>
</body>

新增品牌

<body>
<div id="app">
    <h3>添加品牌</h3>
    <form action="" method="post">
        品牌名称:<input id="brandName" v-model="brand.brandName" name="brandName"><br>
        企业名称:<input id="companyName" v-model="brand.companyName" name="companyName"><br>
        排序:<input id="ordered" v-model="brand.ordered" name="ordered"><br>
        描述信息:<textarea rows="5" cols="20" id="description" v-model="brand.description" name="description"></textarea><br>
        状态:
        <input type="radio" name="status" v-model="brand.status" value="0">禁用
        <input type="radio" name="status" v-model="brand.status" value="1">启用<br>

        <input type="button" id="btn"  value="提交" @click="submitForm">
    </form>
</div>

<script src="js/axios-0.18.0.js"></script>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                brand: {}
            }
        },
        mounted() {

        },
        methods: {
            submitForm() {
                // 发送ajax请求,添加
                const _this = this;
                axios({
                    method: "post",
                    url: "http://localhost:8080/brand-demo/addServlet",
                    data: _this.brand
                }).then(function (resp) {
                    // 判断响应数据是否为success
                    if (resp.data === "success") {
                        location.href = "http://localhost:8080/brand-demo/brand.html";
                    }
                })
            }
        }
    })
</script>
</body>
13.4 Element-概述&快速入门&布局
  1. 引入Element的css、js文件和Vue.js

  2. 创建Vue核心对象

  3. 官网复制Element组件代码

Element - 网站快速成型工具

示例

<body>
<div id="app">
    <el-row>
        <!--
        <el-button>默认按钮</el-button>
        <el-button type="primary">主要按钮</el-button>
        <el-button type="success">成功按钮</el-button>
        <el-button type="info">信息按钮</el-button>
        <el-button type="warning">警告按钮</el-button>
        -->
        <el-button type="danger">危险按钮</el-button>
    </el-row>
    <!--
    <el-row>
        <el-button plain>朴素按钮</el-button>
        <el-button type="primary" plain>主要按钮</el-button>
        <el-button type="success" plain>成功按钮</el-button>
        <el-button type="info" plain>信息按钮</el-button>
        <el-button type="warning" plain>警告按钮</el-button>
        <el-button type="danger" plain>危险按钮</el-button>
    </el-row>

    <el-row>
        <el-button round>圆角按钮</el-button>
        <el-button type="primary" round>主要按钮</el-button>
        <el-button type="success" round>成功按钮</el-button>
        <el-button type="info" round>信息按钮</el-button>
        <el-button type="warning" round>警告按钮</el-button>
        <el-button type="danger" round>危险按钮</el-button>
    </el-row>

    <el-row>
        <el-button icon="el-icon-search" circle></el-button>
        <el-button type="primary" icon="el-icon-edit" circle></el-button>
        <el-button type="success" icon="el-icon-check" circle></el-button>
        <el-button type="info" icon="el-icon-message" circle></el-button>
        <el-button type="warning" icon="el-icon-star-off" circle></el-button>
        <el-button type="danger" icon="el-icon-delete" circle></el-button>
    </el-row>
    -->
</div>

<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">

<script>
    new Vue({
        el: "#app"
    })
</script>
</body>

布局

  • 两种布局

    • Layout布局:通过基础的24分栏,迅速简便地创建布局

      <body>
      <div id="app">
          <el-row>
              <el-col :span="24">
                  <div class="grid-content bg-purple-dark"></div>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="12">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="12">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="8">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="8">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="8">
                  <div class="grid-content bg-purple"></div>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="6">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="6">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="6">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="6">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="4">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="4">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="4">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="4">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="4">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="4">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
          </el-row>
          <el-row>
              <el-col :span="3">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple"></div>
              </el-col>
              <el-col :span="3">
                  <div class="grid-content bg-purple-light"></div>
              </el-col>
          </el-row>
      </div>
      
      <script src="js/vue.js"></script>
      <script src="element-ui/lib/index.js"></script>
      <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
      
      <script>
          new Vue({
              el: "#app"
          })
      </script>
      
      <style>
          .el-row {
              margin-bottom: 20px;
          }
      
          .el-col {
              border-radius: 4px;
          }
      
          .bg-purple-dark {
              background: #99a9bf;
          }
      
          .bg-purple {
              background: #d3dce6;
          }
      
          .bg-purple-light {
              background: #e5e9f2;
          }
      
          .grid-content {
              border-radius: 4px;
              min-height: 36px;
          }
      
          .row-bg {
              padding: 10px 0;
              background-color: #f9fafc;
          }
      </style>
      </body>
      
    • Container布局容器:用于布局的容器组件,方便快速搭建页面的基本结构

      <--和Layout同样,从文档上复制下来即可-->
      
13.5 案例-编写前端页面
<body>
<div id="app">
    <!--表单-->
    <el-form :inline="true" :model="brand" class="demo-form-inline">
        <el-form-item label="当前状态">
            <el-select v-model="brand.status" placeholder="当前状态">
                <el-option label="启用" value="1"></el-option>
                <el-option label="禁用" value="0"></el-option>
            </el-select>
        </el-form-item>
        <el-form-item label="企业名称">
            <el-input v-model="brand.companyName" placeholder="企业名称"></el-input>
        </el-form-item>
        <el-form-item label="品牌名称">
            <el-input v-model="brand.brandName" placeholder="品牌名称"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
    </el-form>

    <!--按钮-->
    <el-row>
        <el-button type="primary" plain>批量删除</el-button>
        <el-button type="danger" plain @click="dialogVisible = true">新增</el-button>
    </el-row>

    <!--弹出对话框-->
    <el-dialog
            title="编辑品牌"
            :visible.sync="dialogVisible"
            width="30%">
        <el-form ref="form" :model="brand" label-width="80px">
            <el-form-item label="品牌名称">
                <el-input v-model="brand.brandName"></el-input>
            </el-form-item>
            <el-form-item label="企业名称">
                <el-input v-model="brand.companyName"></el-input>
            </el-form-item>
            <el-form-item label="排序">
                <el-input v-model="brand.ordered"></el-input>
            </el-form-item>
            <el-form-item label="备注">
                <el-input type="textarea" v-model="brand.description"></el-input>
            </el-form-item>
            <el-form-item label="状态">
                <el-switch v-model="brand.status"
                           active-value="1"
                           inactive-value="0"
                ></el-switch>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="addBrand">提交</el-button>
                <el-button @click="dialogVisible = false">取消</el-button>
            </el-form-item>
        </el-form>
    </el-dialog>

    <!--表格-->
    <template>
        <el-table
                :data="tableData"
                style="width: 100%"
                :row-class-name="tableRowClassName"
                @selection-change="handleSelectionChange">
            <el-table-column
                    type="selection"
                    width="55">
            </el-table-column>
            <el-table-column
                    type="index"
                    width="50">
            </el-table-column>
            <el-table-column
                    prop="brandName"
                    label="品牌名称"
                    align="center">
            </el-table-column>
            <el-table-column
                    prop="companyName"
                    label="企业名称"
                    align="center">
            </el-table-column>
            <el-table-column
                    prop="ordered"
                    label="排序"
                    align="center">
            </el-table-column>
            <el-table-column
                    prop="status"
                    label="当前状态"
                    align="center">
            </el-table-column>
            <el-table-column
                    label="操作"
                    align="center">
                <el-button type="primary">修改</el-button>
                <el-button type="warning">删除</el-button>
            </el-table-column>
        </el-table>
    </template>

    <!--分页工具条-->
    <template>
        <div class="block">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="currentPage4"
                    :page-sizes="[5, 10, 15, 20]"
                    :page-size="5"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="400">
            </el-pagination>
        </div>
    </template>
</div>

<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">

<script>
    new Vue({
        el: "#app",
        methods: {
            // 分页方法
            handleSizeChange(val) {
                console.log(`每页 ${val}`);
            },
            handleCurrentChange(val) {
                console.log(`当前页: ${val}`);
            },
            tableRowClassName({row, rowIndex}) {
                if (rowIndex === 1) {
                    return 'warning-row';
                } else if (rowIndex === 3) {
                    return 'success-row';
                }
                return '';
            },
            // 复选框选中后执行的方法
            handleSelectionChange(val) {
                this.multipleSelection = val;
                console.log(this.multipleSelection)
            },
            onSubmit() {
                console.log(this.brand)
            },
            // 添加数据
            addBrand() {
                console.log(this.brand)
            },
            open() {
                this.$alert('这是一段内容', '标题名称', {
                    confirmButtonText: '确定',
                    callback: action => {
                        this.$message({
                            type: 'info',
                            message: `action: ${action}`
                        })
                    }
                })
            }
        },
        data() {
            return {
                // 当前页码
                currentPage4: 4,
                // 添加数据对话框是否展示
                dialogVisible: false,
                // 品牌模型数据
                brand: {
                    status: '',
                    brandName: '',
                    companyName: '',
                    id: '',
                    ordered: '',
                    description: ''
                },
                // 复选框选中部分
                multipleSelection: [],
                // 表格数据
                tableData: [{
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: '1'
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: '1'
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: '1'
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: '1'
                }]
            }
        }
    })
</script>
</body>

14 综合案例

14.1 环境搭建

功能列表

  1. 查询所有

  2. 新增品牌

  3. 修改品牌

  4. 删除品牌

  5. 批量删除

  6. 分页查询

  7. 条件查询

数据库

-- 删除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 
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1)
        ;
SELECT * FROM tb_brand;
14.2 Servlet 代码优化

将Servlet进行归类,对于用一个实体的操作方法,写到一个Servlet中。

  1. 获取最后一段路径,其实就是方法名称

  2. 通过反射获取方法对象,执行方法

自定义Servlet,使用请求路径进行方法分发,

替换HTTPServlet的根据请求方式进行方法分发

示例

BaseServlet.java

src/main/java/com/itheima/web/servlet/BaseServlet.java

/**
 * 替换HttpServlet,根据请求的最后一段路径来进行方法分发
 */
public class BaseServlet extends HttpServlet {
    // 根据请求的最后一段路径来进行方法分发
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取请求路径
        String uri = req.getRequestURI(); // 例如:/brand-case/brand/selectAll
        // 2.获取最后一段路径,方法名
        int index = uri.lastIndexOf('/');
        String methodName = uri.substring(index + 1);

        // 2.执行方法
        // 2.1获取BrandServlet/UserServlet的class对象
        // 谁调用我(this所在的方法),我(this)代表谁
        Class<? extends BaseServlet> cls = this.getClass();
        try {
            // 2.2获取方法Method对象
            Method method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            // 2.3执行方法
            method.invoke(this, req, resp);
        } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

BrandServlet.java

src/main/java/com/itheima/web/servlet/BrandServlet.java

@WebServlet("/brand/*")
public class BrandServlet extends BaseServlet {

    private BrandService brandService = new BrandServiceImpl();

    public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.调用service查询
        List<Brand> brands = brandService.selectAll();

        // 2.转为JSON
        String jsonString = JSON.toJSONString(brands);

        // 3.写数据
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }

    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收JSON格式的品牌数据
        BufferedReader br = request.getReader();
        String params = br.readLine();
        // 转为Brand对象
        Brand brand = JSON.parseObject(params, Brand.class);

        // 2.调用service添加
        brandService.add(brand);

        // 3.响应成功提示
        response.getWriter().write("success");
    }
}

#### 14.3 代码

|--|brand-case
|--|src
|--|--|main
|--|--|--|java
|--|--|--|--|com.itheima
|--|--|--|--|--|mapper
|--|--|--|--|--|--|BrandMapper.java
|--|--|--|--|--|pojo
|--|--|--|--|--|--|Brand.java
|--|--|--|--|--|--|PageBean.java
|--|--|--|--|--|service
|--|--|--|--|--|--|impl
|--|--|--|--|--|--|--|BrandServiceImpl.java
|--|--|--|--|--|--|BrandService.java #接口
|--|--|--|--|--|util
|--|--|--|--|--|--|SqlSessionFactoryUtils.java #工具类
|--|--|--|--|--|web
|--|--|--|--|--|--|BaseServlet.java
|--|--|--|--|--|--|BrandServlet.java
|--|--|--|resources
|--|--|--|--|com.itheima
|--|--|--|--|--|mapper
|--|--|--|--|--|--|BrandMapper.xml
|--|--|--|--|mybatis-config.xml
|--|--|--|webapp
|--|--|--|--|js
|--|--|--|--|--|axios-0.18.0.js
|--|--|--|--|--|vue.js
|--|--|--|--|brand.html
|--|pom.xml

##### pom.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>brand-case</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!--MyBatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>
        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>
</project>

##### mybatis-config.xml

src/main/resources/mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///db1?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
       <!--扫描mapper-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

##### BrandMapper.java

src/main/java/com/itheima/mapper/BrandMapper.java

package com.itheima.mapper;

import com.itheima.pojo.Brand;
import org.apache.ibatis.annotations.*;
import java.util.List;

public interface BrandMapper {
    /**
     * 查询所有
     */
    @Select("select * from tb_brand")
    @ResultMap("brandResultMap")
    List<Brand> selectAll();


    /**
     * 新增品牌
     */
    @Insert("insert into tb_brand values (null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    @ResultMap("brandResultMap")
    void add(Brand brand);


    /**
     * 删除
     */
    @Delete("delete from tb_brand where id = #{id}")
    void deleteById(int id);


    /**
     * 批量删除
     */
    void deleteByIds(@Param("ids") int[] ids);


    /**
     * 分页查询
     * @param begin
     * @param size
     * @return
     */
    @Select("select * from tb_brand limit #{begin}, #{size}")
    @ResultMap("brandResultMap")
    List<Brand> selectByPage(@Param("begin") int begin, @Param("size") int size);


    /**
     * 查询总记录数
     * @return
     */
    @Select("select count(*) from tb_brand")
    int selectTotalCount();


    /**
     * 分页条件查询
     * @param begin
     * @param size
     * @return
     */
    List<Brand> selectByPageAndCondition(@Param("begin") int begin, @Param("size") int size, @Param("brand") Brand brand);


    /**
     * 根据条件查询总记录数
     * @return
     */
    int selectTotalCountByCondition(Brand brand);

    @Update("update tb_brand set brand_name = #{brandName}, company_name = #{companyName}, ordered = #{ordered}, description = #{description}, status = #{status} where id = #{id}")
    @ResultMap("brandResultMap")
    void changeById(Brand brand);
}

##### BrandMapper.xml

src/main/resources/com/itheima/mapper/BrandMapper.xml

<?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 property="brandName" column="brand_name"/>
        <result property="companyName" column="company_name"/>
    </resultMap>

    <delete id="deleteByIds">
        delete from tb_brand where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

    <select id="selectByPageAndCondition" resultMap="brandResultMap">
        select * from tb_brand
        <where>
            <if test="brand.brandName != null and brand.brandName != ''">
                and brand_name like #{brand.brandName}
            </if>
            <if test="brand.companyName != null and brand.companyName != ''">
                and company_name like #{brand.companyName}
            </if>
            <if test="brand.status != null">
                and status = #{brand.status}
            </if>
        </where>
        limit #{begin}, #{size}
    </select>

    <select id="selectTotalCountByCondition" resultType="java.lang.Integer">
        select count(*) from tb_brand
        <where>
            <if test=" brandName != null and  brandName != ''">
                and brand_name like #{ brandName}
            </if>
            <if test=" companyName != null and  companyName != ''">
                and company_name like #{ companyName}
            </if>
            <if test=" status != null">
                and status = #{ status}
            </if>
        </where>
    </select>
</mapper>

##### Brand.java

src/main/java/com/itheima/pojo/Brand.java

package com.itheima.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 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 String getStatusStr(){
        if (status == null){
            return "未知";
        }
        return status == 0 ? "禁用":"启用";
    }

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

##### PageBean.java

src/main/java/com/itheima/pojo/PageBean.java

package com.itheima.pojo;

import java.util.List;

// 分页查询的JavaBean
//
public class PageBean<T> {
    // 总记录数
    private int totalCount;
    // 当前页数据
    private List<T> rows;

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }
}

##### BrandService.java

src/main/java/com/itheima/service/BrandService.java

package com.itheima.service;

import com.itheima.pojo.Brand;
import com.itheima.pojo.PageBean;

import java.util.List;

public interface BrandService {

    /**
     * 查询所有
     */
    List<Brand> selectAll();


    /**
     * 新增品牌
     */
    void add(Brand brand);

    void changeById(Brand brand);

    /**
     * 删除
     */
    void deleteById(int id);


    /**
     * 批量删除
     */
    void deleteByIds(int[] ids);

    /**
     * 分页查询
     * @param currentPage 当前页码
     * @param pageSize 每页展示条数
     * @return PageBean<Brand>
     */
    PageBean<Brand> selectByPage(int currentPage, int pageSize);

    /**
     * 分页条件查询
     * @param currentPage
     * @param pageSize
     * @param brand
     * @return
     */
    PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand);
}

##### BrandServiceImpl.java

src/main/java/com/itheima/service/impl/BrandServiceImpl.java

package com.itheima.service.impl;

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

import java.util.Collections;
import java.util.List;

public class BrandServiceImpl implements BrandService {
    // 1.创建SqlSessionFactory工厂对象
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /**
     * 查询所有
     */
    @Override
    public List<Brand> selectAll() {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 4.调用方法
        List<Brand> brands = mapper.selectAll();
        // 5.释放资源
        sqlSession.close();
        return brands;
    }


    /**
     * 新增品牌
     */
    @Override
    public void add(Brand brand) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 4.调用方法
        mapper.add(brand);
        sqlSession.commit(); // 提交事务
        // 5.释放资源
        sqlSession.close();
    }

    @Override
    public void changeById(Brand brand) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 4.调用方法
        mapper.changeById(brand);
        sqlSession.commit(); // 提交事务
        // 5.释放资源
        sqlSession.close();
    }

    /**
     * 删除
     */
    @Override
    public void deleteById(int id) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 4.调用方法
        mapper.deleteById(id);
        sqlSession.commit();
        // 5.释放资源
        sqlSession.close();
    }

    /**
     * 批量删除
     */
    @Override
    public void deleteByIds(int[] ids) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        // 4.调用方法
        mapper.deleteByIds(ids);
        sqlSession.commit();
        // 5.释放资源
        sqlSession.close();
    }

    @Override
    public PageBean<Brand> selectByPage(int currentPage, int pageSize) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 4.计算开始索引
        int begin = (currentPage - 1) * pageSize;
        // 计算查询条目数
        int size = pageSize;

        // 5.查询当前页数据
        List<Brand> rows = mapper.selectByPage(begin, size);

        // 6.查询总记录数
        int totalCount = mapper.selectTotalCount();

        // 7.封装资源
        PageBean<Brand> pageBean = new PageBean<>();
        pageBean.setRows(rows);
        pageBean.setTotalCount(totalCount);

        return pageBean;
    }

    @Override
    public PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {
        // 2.获取SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 3.获取BrandMapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        // 4.计算开始索引
        int begin = (currentPage - 1) * pageSize;
        // 计算查询条目数
        int size = pageSize;

        // 处理brand条件
        String brandName = brand.getBrandName();
        if (brandName != null && brandName.length() > 0) {
            brand.setBrandName("%"+brandName+"%");
        }
        String companyName = brand.getCompanyName();
        if (companyName != null && companyName.length() > 0) {
            brand.setCompanyName("%"+companyName+"%");
        }

        // 5.查询当前页数据
        List<Brand> rows = mapper.selectByPageAndCondition(begin, size, brand);

        // 6.查询总记录数
        int totalCount = mapper.selectTotalCountByCondition(brand);

        // 7.封装资源
        PageBean<Brand> pageBean = new PageBean<>();
        pageBean.setRows(rows);
        pageBean.setTotalCount(totalCount);

        return pageBean;
    }
}

##### SqlSessionFactoryUtils.java

src/main/java/com/itheima/util/SqlSessionFactoryUtils.java

package com.itheima.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;
    }
}

##### BaseServlet.java

src/main/java/com/itheima/web/servlet/BaseServlet.java

package com.itheima.web_20211015_122145.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 替换HttpServlet,根据请求的最后一段路径来进行方法分发
 */
public class BaseServlet extends HttpServlet {
    // 根据请求的最后一段路径来进行方法分发
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取请求路径
        String uri = req.getRequestURI(); // 例如:/brand-case/brand/selectAll
        // 2.获取最后一段路径,方法名
        int index = uri.lastIndexOf('/');
        String methodName = uri.substring(index + 1);

        // 2.执行方法
        // 2.1获取BrandServlet/UserServlet的class对象
        // 谁调用我(this所在的方法),我(this)代表谁
        Class<? extends BaseServlet> cls = this.getClass();
        try {
            // 2.2获取方法Method对象
            Method method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            // 2.3执行方法
            method.invoke(this, req, resp);
        } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

##### BrandServlet.java

src/main/java/com/itheima/web/servlet/BrandServlet.java

package com.itheima.web_20211015_122145.servlet;

import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Brand;
import com.itheima.pojo.PageBean;
import com.itheima.service.BrandService;
import com.itheima.service.impl.BrandServiceImpl;

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

@WebServlet("/brand/*")
public class BrandServlet extends BaseServlet {

    private BrandService brandService = new BrandServiceImpl();

    public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.调用service查询
        List<Brand> brands = brandService.selectAll();

        // 2.转为JSON
        String jsonString = JSON.toJSONString(brands);

        // 3.写数据
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }

    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收JSON格式的品牌数据
        BufferedReader br = request.getReader();
        String params = br.readLine();
        // 转为Brand对象
        Brand brand = JSON.parseObject(params, Brand.class);

        // 2.调用service添加
        brandService.add(brand);

        // 3.响应成功提示
        response.getWriter().write("success");
    }

    public void changeById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收JSON格式的品牌数据
        BufferedReader br = request.getReader();
        String params = br.readLine();
        // 转为Brand对象
        Brand brand = JSON.parseObject(params, Brand.class);

        // 2.调用service添加
        brandService.changeById(brand);

        // 3.响应成功提示
        response.getWriter().write("success");
    }

    public void deleteById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收JSON格式的品牌数据
        BufferedReader br = request.getReader();
        String params = br.readLine();
        // 转为int[]
        int id = JSON.parseObject(params, int.class);

        // 2.调用service添加
        brandService.deleteById(id);

        // 3.响应成功提示
        response.getWriter().write("success");
    }

    public void deleteByIds(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收JSON格式的品牌数据
        BufferedReader br = request.getReader();
        String params = br.readLine();
        // 转为int[]
        int[] ids = JSON.parseObject(params, int[].class);

        // 2.调用service添加
        brandService.deleteByIds(ids);

        // 3.响应成功提示
        response.getWriter().write("success");
    }

    public void selectByPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收 当前页码 和 每页展示条数 url?currentPage=1&pageSize=5
        String _currentPage = request.getParameter("currentPage");
        String _pageSize = request.getParameter("pageSize");

        int currentPage = Integer.parseInt(_currentPage);
        int pageSize = Integer.parseInt(_pageSize);

        // 2.调用service查询
        PageBean<Brand> pageBean = brandService.selectByPage(currentPage, pageSize);

        // 3.转为JSON
        String jsonString = JSON.toJSONString(pageBean);

        // 4.写数据
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }

    public void selectByPageAndCondition(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收 当前页码 和 每页展示条数 url?currentPage=1&pageSize=5
        String _currentPage = request.getParameter("currentPage");
        String _pageSize = request.getParameter("pageSize");

        int currentPage = Integer.parseInt(_currentPage);
        int pageSize = Integer.parseInt(_pageSize);

        BufferedReader br = request.getReader();
        String params = br.readLine();
        Brand brand = JSON.parseObject(params, Brand.class);

        // 2.调用service查询
        PageBean<Brand> pageBean = brandService.selectByPageAndCondition(currentPage, pageSize, brand);

        // 3.转为JSON
        String jsonString = JSON.toJSONString(pageBean);

        // 4.写数据
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }
}

##### brand.html

src/main/webapp/brand.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<style>
        .el-table .warning-row {
            background: oldlace;
        }

        .el-table .success-row {
            background: #f0f9eb;
        }
	</style>
</head>
<body>
<div id="app">
	<!--搜索表单-->
	<el-form :inline="true" :model="brand" class="demo-form-inline">
		<el-form-item label="当前状态">
			<el-select v-model="brand.status" placeholder="当前状态">
				<el-option label="启用" value="1"></el-option>
				<el-option label="禁用" value="0"></el-option>
			</el-select>
		</el-form-item>
		<el-form-item label="企业名称">
			<el-input v-model="brand.companyName" placeholder="企业名称"></el-input>
		</el-form-item>
		<el-form-item label="品牌名称">
			<el-input v-model="brand.brandName" placeholder="品牌名称"></el-input>
		</el-form-item>
		<el-form-item>
			<el-button type="primary" @click="onSubmit">查询</el-button>
		</el-form-item>
	</el-form>

	<!--按钮-->
	<el-row>
		<el-button type="danger" plain @click="deleteByIds">批量删除</el-button>
		<el-button type="primary" plain @click="dialogVisible = true">新增</el-button>
	</el-row>
	<!--添加数据对话框表单-->
	<el-dialog
			title="编辑品牌"
			:visible.sync="dialogVisible"
			width="30%"
	>
		<el-form ref="form" :model="brand" label-width="80px">
			<el-form-item label="品牌名称">
				<el-input v-model="brand.brandName"></el-input>
			</el-form-item>
			<el-form-item label="企业名称">
				<el-input v-model="brand.companyName"></el-input>
			</el-form-item>
			<el-form-item label="排序">
				<el-input v-model="brand.ordered"></el-input>
			</el-form-item>
			<el-form-item label="备注">
				<el-input type="textarea" v-model="brand.description"></el-input>
			</el-form-item>
			<el-form-item label="状态">
				<el-switch v-model="brand.status"
				           active-value="1"
				           inactive-value="0"
				></el-switch>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="addBrand">提交</el-button>
				<el-button @click="dialogVisible = false">取消</el-button>
			</el-form-item>
		</el-form>
	</el-dialog>

	<!--添加数据对话框表单-->
	<el-dialog
			title="修改品牌"
			:visible.sync="dialogVisibleChange"
			width="30%"
	>
		<el-form ref="form" :model="brand" label-width="80px">
			<el-form-item label="品牌名称">
				<el-input v-model="brand.brandName"></el-input>
			</el-form-item>
			<el-form-item label="企业名称">
				<el-input v-model="brand.companyName"></el-input>
			</el-form-item>
			<el-form-item label="排序">
				<el-input v-model="brand.ordered"></el-input>
			</el-form-item>
			<el-form-item label="备注">
				<el-input type="textarea" v-model="brand.description"></el-input>
			</el-form-item>
			<el-form-item label="状态">
				<el-switch v-model="brand.status"
				           active-value="1"
				           inactive-value="0"
				></el-switch>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="changeById">提交</el-button>
				<el-button @click="dialogVisibleChange = false">取消</el-button>
			</el-form-item>
		</el-form>
	</el-dialog>

	<!--表格-->
	<template>
		<el-table
				:data="tableData"
				style="width: 100%"
				:row-class-name="tableRowClassName"
				@selection-change="handleSelectionChange"
		>
			<el-table-column
					type="selection"
					width="55">
			</el-table-column>
			<el-table-column
					type="index"
					width="50">
			</el-table-column>
			<el-table-column
					prop="brandName"
					label="品牌名称"
					align="center"
			>
			</el-table-column>
			<el-table-column
					prop="companyName"
					label="企业名称"
					align="center"
			>
			</el-table-column>
			<el-table-column
					prop="ordered"
					align="center"
					label="排序">
			</el-table-column>
			<el-table-column
					prop="statusStr"
					align="center"
					label="当前状态">
			</el-table-column>
			<el-table-column
					align="center"
					label="操作">
				<el-row slot-scope="scope">
					<el-button type="primary" @click="changeBySome(scope.$index, scope.row)">修改</el-button>
					<el-button type="danger" @click="deleteById(scope.$index, scope.row)">删除</el-button>
				</el-row>
			</el-table-column>
		</el-table>
	</template>

	<!--分页工具条-->
	<el-pagination
			@size-change="handleSizeChange"
			@current-change="handleCurrentChange"
			:current-page="currentPage"
			:page-sizes="[5, 10, 15, 20]"
			:page-size="5"
			layout="total, sizes, prev, pager, next, jumper"
			:total="totalCount">
	</el-pagination>
</div>

<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/axios-0.18.0.js"></script>

<script>
    new Vue({
        el: "#app",
        mounted() {
            this.selectAll()
        },
        methods: {
            changeBySome(index, row) {
                this.brand = row;
                this.dialogVisibleChange = true
            },
            changeById() {
                const _this = this;
                axios({
                    method: "post",
                    url: "http://localhost:8080/brand-case/brand/changeById",
                    data: _this.brand
                }).then(function (resp) {
                    if (resp.data === "success") {
                        // 添加成功

                        // 关闭窗口
                        _this.dialogVisibleChange = false;
                        // 提示成功
                        _this.$message({
                            message: '恭喜你,修改成功',
                            type: 'success'
                        });
                        _this.$data.brand = _this.$options.data().brand;
                        // 重新查询
                        _this.selectAll()
                    }
                })
            },
            // 查询所有数据
            selectAll() {
                /*
                // 页面加载后发送异步请求获取数据
                const _this = this;
                axios({
                    method: "get",
                    url: "http://localhost:8080/brand-case/brand/selectByPage?currentPage=1&pageSize=5"
                }).then(function (resp) {
                    _this.tableData = resp.data.rows;
                })
                */
                /*
				const _this = this;
				axios({
					method: "post",
					url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + _this.currentPage + "&pageSize=" + _this.pageSize,
					data: this.brand
				}).then(function (resp) {
					_this.tableData = resp.data.rows;
					_this.totalCount = resp.data.totalCount;
				})
				*/
                axios({
                    method: "post",
                    url: "http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage=" + this.currentPage + "&pageSize=" + this.pageSize,
                    data: this.brand
                }).then(resp => {
                    this.tableData = resp.data.rows;
                    this.totalCount = resp.data.totalCount;
                })
            },
            tableRowClassName({row, rowIndex}) {
                if (rowIndex === 1) {
                    return 'warning-row';
                } else if (rowIndex === 3) {
                    return 'success-row';
                }
                return '';
            },
            // 复选框选中后执行的方法
            handleSelectionChange(val) {
                this.multipleSelection = val;

                console.log(this.multipleSelection)
            },
            // 查询方法
            onSubmit() {
                this.selectAll()
            },
            // 添加数据
            addBrand() {
                const _this = this;
                axios({
                    method: "post",
                    url: "http://localhost:8080/brand-case/brand/add",
                    data: _this.brand
                }).then(function (resp) {
                    if (resp.data === "success") {
                        _this.$data.brand = _this.$options.data().brand;
                        // 添加成功

                        // 关闭窗口
                        _this.dialogVisible = false;
                        // 提示成功
                        _this.$message({
                            message: '恭喜你,添加成功',
                            type: 'success'
                        });
                        // 重新查询
                        _this.selectAll()
                    }
                })
            },
            //分页
            handleSizeChange(val) {
                this.pageSize = val;
                this.selectAll()
            },
            handleCurrentChange(val) {
                this.currentPage = val;
                this.selectAll()
            },
            deleteById(index, row) {
                this.selectedId = row.id;
                const _this = this;
                axios({
                    method: "post",
                    url: "http://localhost:8080/brand-case/brand/deleteById",
                    data: _this.selectedId
                }).then(function (resp) {
                    console.log("abc");
                    if (resp.data === "success") {
                        // 删除成功
                        // 关闭窗口
                        _this.dialogVisible = false;
                        // 提示成功
                        _this.$message({
                            message: '恭喜你,删除成功',
                            type: 'success'
                        });
                        // 重新查询
                        _this.selectAll()
                    }
                })
            },
            deleteByIds() {
                // 1.创建id数组,从this.multipleSelection中获取
                for (let i = 0; i < this.multipleSelection.length; i++) {
                    let selectionElement = this.multipleSelection[i];
                    this.selectedIds[i] = selectionElement.id;
                }
                this.$confirm('此操作将删除数据, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    // 2.发送AJAX请求
                    const _this = this;
                    axios({
                        method: "post",
                        url: "http://localhost:8080/brand-case/brand/deleteByIds",
                        data: _this.selectedIds
                    }).then(function (resp) {
                        if (resp.data === "success") {
                            // 删除成功
                            // 关闭窗口
                            _this.dialogVisible = false;
                            // 提示成功
                            _this.$message({
                                message: '恭喜你,删除成功',
                                type: 'success'
                            });
                            // 重新查询
                            _this.selectAll()
                        }
                    })
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });

            }
        },
        data() {
            return {
                pageSize: 5,
                totalCount: 100,
                // 当前页码
                currentPage: 1,
                // 添加数据对话框是否展示的标记
                dialogVisible: false,
                dialogVisibleChange: false,
                selectedId: 0,
                selectedIds: [],
                // 品牌模型数据
                brand: {
                    status: '',
                    brandName: '',
                    companyName: '',
                    id: "",
                    ordered: "",
                    description: ""
                },
                // 复选框选中数据集合
                multipleSelection: [],
                // 表格数据
                tableData: [{
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: "1"
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: "1"
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: "1"
                }, {
                    brandName: '华为',
                    companyName: '华为科技有限公司',
                    ordered: '100',
                    status: "1"
                }]
            }
        }
    })
</script>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值