尚硅谷JavaWeb-核心控制器思想-M1(servlet优化)

M1(servlet优化)

1.核心思想

把所有功能的servlet合成一个servlet

通过获取前段页面的请求参数不同,来调用相应的功能方法

2.示意图

优化前:
在这里插入图片描述
优化后:
在这里插入图片描述

3.代码

A.重写service方法

public class FruitServlet extends ViewBaseServlet{
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }
}

B.设置路径

@WebServlet("/fruit.do")

C.获取请求的网页对应的参数

// 设置编码,防止乱码问题
request.setCharacterEncoding("utf-8");
// 获取请求的网页对应的参数
String operate = request.getParameter("operate");
// 安全控制,没有参数则默认为index
if (Util.isEmpty(operate)) {
    operate = "index";
}

B.switch调用不同的方法

switch (operate){
    case "index":
        index(request,response);
        // 防止穿透!!!
        break;
    case "add":
        add(request,response);
        break;
    case "del":
        del(request,response);
        break;
    case "edit":
        edit(request,response);
        break;
    case "update":
        update(request,response);
        break;
    default:
        throw new RuntimeException("operate参数非法!!!");

C.注意

注意:doGet方法和doPost方法同时存在,没有关系,都经过service方法!!!

可以使用request.getMethod()返回的String指明了客户端的提交方式

request.getMethod().equals("GET");
request.getMethod().equals("POST");

D.五大方法

index方法
  • index方法
    private void index(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取session作用域
        HttpSession session = request.getSession();

        // 获取请求的页码
        int pageNo = 1;

        // 搜索的关键字
        String keyword = "";

        // 每页显示五条记录
        int pageSize = 5;

        // 判断当前请求为正常请求,或是搜索请求
        if ("search".equals(request.getParameter("oper"))) {
            // 执行到这里,说明是点击了搜索按钮
            //此时,pageNo应该还原为1(默认) , keyword应该从请求参数中获取

            // 获取关键字,用关键字向数据库中搜索
            // 关键字非法的话,设置为空串
            if (!(Util.isEmpty(request.getParameter("keyword")))) {
                keyword = request.getParameter("keyword");
            }

        }else {
            Object keywordObj = session.getAttribute("keyword");
            // 合法控制,为NULL就不保存,否则保存
            if (keywordObj != null) {
                // 强制类型转换,说明当前请求不是第一次,获取关键字来查询数据库,无论它是之前的搜索请求还是正常请求
                keyword = (String) keywordObj;
            }

            // 获取当前页数,判断是否合法,不合法默认设置页码为首页
            if (!(Util.isEmpty(request.getParameter("pageNo")))) {
                pageNo = Integer.parseInt(request.getParameter("pageNo"));
            }
        }

        // 从数据库中获取列表
        List<Fruit> fruitList = fruitDAO.getFruitList(keyword,(pageNo-1)*pageSize,pageSize);
        // 将水果放入请求的session作用域中
        session.setAttribute("fruit",fruitList);

        // 根据总条数,求出总页数
        int count = fruitDAO.getFruitCount(keyword);
        int pageCount = (count + pageSize - 1) / pageSize;
        // 将当前页码和总页码,关键字keyword放入session作用域中
        session.setAttribute("pageNo",pageNo);
        session.setAttribute("pageCount",pageCount);
        session.setAttribute("keyword",keyword);

        // 将请求转发到视图上
        super.processTemplate("index",request,response);
    }
  • index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" th:href="@{/css/index.css}">
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script th:src="@{/js/index.js}"></script>
</head>
<body>
<div id="div_container">
    <div id="div_fruit_list">
        <p class="center f30">欢迎使用水果库存后台管理系统</p>
        <div style="border:0px solid red;width:60%;margin-left:20%;text-align:center;text-decoration: none">
            <form th:action="@{/fruit.do(operate='index')}" method="post" style="float:left;width:60%;border:0px solid green">
                <input type="hidden" name="oper" value="search"/>
                请输入关键字:<input style="border:0px solid blue;margin-bottom:5px;" type="text" name="keyword" th:value="${session.keyword}"/>
                <input type="submit" value="查询" class="btn"/>
            </form>
            <a th:href="@{/fruit.do(operate='add')}" style="border:0px solid blue;margin-bottom:4px;">添加新库存记录</a>
        </div>
        <table id="tbl_fruit">
                <th class="w20">名称</th>
                <th class="w20">单价</th>
                <th class="w20">库存</th>
                <th>操作</th>
            </tr>
<!--            如果链表为空-->
            <tr th:if="${#lists.isEmpty(session.fruit)}">
                <td colspan="4">对不起,库存为空!</td>
            </tr>
<!--            如果链表不为空,取出数据-->
            <tr th:unless="${#lists.isEmpty(session.fruit)}" th:each="fruit : ${session.fruit}">
                <td><a th:href="@{/fruit.do(fid=${fruit.getFid()},operate='edit')}" th:text="${fruit.getFname()}"></a></td>
                <td th:text="${fruit.getFprice()}">5</td>
                <td th:text="${fruit.getFstock()}">20</td>
                <td><img th:src="@{/imgs/del.jpg}  " class="delImg" th:name="${fruit.getFid()}"></td>
            </tr>
        </table>
        <div style="width:60%;margin-left:20%;border:0px solid red;padding-top:4px;" class="center">
            <input type="button" value="首  页" class="btn" pageNo="1" th:disabled="${session.pageNo == 1}"/>
            <input type="button" value="上一页" class="btn" th:pageNo="${(session.pageNo)-1}" th:disabled="${session.pageNo == 1}"/>
            <input type="button" value="下一页" class="btn" th:pageNo="${(session.pageNo)+1}" th:disabled="${session.pageNo == session.pageCount}"/>
            <input type="button" value="尾  页" class="btn" th:pageNo="${session.pageCount}" th:disabled="${session.pageNo == session.pageCount}"/>
        </div>
        <div style="width:60%;margin-left:20%;border:0px solid red;padding-top:4px;" class="center"
             th:text="${session.pageNo} +'/'+ ${session.pageCount}">
        </div>
    </div>
</div>
</body>
</html>
  • index.js
$(function () {
    $(document).on("click", "img", function () {
        var fid = $(this).attr("name");
        if (confirm("请问确认删除编号为" + fid + "的水果吗?")) {
            $(window).attr("location", "fruit.do?operate=del&fid=" + fid)
        }
    });

    $(document).on("click", "input:button", function () {
        $(window).attr("location", "fruit.do?operate=index&pageNo=" + $(this).attr("pageNo"))
    })
})
add方法
  • add方法
private void add(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {

    // GET请求执行的分支!!!
    if (request.getMethod().equals("GET")) {
        super.processTemplate("add",request,response);
        return;
    }

    // 获取表单数据
    String fname = request.getParameter("Fname");
    String fprice = request.getParameter("Fprice");
    String fstock = request.getParameter("Fstock");
    if (Util.isEmpty(fname) || Util.isEmpty(fprice) || Util.isEmpty(fstock)) {
        throw new RuntimeException("输入非法!!!");
    }
    // 创建对象
    Fruit fruit = new Fruit(0, fname, Double.parseDouble(fprice),Integer.parseInt(fstock));

    fruitDAO.addFruit(fruit);

    // 重定向到index页面
    response.sendRedirect("fruit.do?operate=index");
}
  • add.html
...
<!--        自定义变量-->
<!--        注意:form无法使用?的发生发送参数,需要使用隐藏域!!!-->
        <form method="post" th:action="@{/fruit.do}">
<!--            隐藏作用域-->
            <input type="hidden" operate="add">
...
del方法
private void del(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 获取发送的fid
    String fid = request.getParameter("fid");
    if (Util.isEmpty(fid)) {
        throw new RuntimeException("请求非法!!!");
    }
    fruitDAO.delFruit(Integer.valueOf(fid));
    // 客户端重定向
    response.sendRedirect("fruit.do?operate=index");
}
edit方法

edit方法

private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 获取发送的信息
    String fid = request.getParameter("fid");
    // 判断字符串是否合法(使用工具类)
    if (Util.isEmpty(fid)) {
        throw new RuntimeException("字符串为空串!!!");
    }
    // 向DAO层获取水果信息,向下转型为数字
    Fruit fruitByFid = fruitDAO.getFruitByFid(Integer.valueOf(fid));
    // 放入作用域
    request.setAttribute("fruit",fruitByFid);
    // 将请求转发到edit视图上
    super.processTemplate("edit",request,response);
}

edit.html

......
<form method="post" th:object="${fruit}" th:action="@{/fruit.do}">
    <input type="hidden" name="operate" th:value="update">
......
update方法
private void update(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String fid = request.getParameter("Fid");
    String fname = request.getParameter("Fname");
    String fprice = request.getParameter("Fprice");
    String fstock = request.getParameter("Fstock");
    if (Util.isEmpty(fname)||Util.isEmpty(fprice)||Util.isEmpty(fstock)) {
        throw new RuntimeException("输入非法!!!");
    }

    Fruit fruit = new Fruit(Integer.parseInt(fid), fname, Double.parseDouble(fprice), Integer.parseInt(fstock));
    fruitDAO.updateFruit(fruit);

    // 要求客户端重定向,更新数据!!!
    response.sendRedirect("fruit.do?operate=index");
}

4.涉及代码

A.fruit.do组件
package servlets;

import DAO.FruitDAO;
import DAO.impl.FruitDAOImpl;
import pojo.Fruit;
import util.Util;

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

@WebServlet("/fruit.do")
public class FruitServlet extends ViewBaseServlet {

    private FruitDAO fruitDAO = new FruitDAOImpl();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 设置编码,防止乱码问题
        request.setCharacterEncoding("utf-8");
        // 获取请求的网页对应的参数
        String operate = request.getParameter("operate");
        // 安全控制,没有参数则默认为index
        if (Util.isEmpty(operate)) {
            operate = "index";
        }

        switch (operate) {
            case "index":
                index(request, response);
                // 防止穿透!!!
                break;
            case "add":
                add(request, response);
                break;
            case "del":
                del(request, response);
                break;
            case "edit":
                edit(request, response);
                break;
            case "update":
                update(request, response);
                break;
            default:
                throw new RuntimeException("operate参数非法!!!");
        }

    }

    private void index(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取session作用域
        HttpSession session = request.getSession();

        // 获取请求的页码
        int pageNo = 1;

        // 搜索的关键字
        String keyword = "";

        // 每页显示五条记录
        int pageSize = 5;

        // 判断当前请求为正常请求,或是搜索请求
        if ("search".equals(request.getParameter("oper"))) {
            // 执行到这里,说明是点击了搜索按钮
            //此时,pageNo应该还原为1(默认) , keyword应该从请求参数中获取

            // 获取关键字,用关键字向数据库中搜索
            // 关键字非法的话,设置为空串
            if (!(Util.isEmpty(request.getParameter("keyword")))) {
                keyword = request.getParameter("keyword");
            }

        } else {
            Object keywordObj = session.getAttribute("keyword");
            // 合法控制,为NULL就不保存,否则保存
            if (keywordObj != null) {
                // 强制类型转换,说明当前请求不是第一次,获取关键字来查询数据库,无论它是之前的搜索请求还是正常请求
                keyword = (String) keywordObj;
            }

            // 获取当前页数,判断是否合法,不合法默认设置页码为首页
            if (!(Util.isEmpty(request.getParameter("pageNo")))) {
                pageNo = Integer.parseInt(request.getParameter("pageNo"));
            }
        }

        // 从数据库中获取列表
        List<Fruit> fruitList = fruitDAO.getFruitList(keyword, (pageNo - 1) * pageSize, pageSize);
        // 将水果放入请求的session作用域中
        session.setAttribute("fruit", fruitList);

        // 根据总条数,求出总页数
        int count = fruitDAO.getFruitCount(keyword);
        int pageCount = (count + pageSize - 1) / pageSize;
        // 将当前页码和总页码,关键字keyword放入session作用域中
        session.setAttribute("pageNo", pageNo);
        session.setAttribute("pageCount", pageCount);
        session.setAttribute("keyword", keyword);

        // 将请求转发到视图上
        super.processTemplate("index", request, response);
    }

    private void add(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        if (request.getMethod().equals("GET")) {
            super.processTemplate("add",request,response);
            return;
        }

        // 获取表单数据
        String fname = request.getParameter("Fname");
        String fprice = request.getParameter("Fprice");
        String fstock = request.getParameter("Fstock");
        if (Util.isEmpty(fname) || Util.isEmpty(fprice) || Util.isEmpty(fstock)) {
            throw new RuntimeException("输入非法!!!");
        }
        // 创建对象
        Fruit fruit = new Fruit(0, fname, Double.parseDouble(fprice), Integer.parseInt(fstock));

        fruitDAO.addFruit(fruit);

        // 重定向到index页面
        response.sendRedirect("fruit.do?operate=index");
    }

    private void del(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取发送的fid
        String fid = request.getParameter("fid");
        if (Util.isEmpty(fid)) {
            throw new RuntimeException("请求非法!!!");
        }

        fruitDAO.delFruit(Integer.valueOf(fid));

        // 客户端重定向
        response.sendRedirect("fruit.do?operate=index");
    }

    private void edit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取发送的信息
        String fid = request.getParameter("fid");
        // 判断字符串是否合法(使用工具类)
        if (Util.isEmpty(fid)) {
            throw new RuntimeException("字符串为空串!!!");
        }
        // 向DAO层获取水果信息,向下转型为数字
        Fruit fruitByFid = fruitDAO.getFruitByFid(Integer.valueOf(fid));
        // 放入作用域
        request.setAttribute("fruit",fruitByFid);
        // 将请求转发到edit视图上
        super.processTemplate("edit",request,response);
    }

    private void update(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String fid = request.getParameter("Fid");
        String fname = request.getParameter("Fname");
        String fprice = request.getParameter("Fprice");
        String fstock = request.getParameter("Fstock");

        if (Util.isEmpty(fname)||Util.isEmpty(fprice)||Util.isEmpty(fstock)) {
            throw new RuntimeException("输入非法!!!");
        }

        Fruit fruit = new Fruit(Integer.parseInt(fid), fname, Double.parseDouble(fprice), Integer.parseInt(fstock));
        fruitDAO.updateFruit(fruit);

        // 要求客户端重定向,更新数据!!!
        response.sendRedirect("fruit.do?operate=index");
    }
}
B.add.html
<html>

