JavaWeb阶段性项目1:系统的servlet优化1

前置知识

前置准备

知识准备

已掌握JavaSE/MySQL/JDBC+HTML/CSS/JavaScript基础

并已完成了Javaweb前置知识的学习

01-JavaWeb-HTML初识

02-JavaWeb-CSS初识

03-JavaWeb-JavaScript初识

04-JavaScript基础应用-鼠标悬浮/离开表格格式变化

05-JavaWeb-Tomcat8安装、Servlet初识

06-JavaWeb-Servlet方法/生命周期、HTTP/会话session

07-JavaWeb-视图模板技术Thymeleaf的使用

08-JavaWeb-Servlet保存作用域

09-JavaWeb-阶段性项目1:最简单的后台库存管理系统

资源准备

尚硅谷丨2022版JavaWeb教程视频

教学资源

https://pan.baidu.com/s/1TS7QJ_a2vHHmXkggAs8RMQ

提取码:yyds

理解项目1的过程

服务端-thymeleaf渲染-servlet-FruitDAO-数据库

可以看出servlet根据业务的增多会不断增加,大量servlet组件很难维护、也很复杂,所以需要进行优化。

servlet优化的过程1

将所有servlet放在一个FruitServlet组件中,该组件包含各个功能,根据前端发过来的请求可以调用不同的方法实现不同功能。

  这里是模板方法设计模式,模板方法设计模式在实际开发中是一种使用非常广泛的设计模式,也是一种非常重要的思想。其核心内容为:通过定义一个模板类,在模板类中规定其整体的骨架并确定哪些方法是允许子类去重写,哪些不允许子类重写或者哪些必须子类重写,其目的是保证其核心算法不被破坏。定义完模板类后,写出具体的子类去继承模板类并按规定好的框架来完成子类的定义。

增加FruitServlet组件

将所有servlet放在一个FruitServlet组件中,该组件包含各个功能

package com.fancy.fruit.servlets;
​
import com.fancy.fruit.dao.FruitDAO;
import com.fancy.fruit.dao.impl.FruitDAOImpl;
import com.fancy.fruit.pojo.Fruit;
import com.fancy.myssm.basedao.myspringmvc.ViewBaseServlet;
import com.fancy.myssm.basedao.util.StringUtil;
​
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 req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
​
        String operate = req.getParameter("operate");
        if(StringUtil.isEmpty(operate)){
            operate = "index";
        }
​
        switch (operate){
            case "index":
                index(req, resp);
                break;
            case "add":
                add(req, resp);
                break;
            case "del":
                del(req, resp);
                break;
            case "edit":
                edit(req, resp);
                break;
            case "update":
                update(req, resp);
                break;
        }
    }
​
    private void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        req.setCharacterEncoding("UTF-8");
        //2.获取参数
        String fidStr = req.getParameter("fid");
        int fid = Integer.parseInt(fidStr);
        String fname = req.getParameter("fname");
        String priceStr = req.getParameter("price");
        int price = Integer.parseInt(priceStr);
        String fcountStr = req.getParameter("fcount");
        Integer fcount = Integer.parseInt(fcountStr);
        String remark = req.getParameter("remark");
​
        //3.执行更新
        fruitDAO.updateFruit(new Fruit(fid,fname,price,fcount,remark));
​
        //4.资源跳转
        //super.processTemplate("index",req,resp);
        //此处需要重定向,目的是重新给IndexServlet发请求,然后覆盖到session中,这样index页面上显示的数据才是最新的
        resp.sendRedirect("index");//重定向,重新给index,给session重新给fruit更改后的数据
    }
​
    private void edit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String fidStr = req.getParameter("fid");
        //HTML是模板,thymeleaf是引擎,我们在servlet中调用了引擎并且给了引擎需要的模板和参数
        if(StringUtil.isNotEmpty(fidStr)){
            int fid = Integer.parseInt(fidStr);
            Fruit fruit = fruitDAO.getFruitByFid(fid);
            //获取到fruit对象后将之放置在session作用域
            req.setAttribute("fruit",fruit);
            //thymeleaf的viewBaseServlet中的方法,处理模板数据
            super.processTemplate("edit",req,resp);
        }
    }
​
    private void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //获取fid
        String fidStr = req.getParameter("fid");
        if(StringUtil.isNotEmpty(fidStr)){
            int fid = Integer.parseInt(fidStr);
            fruitDAO.delFruit(fid);
​
            resp.sendRedirect("index");
        }
    }
​
    private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        req.setCharacterEncoding("UTF-8");
        //2.获取参数
        String fname = req.getParameter("fname");
        String priceStr = req.getParameter("price");
        int price = Integer.parseInt(priceStr);
        String fcountStr = req.getParameter("fcount");
        Integer fcount = Integer.parseInt(fcountStr);
        String remark = req.getParameter("remark");