<head>
    <meta charset="utf-8">
    <link rel="stylesheet" th:href="@{/css/index.css}">
    <script language="JavaScript" th:src="@{/js/index.js}"></script>
</head>

<body>
<div id="div_container">
    <div id="div_fruit_list">
        <p class="center f30">添加库存信息</p>
<!--        自定义变量-->
<!--        注意:form无法使用?的发生发送参数,需要使用隐藏域!!!-->
        <form method="post" th:action="@{/fruit.do}">
<!--            隐藏作用域-->
            <input type="hidden" name = "operate" value="add">
        <table id="tbl_fruit">
            <tr>
                <td class="w20">名称</td>
                <td><input type="text" name="Fname"></td>
            </tr>
            <tr>
                <td class="w20">单价</td>
                <td><input type="text" name="Fprice"></td>
            </tr>
            <tr>
                <td class="w20">库存</td>
                <td><input type="text" name="Fstock"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="添加" /></td>
            </tr>
        </table>
        </form>
    </div>
</div>
</body>

</html>
C.edit.html
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="utf-8">
    <link rel="stylesheet" th:href="@{/css/index.css}">
    <script language="JavaScript" th:src="@{/js/index.js}"></script>
</head>

<body>
<div id="div_container">
    <div id="div_fruit_list">
        <p class="center f30">编辑库存信息</p>
<!--        自定义变量-->
        <form method="post" th:object="${fruit}" th:action="@{/fruit.do}">
            <input type="hidden" name="operate" th:value="update">
            <table id="tbl_fruit">
            <!--编号--->
            <!-- 隐藏域 : 功能类似于文本框 , 它的值会随着表单的发送也会发送给服务器,但是界面上用户看不到 -->
            <input type="hidden" name="Fid" th:value="*{getFid()}">
            <tr>
                <td class="w20">名称</td>
                <td><input type="text" name="Fname" th:value="*{getFname()}"></td>
            </tr>
            <tr>
                <td class="w20">单价</td>
                <td><input type="text" name="Fprice" th:value="*{getFprice()}"></td>
            </tr>
            <tr>
                <td class="w20">库存</td>
                <td><input type="text" name="Fstock" th:value="*{getFstock()}"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="修改" /></td>
            </tr>
        </table>
        </form>
    </div>
</div>
</body>

</html>
D.index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" th:href="@{/css/index.css}">
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script th:src="@{/js/index.js}"></script>
</head>
<body>
<div id="div_container">
    <div id="div_fruit_list">
        <p class="center f30">欢迎使用水果库存后台管理系统</p>
        <div style="border:0px solid red;width:60%;margin-left:20%;text-align:center;text-decoration: none">
            <form th:action="@{/fruit.do(operate='index')}" method="post" style="float:left;width:60%;border:0px solid green">
                <input type="hidden" name="oper" value="search"/>
                请输入关键字:<input style="border:0px solid blue;margin-bottom:5px;" type="text" name="keyword" th:value="${session.keyword}"/>
                <input type="submit" value="查询" class="btn"/>
            </form>
            <a th:href="@{/fruit.do(operate='add')}" style="border:0px solid blue;margin-bottom:4px;">添加新库存记录</a>
        </div>
        <table id="tbl_fruit">
                <th class="w20">名称</th>
                <th class="w20">单价</th>
                <th class="w20">库存</th>
                <th>操作</th>
            </tr>