​
        Fruit fruit = new Fruit(0, fname, price, fcount, remark);
​
        fruitDAO.addFruit(fruit);
​
        resp.sendRedirect("index");
    }
​
    private void index(HttpServletRequest request , HttpServletResponse response)throws IOException, ServletException {
        //添加关键词查询功能
​
        Integer pageNo = 1 ;
        HttpSession session = request.getSession() ;
​
        String oper = request.getParameter("oper");
        //如果oper!=null 说明是通过表单的查询按钮点击过来的
        //如果oper = null 说明不是通过表单的查询按钮点击过来的
        String keyword = null;
        if(StringUtil.isNotEmpty(oper) && "search".equals(oper)){
            //说明是通过表单的查询按钮点击过来的
            //此时pageNo应该还原为1,keyword应该从请求参数中获取
            pageNo = 1;
            keyword = request.getParameter("keyword");
            if(StringUtil.isEmpty(keyword)){
                keyword = "";
            }
            session.setAttribute("keyword",keyword);
        }else {
            //说明此处不是通过表单的查询按钮点击过来的,比如是点击上一页、下一页或直接在地址栏输入
            //此时keyword应该从session作用域中获取
            String pageNoStr = request.getParameter("pageNo");
            if(StringUtil.isNotEmpty(pageNoStr)){
                pageNo = Integer.parseInt(pageNoStr);
            }
            Object keywordObj =session.getAttribute("keyword");
            if(keywordObj != null){
                keyword = (String) keywordObj;
            }else {
                keyword = "" ;
            }
        }
​
        session.setAttribute("pageNo",pageNo);
​
        FruitDAO fruitDAO = new FruitDAOImpl();
        List<Fruit> fruitList = fruitDAO.getFruitList(keyword,pageNo);
​
        session.setAttribute("fruitList",fruitList);
​
        //总记录条数
        int fruitCount = fruitDAO.getFruitCount(keyword);
        //总页数
        int pageCount = (fruitCount+5-1)/5 ;
        /*
        总记录条数       总页数
        1               1
        5               1
        6               2
        10              2
        11              3
        fruitCount      (fruitCount+5-1)/5
         */
        session.setAttribute("pageCount",pageCount);
​
        //此处的视图名称是 index
        //那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去
        //逻辑视图名称 :   index
        //物理视图名称 :   view-prefix + 逻辑视图名称 + view-suffix
        //所以真实的视图名称是:      /       index       .html
        super.processTemplate("index",request,response);
    }
}

此时servlet响应的功能与operate值绑定

把所有功能的servlet合成一个fruitservlet通过获取前段页面的请求参数不同,来调用相应的功能方法

改index页面

<p class="center f30">欢迎使用水果库存后台管理系统</p>
<div style="border:0px solid red;width:60%;margin-left:32%;text-align:right;">
    <form th:action="@{/fruit.do}" method="post" style="border:1px solid red;">
<td> <a th:text="${fruit.fname}" th:href='@{/fruit.do(fid=${fruit.fid},operate="edit")}'>苹果</a></td>

改index.js文件

function delFruit(fid){
    if(confirm("是否确认删除")){
        window.location.href='fruit.do?fid='+fid+'&operate=del';
    }
}
​
function page(pageNo){
    window.location.href="fruit.do?pageNo="+pageNo;
}

改FruitServlet中的del方法

重定向给fruit.do

private void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("UTF-8");
    //获取fid
    String fidStr = req.getParameter("fid");
    if(StringUtil.isNotEmpty(fidStr)){
        int fid = Integer.parseInt(fidStr);
        fruitDAO.delFruit(fid);
​
        resp.sendRedirect("fruit.do");
    }
}

改add.html页面

<form th:action="@{/fruit.do}" method="post">

在下方增加一个隐藏的input,将operate赋值为add,进行添加操作

<input type="hidden" name="operate" value="add"/>

同理FruitServlet中的del方法也要重定向给fruit.do。resp.sendRedirect("fruit.do");

改edit.html页面

<input type="hidden" name="operate" value="update"/>

运行

访问http://localhost:8080/pro13/fruit.do

如果报500错误请确认跟着视频敲的代码是否正确,projectstructure是否配置正确

正常出现页面但是数据没有出来,说明thymeleaf有问题

看报错信息

Could not parse as expression: "@{/fruit.do(fid=${fruit.fid},

改index.html

<td> <a th:text="${fruit.fname}" th:href='@{/fruit.do(fid=${fruit.fid},operate="edit")}'>苹果</a></td>
<td> <a th:text="${fruit.fname}" th:href="@{/fruit.do(fid=${fruit.fid},operate='edit')}">苹果</a></td>

 

经过了以上改动,servlet数量大大缩减

posted @ 2022-08-09 01:21  Fancy[love]  阅读(68)  评论(0编辑  收藏  举报