<!--            如果链表为空-->
            <tr th:if="${#lists.isEmpty(session.fruit)}">
                <td colspan="4">对不起,库存为空!</td>
            </tr>
<!--            如果链表不为空,取出数据-->
            <tr th:unless="${#lists.isEmpty(session.fruit)}" th:each="fruit : ${session.fruit}">
                <td><a th:href="@{/fruit.do(fid=${fruit.getFid()},operate='edit')}" th:text="${fruit.getFname()}"></a></td>
                <td th:text="${fruit.getFprice()}">5</td>
                <td th:text="${fruit.getFstock()}">20</td>
                <td><img th:src="@{/imgs/del.jpg}  " class="delImg" th:name="${fruit.getFid()}"></td>
            </tr>
        </table>
        <div style="width:60%;margin-left:20%;border:0px solid red;padding-top:4px;" class="center">
            <input type="button" value="首  页" class="btn" pageNo="1" th:disabled="${session.pageNo == 1}"/>
            <input type="button" value="上一页" class="btn" th:pageNo="${(session.pageNo)-1}" th:disabled="${session.pageNo == 1}"/>
            <input type="button" value="下一页" class="btn" th:pageNo="${(session.pageNo)+1}" th:disabled="${session.pageNo == session.pageCount}"/>
            <input type="button" value="尾  页" class="btn" th:pageNo="${session.pageCount}" th:disabled="${session.pageNo == session.pageCount}"/>
        </div>
        <div style="width:60%;margin-left:20%;border:0px solid red;padding-top:4px;" class="center"
             th:text="${session.pageNo} +'/'+ ${session.pageCount}">
        </div>
    </div>
</div>
</body>
</html>
E.index.js
$(function () {
    $(document).on("click", "img", function () {
        var fid = $(this).attr("name");
        if (confirm("请问确认删除编号为" + fid + "的水果吗?")) {
            $(window).attr("location", "fruit.do?operate=del&fid=" + fid)
        }
    });

    $(document).on("click", "input:button", function () {
        $(window).attr("location", "fruit.do?operate=index&pageNo=" + $(this).attr("pageNo"))
    })
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值