Java网络开发(Tomcat)——从同步到异步 从jsp 到 js + axios + vue 实现 数据分页显示 数据增删改查

news2024/11/8 10:55:48

目录

  • 引出
  • 一些固定的东西
    • 1.固定的响应格式
    • 2.name 变成 v-model 进行双向绑定
    • 3.下拉框选中--:value="type.id"
    • 4.vue导包固定写法
    • 5.script固定写法
    • 6.axios的get请求
    • 7.axios的post请求
    • 8.前端美化:
  • 数据分页显示
    • 1.后端改成resp响应
    • 2.前端的修改要点
      • (1)显示所有图书信息-----方法queryListByPageNum(pageNum)
        • 【bug】一个没有报错信息的bug--应该写在created里
      • (2)首页、尾页、上下页
      • (3)【有坑】页面的跳转
    • 3.前后端完整代码
      • (1)后端CompanyListServlet.java代码:
      • (2)前端代码:加上了增加和修改,删除的部分,list.jsp页面代码
  • 增加一条数据
    • 1.jsp到Js+axios+vue的变化
    • 2.前端代码修改
      • (1)所有输入框的name,改成v-model进行双向绑定
      • (2)用一个list对象存查询到所有type的list
      • (3)在显示区域进行类型下拉框的显示【bug】
        • 【bug】遇到过的bug:value写成vlaue,没加冒号
    • 3.后端代码修改
    • 4.前后端完整代码
      • (1)后端完整代码:AddServlet.java文件:
      • (2)前端完整代码:addCompMess.jsp文件
  • 修改一条数据
    • 1.Jsp到Js+axios+vue的变化
        • 【bug】遇到过的bug:value写成vlaue,没加冒号
    • 2.前端代码的修改
      • (0)要修改数据的id保存的问题
      • (1)时间显示的问题
      • (2)类型下拉框回显的问题
    • 3.后端代码的修改
      • (1)由于前端有时间框,因此后端实体类加注解
    • 4.前后端完整代码--loacal storage版本
      • (1)前端list.jsp页面相关代码:
      • (2)update.jsp代码
      • (3)后端updatePageServlet.java代码
      • (4)后端updateServlet.java代码
    • 4.前后端完整代码---过一遍servlet版本
      • (1)前端list.jsp页面相关代码:
      • (2)前端update.jsp页面代码
      • (3)该版本的后端updatePageServlet.java代码 和 updateServlet.java代码同local storage版本
  • 删除一条数据
    • 1.Jsp到Js+axios+vue的变化
    • 2.前端代码修改
    • 3.后端代码修改
    • 4.前后端完整代码--需要权限的例子
      • (1)前端删除事件代码:
      • (2)后端删除业务代码,权限控制
  • 总结

引出

从同步到异步 & 从jsp 到 js + axios + vue 实现 数据分页显示 & 数据增删改查


一些固定的东西

1.固定的响应格式

import com.alibaba.fastjson.JSON;
import com.tianju.entity.ResData;
resp.getWriter().write(JSON.toJSONString(
                new ResData(200, "登陆成功", newUser)));

2.name 变成 v-model 进行双向绑定

        <%--    要把原有的书名,和简介,以及类型信息显示出来--%>
        书名:<input type="text" v-model="opus.name" ><br>
        简介:<input type="text" v-model="opus.intro" ><br>
        类型:

        <%--    用forEach把类型信息拼出来--%>
<%--     v-model="opus.typeId" 双向绑定--%>
        <select v-model="opus.typeId">
                <%--            如果根据id查询到的书籍信息,和这里拼的某一个类型信息一致,则设置成selected ,实现默认选中--%>
                <option v-for="types in bookTypeList" :value="types.id">{{types.name}}</option>
        </select><br>

3.下拉框选中–:value=“type.id”

    <select v-model="companyDb.typeId">
        <option value="">请选择</option>
        <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
    </select>

4.vue导包固定写法

<head>
    <title>修改公司信息</title>
    <link rel="stylesheet" href="/day06/bootstrap/css/bootstrap.css">
    <script src="/day06/js/axios.min.js"></script>
    <script src="/day06/js/jquery-3.5.1.js"></script>
    <script src="/day06/bootstrap/js/bootstrap.js"></script>
    <script src="/day06/js/vue.min-v2.5.16.js"></script>

</head>

5.script固定写法

	let app = new Vue({
        // 选择操作的div区域
        el:"#app",
        // 数据区
        data:{},
        // 方法区
        methods:{},
        // 文档加载之后就执行
        created(){},
        // 整个页面全部加载完成后再执行
        mounted(){},
    })

6.axios的get请求

            axios.get("/day06/types/list/vue?name="+"柯基")
                .then(response=>{
                    let resp = response.data;
                    console.log(resp);
                },error=>{
                    console.log(error)
                })

7.axios的post请求

let params = new URLSearchParams();
params.append("username",this.username);
params.append("password",this.password);
params.append("rePassword",this.rePassword);
params.append("gender",this.gender);
params.append("birthday",this.birthday);
params.append("imgCode",this.imgCode);
console.log(params);
axios.post("/day06/comUser/register/vue",params)
      .then(response=>{
           let resp = response.data;
           console.log(resp);
          if (resp.code==200)
          {
              // 成功,跳转回到list页面
              location.href="/day06/compMess/listVue.jsp"
          }
          else
          {
              alert(resp.msg);
          }
       },error=>{
           console.log(error)
       })

8.前端美化:

<table class="table-condensed table-hover table-striped table-responsive table-cell table-row-cell table-view table-bordered">

class="btn btn-primary btn-sm"

数据分页显示

在这里插入图片描述

1.后端改成resp响应

        // 4.new PageInfo对象,共享页数等,以及查询到的数据
        List<Company> list = companyService.queryByLikeNameLimit(pageNum, pageSize,name);
        PageInfo<Company> pageInfo = new PageInfo<>(pageNum, pageSize, total, pages, list);

        resp.getWriter().write(JSON.toJSONString(
                new ResData(200, "ok", pageInfo)
        ));

2.前端的修改要点

(1)显示所有图书信息-----方法queryListByPageNum(pageNum)

因为后端需要知道前端要显示第几页 pageNum,所有在前端定义一个方法queryListByPageNum(pageNum),该方法与后端交互,从拿到pageInfo对象,进而从这个对象中获得pageNum, pageSize, total, pages, list;从而实现整体的功能

        methods:{
            // 本质每次给后端传一个pageNum,然后后端给前端传要显示的数据
            queryListByPageNum(pageNum){
                axios.get("/day06/company/messList?pageNum="+pageNum)
                    .then(response=>{
                        let resp = response.data;
                        console.log("~~~~~~~~~queryListByPageNum")
                        console.log(resp.data)
                        this.pageInfo = resp.data;
                    	// 应该写到这里
                    	this.gotoPageNum = this.pageInfo.pageNum;
                    
                    });
                // 如果写在这里,在axios发送了请求,等待响应的期间,程序会接着执行,
                // 此时,this.pageInfo.pageNum还是响应之前的数据,因此导致这里的
                // this.gotoPageNum 被赋值成了上一次到的值
                this.gotoPageNum = this.pageInfo.pageNum;
            }
        },

【bug】一个没有报错信息的bug–应该写在created里

在这里插入图片描述

(2)首页、尾页、上下页

基本功能:

首页:调用上面的方法,传入的 pageNum 参数为1,点击时:queryListByPageNum(1);

上页:点击时,queryListByPageNum(pageInfo.pageNum-1);

下页:点击时,queryListByPageNum(pageInfo.pageNum+1);

尾页:点击时,queryListByPageNum(pageInfo.pages)

显示与否:

如果不是第一页,pageInfo.pageNum!=1,首页和上页显示;

如果不是最后一页,pageInfo.pageNum!=pageInfo.pages,下一页和尾页显示;

<button @click="queryListByPageNum(1)" v-show="pageInfo.pageNum!=1">首页</button>
    <button @click="queryListByPageNum(pageInfo.pageNum-1)" v-show="pageInfo.pageNum!=1">上一页</button>
    <button @click="queryListByPageNum(pageInfo.pageNum+1)" v-show="pageInfo.pageNum!=pageInfo.pages">下一页</button>
    <button @click="queryListByPageNum(pageInfo.pages)" v-show="pageInfo.pageNum!=pageInfo.pages">尾页</button>

快速美化:

class="btn btn-primary btn-sm"

(3)【有坑】页面的跳转

输入跳转的目标页码,调用上面的方法,并且把原来输入框中的值改成跳转后页码

显示部分:

    跳转到:<input type="text" v-model="gotoPageNum">
    <button @click="queryListByPageNum(gotoPageNum)" class="btn btn-primary btn-sm">跳转</button>

有一个坑:

跳转框中的页码什么时候赋值的问题,等到axios请求获得响应后再赋值,写在axios里面

如果写在这里,在axios发送了请求,等待响应的期间,程序会接着执行,此时,this.pageInfo.pageNum还是响应之前的数据,因此导致这里的this.gotoPageNum 被赋值成了上一次到的值

在这里插入图片描述

业务逻辑部分:

<script>
    let app = new Vue({
        el:"#app",
        data:{
            pageInfo:{},
            gotoPageNum:1, // 初始化第一页
        },
        methods:{
            // 本质每次给后端传一个pageNum,然后后端给前端传要显示的数据
            queryListByPageNum(pageNum){
                axios.get("/day06/company/messList?pageNum="+pageNum)
                    .then(response=>{
                        let resp = response.data;
                        console.log("~~~~~~~~~queryListByPageNum")
                        console.log(resp.data)
                        this.pageInfo = resp.data;
                        this.gotoPageNum = this.pageInfo.pageNum;
                    });
                // 如果写在这里,在axios发送了请求,等待响应的期间,程序会接着执行,
                // 此时,this.pageInfo.pageNum还是响应之前的数据,因此导致这里的
                // this.gotoPageNum 被赋值成了上一次到的值
                // this.gotoPageNum = this.pageInfo.pageNum;
            }
        },
        // 文档加载之后就执行
        created(){
            // 页面一启动查首页
            this.queryListByPageNum(1);
        },
        // 整个页面全部加载完成后再执行
        mounted(){},
    })
</script>

3.前后端完整代码

(1)后端CompanyListServlet.java代码:

package com.tianju.servlet.company;

import com.alibaba.fastjson.JSON;
import com.tianju.entity.Company;
import com.tianju.entity.PageInfo;
import com.tianju.entity.ResData;
import com.tianju.service.ICompanyService;
import com.tianju.service.impl.CompanyService;
import com.tianju.util.StringUtils;

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

/**
 * 进行公司信息列表展示的servlet类
 */
@WebServlet("/company/messList")
public class CompanyListServlet extends HttpServlet {
    private ICompanyService companyService = new CompanyService();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 2.0版本,支持模糊查询和分页展示信息
        // 1.从前端获取数据:要显示第几页,每页显示多少条数据,查询的关键词是啥
        String pageNumStr = req.getParameter("pageNum"); // 第几页
        String pageSizeStr = req.getParameter("pageSize"); // 每页显示数据条数
        String name = req.getParameter("name");

        // 2.进行赋值,
        // 如果没有输入第几页,默认显示首页,第一页;
        Integer pageNum = StringUtils.isBlank(pageNumStr) ? 1:Integer.parseInt(pageNumStr);
        // 如果没有输入显示多少条数据,默认每页显示3条;
        Integer pageSize = StringUtils.isBlank(pageSizeStr) ? 3:Integer.parseInt(pageSizeStr);
        // 如果没有输入查询关键词,数据条数为总数;
        Integer total = companyService.countLines(name);


        // 3.根据查询数据条数,以及前端获取的每页显示数据条数,计算总页数;
        // 思路:如果能整除,则为页数;如果不能整除,则/后再加1;
        Integer pages = total % pageSize==0 ? total/pageSize:total/pageSize+1;

        // 4.new PageInfo对象,共享页数等,以及查询到的数据
        List<Company> list = companyService.queryByLikeNameLimit(pageNum, pageSize,name);
        PageInfo<Company> pageInfo = new PageInfo<>(pageNum, pageSize, total, pages, list);

        resp.getWriter().write(JSON.toJSONString(
                new ResData(200, "ok", pageInfo)
        ));

    }
}

(2)前端代码:加上了增加和修改,删除的部分,list.jsp页面代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>公司的信息</title>
    <link rel="stylesheet" href="/day06/bootstrap/css/bootstrap.css">
    <script src="/day06/js/axios.min.js"></script>
    <script src="/day06/js/jquery-3.5.1.js"></script>
    <script src="/day06/bootstrap/js/bootstrap.js"></script>
    <script src="/day06/js/vue.min-v2.5.16.js"></script>
</head>
<body>

<div id="app">
    <table class="table-condensed table-hover table-striped table-responsive table-cell table-row-cell table-view table-bordered">
        <tr>
            <th>公司id</th>
            <th>公司名</th>
            <th>公司类型</th>
            <th>合伙人</th>
            <th>统一信用编码</th>
            <th>公司地址</th>
            <th>成立时间</th>
            <th>用户名</th>
            <th>修改时间</th>
            <th>执行操作
                <button @click="add">添加</button>
<%--                <a href="/day06/compMess/addPage">添加</a>--%>
            </th>
        </tr>


            <tr v-for="comp in pageInfo.compList">
                <td>{{comp.id}}</td>
                <td>{{comp.name}}</td>
                <td>{{comp.typename}}</td>
                <td>{{comp.corporation}}</td>
                <td>{{comp.creditCode}}</td>
                <td>{{comp.address}}</td>
                <td>{{comp.createTime}}</td>
                <td>{{comp.username}}</td>
                <td>{{comp.updateTime}}</td>
                <td>
                    <button @click="update(comp.id)">修改</button>
                    <button @click="remove(comp.id)">删除</button>
                </td>
            </tr>

    </table><br>
    <%--     分页查询相关--%>
    <%--     如果当前页是第一页,需要控制首页不显示,上一页不显示--%>

    <button @click="queryListByPageNum(1)" v-show="pageInfo.pageNum!=1" class="btn btn-primary btn-sm">首页</button>
    <button @click="queryListByPageNum(pageInfo.pageNum-1)" v-show="pageInfo.pageNum!=1" class="btn btn-primary btn-sm">上一页</button>
    <button @click="queryListByPageNum(pageInfo.pageNum+1)" v-show="pageInfo.pageNum!=pageInfo.pages" class="btn btn-primary btn-sm">下一页</button>
    <button @click="queryListByPageNum(pageInfo.pages)" v-show="pageInfo.pageNum!=pageInfo.pages" class="btn btn-primary btn-sm">尾页</button>

    <%--    提示信息,总页数为,当前第几页--%>
    总计{{pageInfo.pages}}/当前{{pageInfo.pageNum}}<br>
    跳转到:<input type="text" v-model="gotoPageNum">
    <button @click="queryListByPageNum(gotoPageNum)" class="btn btn-primary btn-sm">跳转</button>

</div>


<script>
    let app = new Vue({
        el:"#app",
        data:{
            pageInfo:{},
            gotoPageNum:1, // 初始化第一页
        },
        methods:{
            // 本质每次给后端传一个pageNum,然后后端给前端传要显示的数据
            queryListByPageNum(pageNum){
                axios.get("/day06/company/messList?pageNum="+pageNum)
                    .then(response=>{
                        let resp = response.data;
                        console.log("~~~~~~~~~queryListByPageNum")
                        console.log(resp.data)
                        this.pageInfo = resp.data;
                        this.gotoPageNum = this.pageInfo.pageNum;
                    });
                // 如果写在这里,在axios发送了请求,等待响应的期间,程序会接着执行,
                // 此时,this.pageInfo.pageNum还是响应之前的数据,因此导致这里的
                // this.gotoPageNum 被赋值成了上一次到的值
                // this.gotoPageNum = this.pageInfo.pageNum;
            },
            // 点击添加,直接到添加的页面
            add(){
                location.href="/day06/compMess/addCompMess.jsp"
            },
            // 更新信息的事件
            update(id){
                // // 1.把id存在local storage里
                // localStorage.setItem("id",id);
                // // 跳转到修改页面
                // location.href="/day06/compMess/update.jsp"
                // 2.把id交给后端的servlet,然后通过servlet给update.jsp页面
                location.href="/day06/update/company/id?id="+id;
            },
            // 删除数据的事件
            remove(id){
                axios.get("/day06/company/remove?id="+id)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            // 删除成功,再查第一页数据
                            alert("成功");
                            this.queryListByPageNum(1);
                        }
                        else
                        {
                            alert(resp.msg)
                        }
                    })
            }

        },
        // 文档加载之后就执行
        created(){
            // 页面一启动查首页
            this.queryListByPageNum(1);
        },
        // 整个页面全部加载完成后再执行
        mounted(){},
    })
</script>

</body>
</html>

增加一条数据

1.jsp到Js+axios+vue的变化

在jsp的模式中,增加一条数据的业务逻辑如下:

(1)点击添加按钮,跳转到servlet,从数据库中查出类型信息,然后共享类型信息的值,转发到添加页面jsp;

(2)在添加页面jsp中,把上一步共享得到的类型信息用foreach的方法拼出一个下拉框,在form表单中用户填完信息后,点击添加按钮;

(3)form表单中的数据发送到处理添加业务的servlet,在该servlet中,把表单中的数据存进数据库,然后再跳转到查询所有数据的servlet中;

(4)在查询所有数据的servlet中,再查一次数据库,然后把显示的数据共享转发给list.jsp,从而最终显示添加之后的数据;

在vue的模式下,增加一条数据的业务逻辑变成如下的形式:

(1)在list页面,点击添加按钮,直接到添加页面;

(2)在添加页面的 created(){} 的启动就执行的方法中,把类型查出来;

(3)在添加页面显示类型下拉框,用户执行添加操作;

(4)点击添加按钮,请求发送给添加的servlet,添加成功后,resp返回状态码200;

(5)前端判断响应resp中的状态码是否为200,如果是,再跳转到显示所有信息的list.jsp页面;

2.前端代码修改

(1)所有输入框的name,改成v-model进行双向绑定

<input type="text" v-model="name"><br>

(2)用一个list对象存查询到所有type的list

<script>
    let app = new Vue({
        // 选择操作的div区域
        el:"#app",
        // 数据区
        data:{
            typeList:[],

        },
        // 方法区
        methods:{
            // 查询到所有的类型信息
            queryTypes(){
                axios.get("/day06/type/list/vue")
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        this.typeList = resp.data;
                    })
            }
        },
        // 文档加载之后就执行
        created(){
            this.queryTypes();
        },
        // 整个页面全部加载完成后再执行
        mounted(){},
    })
</script>

(3)在显示区域进行类型下拉框的显示【bug】

        <select v-model="typeId">
            <option value="">请选择</option>
            <%--        这部分拼出来--%>
            <%--        <option value="1">有限责任公司</option>--%>
                <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
        </select>

在这里插入图片描述

【bug】遇到过的bug:value写成vlaue,没加冒号

在这里插入图片描述同上,不太好找的bug

在这里插入图片描述

3.后端代码修改

此时需要补一个查询所有类型信息的servlet

/**
 * 直接查询所有类型的list的servlet
 */
@WebServlet("/type/list/vue")
public class TypeListServlet extends HttpServlet {
    IComTypeService typeService = new ComTypeServiceImpl();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 查询得到所有的类型
        List<ComType> list = typeService.queryAll();
        System.out.println(list);
        resp.getWriter().write(JSON.toJSONString(
                new ResData(200, "ok", list)
        ));
    }
}

AddServlet.java文件改成resp方式

resp.getWriter().write(JSON.toJSONString(new ResData(200, "ok", null)));

4.前后端完整代码

(1)后端完整代码:AddServlet.java文件:

package com.tianju.servlet.company;

import com.alibaba.fastjson.JSON;
import com.tianju.entity.Company;
import com.tianju.entity.ResData;
import com.tianju.service.IComTypeService;
import com.tianju.service.ICompanyService;
import com.tianju.service.impl.ComTypeServiceImpl;
import com.tianju.service.impl.CompanyService;
import com.tianju.util.StringUtils;

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

/**
 * 新增公司信息的业务逻辑
 * 目的是:接收从addCompMess.jsp传过来的信息;
 * new Company 并存到数据库
 */
@WebServlet("/compMess/add")
public class AddServlet extends HttpServlet {
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private ICompanyService companyService = new CompanyService();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 新增一条数据到数据库
        // 1.读取前端的值;
        String name = req.getParameter("name");
        String corporation = req.getParameter("corporation");
        String typeId = req.getParameter("typeId");
        String creditCode = req.getParameter("creditCode");
        String createTime = req.getParameter("createTime");
        String address = req.getParameter("address");

        System.out.println(createTime);

        // 2.判断是否为空;
        if (StringUtils.isBlank(name)
        || StringUtils.isBlank(corporation)
        || StringUtils.isBlank(typeId)
        || StringUtils.isBlank(creditCode)
        || StringUtils.isBlank(createTime)
        || StringUtils.isBlank(address)){
            resp.getWriter().write(JSON.toJSONString(
                    new ResData(1001, "输入为空", null)));
            return;
        }

        // 3.new company实体类;
        Company company = new Company();
        company.setAddress(address);
        company.setName(name);
        company.setCorporation(corporation);
        System.out.println(typeId);
        company.setTypeId(Integer.parseInt(typeId));
        company.setCreditCode(creditCode);
        try {
            company.setCreateTime(sdf.parse(createTime));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        // TODO:记录是谁操作的这条信息
        company.setUserId(1);


        // 4.新增数据到数据库;
        Integer addFlag = companyService.add(company);
        if (addFlag<1){
            // 共享一条msg给前端,提醒一下
            resp.getWriter().write(JSON.toJSONString(
                    new ResData(1002, "系统繁忙,请稍后重试", null)));
            return;
        }

        // 5.重定向到list页面,显示更新后的公司信息
        resp.getWriter().write(JSON.toJSONString(new ResData(200, "ok", null)));


    }
}

(2)前端完整代码:addCompMess.jsp文件

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新增公司信息</title>
    <link rel="stylesheet" href="/day06/bootstrap/css/bootstrap.css">
    <script src="/day06/js/jquery-3.5.1.js"></script>
    <script src="/day06/bootstrap/js/bootstrap.js"></script>
    <script src="/day06/js/vue.min-v2.5.16.js"></script>
    <script src="/day06/js/axios.min.js"></script>
</head>
<body>

<div id="app">
    <h1>新增公司信息</h1>

    公司名:<input type="text" v-model="name"><br>
    合伙人:<input type="text" v-model="corporation"><br>
    公司类型:
    <select v-model="typeId">
        <option value="">请选择</option>
        <%--        这部分拼出来--%>
        <%--        <option value="1">有限责任公司</option>--%>
<%--        TODO:忘记加冒号--%>
            <option v-for="type in typeList" value="type.id">{{type.name}}</option>
    </select>
    <br>
    统一信用编码:
    <input type="text" v-model="creditCode"><br>
    公司成立时间:
    <input type="date" v-model="createTime"><br>
    公司地址:<input type="text" v-model="address"><br>

    <span style="color: darkred">{{msg}}</span><br>


    <button @click="add">提交</button>
    <button @click="reset">重置</button>
    <hr>
    <a href="/day06/compMess/listVue.jsp">返回</a>

</div>

<script>
    let app = new Vue({
        el:"#app",
        data:{
            name:"",
            corporation:"",
            typeId:"",
            creditCode:"",
            createTime:"",
            address:"",
            typeList:[],
            msg:"",
        },

        // 方法区
        methods:{
            // 查询到所有的类型信息
            queryTypes(){
                axios.get("/day06/type/list/vue")
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        this.typeList = resp.data;
                    })
            },
            // 添加数据
            add(){
                let params = new URLSearchParams();
                params.append("name",this.name);
                params.append("corporation",this.corporation);
                params.append("typeId",this.typeId);
                params.append("creditCode",this.creditCode);
                params.append("createTime",this.createTime);
                params.append("address",this.address);
                axios.post("/day06/compMess/add",params)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            alert(resp.msg);
                            // 再回到list页面
                            location.href = "/day06/compMess/listVue.jsp";
                        }
                        else
                        {
                            this.msg=resp.msg;
                        }
                    })
            },
            reset(){
                this.name="";
                this.corporation="";
                this.typeId="";
                this.creditCode="";
                this.createTime="";
                this.address="";
                this.msg="";
            }
        },


        // 文档加载之后就执行
        created(){
            this.queryTypes();
        },
        // 整个页面全部加载完成后再执行
        mounted(){},

    })
</script>

</body>
</html>

修改一条数据

1.Jsp到Js+axios+vue的变化

在jsp模式下,修改一条数据的业务流程如下:

(1)在所有数据的页面,用户点击修改,向后端传要修改的id,由updatePage.java中的servlet进行处理;

(2)在该servlet中,把类型信息List查询出来,根据id查询出当前要修改的数据;

(3)把步骤(2)中的类型list和要修改的opus共享值,然后转发到updatePage.jsp前端页面;

(4)在修改的前端updatePage.jsp页面中,把原有的信息进行回显,其中类型的回显用type.id==opus.typeId ? ‘selected’ : ''三元表达式;由于修改的业务需要知道id号,所以在前端设置一个隐藏框,存放opus.id;当用户执行完修改操作后,把数据提交给update.java中的servlet进行处理;

(5)在update.java中,获取要修改的id,更新修改后的opus的相关数据,要进行权限的业务逻辑控制,从session中获取登陆的user对象,获得id,和查询出来的要修改的数据中的userId进行对比,如果不一致,则不允许修改;修改成功,则重定向到查询所有数据的servlet中;

(6)在查询所有数据的servlet中,再查一次数据库,然后把显示的数据共享转发给list.jsp,从而最终显示添加之后的数据;

在vue的异步请求模式下,修改一条数据的业务流程如下:

(1)在所有数据的list页面,用户点击修改按钮,跳转到修改页面,由于需要知道要修改的id,所以要把id想办法保存起来,有3种解决方案:

  • [1].把 id 保存到local storage空间,在修改页面中获得保存的 id;
  • [2].经过一次servlet,点击修改时,把id传给servlet后端,在该servlet中,共享该id,转发到修改页面jsp中,在修改页面update.jsp中用 id:${id}, 的方式获取id;
  • [3].vue-cli路由的方式,后面补上【未完待续】

(2)在修改的update.jsp页面中,定义两个启动就执行的方法,[1].查询所有类型信息的方法;[2].查询要修改的opus数据的方法;

(3)启动页面就执行上面的方法,从而在updat.jsp页面中回显数据,其中类型的回显采用 :value=“types.id”,这里需要注意【注意】冒号不能少;value不要敲错;

(4)用户点击修改按钮,把id,修改后的数据传给后端,等待后端的响应;

(5)如果响应状态码为200,再跳转到显示所有信息的list.jsp页面;

【bug】遇到过的bug:value写成vlaue,没加冒号

在这里插入图片描述同上,不太好找的bug

在这里插入图片描述

2.前端代码的修改

(0)要修改数据的id保存的问题

[1].保存到local storage里面

在list页面,点击修改时,保存id到local storage

            update(id){
                // 1.把id存在local storage里
                localStorage.setItem("id",id);
                // 跳转到修改页面
                location.href="/day06/compMess/update.jsp"
            }

在修改页面拿到id:localStorage.getItem(“id”)

        // 文档加载之后就执行
        created(){
            this.queryTypes();
            this.queryMessById(localStorage.getItem("id"));
        },

[2]过一次servlet

需要一个专门转发id到update.jsp页面的servlet,UpdateCompIdServlet.java;

package com.tianju.servlet.company;

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

/**
 * 保存要修改的id,过一次servlet
 * 点击修改,把 id 从list页面传过来
 * servlet中共享id,转发到 update.jsp
 */
@WebServlet("/update/company/id")
public class UpdateCompIdServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        // 共享值,转发给update.jsp页面
        req.setAttribute("id", id);
        req.getRequestDispatcher("/compMess/update.jsp").forward(req,resp);
    }
}

更改list页面点击修改按钮的事件:

            update(id){
                // // 1.把id存在local storage里
                // localStorage.setItem("id",id);
                // // 跳转到修改页面
                // location.href="/day06/compMess/update.jsp"
                // 2.把id交给后端的servlet,然后通过servlet给update.jsp页面
                location.href="/day06/update/company/id?id="+id;
            }

在update.jsp页面的数据区获得后端共享的id,“${id}”

        data:{
            typeList:[],
            // 后端传来的查询到的company对象
            companyDb:{},
            msg:"",
            // 获取经过一次servlet的id
            id:"${id}",

        },

根据这个id查询要修改的company实体类

        // 文档加载之后就执行
        created(){
            this.queryTypes();
            this.queryMessById(this.id);
        },

(1)时间显示的问题

在这里插入图片描述

前端时间显示的问题,需要加注解,有一个坑,月份写法要规范,不能用小写mm,要用大写的MM,不然回显到前端的日期框会失效:

import com.alibaba.fastjson.annotation.JSONField;
@JSONField(format = "yyyy-MM-dd")

在这里插入图片描述

(2)类型下拉框回显的问题

之前用jsp写的时候,代码如下:

    <select name="typeId">
        <option value="">请选择</option>
<%--        这部分拼出来--%>
<%--        <option value="1">有限责任公司</option>--%>
        <c:forEach items="${types}" var="type">
            <option value="${type.id}">${type.name}</option>
        </c:forEach>

    </select>

如果想要显示类型下拉框,需要改成vue的v-for的方式,如下:

    <select name="typeId">
        <option value="">请选择</option>
        <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
    </select>

如果想要回显,把select框的name也双向绑定,绑定的是从后端查询到要修改的数据中的类型id, v-model=“companyDb.typeId”;

    <select v-model="companyDb.typeId">
        <option value="">请选择</option>
        <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
    </select>

在这里插入图片描述

(3)点击重置的时候,重置哪些东西,除了id之外的其他值

            reset(){
                this.companyDb.name="";
                this.companyDb.corporation="";
                this.companyDb.typeId="";
                this.companyDb.creditCode="";
                this.companyDb.createTime="";
                this.companyDb.address="";
                this.msg="";
            }

3.后端代码的修改

(1)由于前端有时间框,因此后端实体类加注解

前端时间显示的问题,需要加注解,有一个坑,月份写法要规范,不能用小写mm,要用大写的MM,不然回显到前端的日期框会失效:

import com.alibaba.fastjson.annotation.JSONField;
@JSONField(format = "yyyy-MM-dd")
package com.tianju.entity;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * 公司信息的实体类
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Company {
    private Integer id;
    private String name;
    private Integer userId;
    private String username;
    private Integer typeId;
    private String typename;
    private String corporation;
    private String creditCode; // 工商号
    private String address;
    @JSONField(format = "yyyy-MM-dd")
    private Date createTime; // 公司的创建时间
    @JSONField(format = "yyyy-MM-dd")
    private Date updateTime; // 这条信息的修改时间

}

4.前后端完整代码–loacal storage版本

在这里插入图片描述

(1)前端list.jsp页面相关代码:

            update(id){
                // 1.把id存在local storage里
                localStorage.setItem("id",id);
                // 跳转到修改页面
                location.href="/day06/compMess/update.jsp"
            }

(2)update.jsp代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>修改公司信息</title>
    <link rel="stylesheet" href="/day06/bootstrap/css/bootstrap.css">
    <script src="/day06/js/axios.min.js"></script>
    <script src="/day06/js/jquery-3.5.1.js"></script>
    <script src="/day06/bootstrap/js/bootstrap.js"></script>
    <script src="/day06/js/vue.min-v2.5.16.js"></script>

</head>
<body>

<div id="app">
    <h1>修改公司信息</h1>
    公司名:<input type="text" v-model="companyDb.name"><br>
    合伙人:<input type="text" v-model="companyDb.corporation"><br>
    公司类型:
    <select v-model="companyDb.typeId">
        <option value="">请选择</option>
        <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
    </select>

    <br>
    统一信用编码:
    <input type="text" v-model="companyDb.creditCode"><br>
    公司成立时间:
    <input type="date" v-model="companyDb.createTime"><br>
    公司地址:<input type="text" v-model="companyDb.address"><br>

    <span style="color: darkred">{{msg}}</span><br>
    <button @click="update">修改</button>
    <button @click="reset">重置</button>
    <hr>
    <a href="/day06/company/messList">返回</a>
</div>

<script>
    let app = new Vue({
        // 选择操作的div区域
        el:"#app",
        // 数据区
        data:{
            typeList:[],
            // 后端传来的查询到的company对象
            companyDb:{},
            msg:"",

        },
        // 方法区
        methods:{
            // 查询所有类型的方法
            queryTypes(){
                axios.get("/day06/type/list/vue")
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        this.typeList = resp.data;
                    })
            },
            // 根据id查询出要修改的公司信息
            queryMessById(id){
                axios.get("/day06/company/updatePage?id="+id)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            this.companyDb = resp.data;
                        }
                        else
                        {
                            this.msg = resp.msg;
                        }
                    })
            },
            // 点击修改按钮,传给后端,进行修改
            update(){
                let params = new URLSearchParams();
                params.set("name",this.companyDb.name);
                params.set("corporation",this.companyDb.corporation);
                params.set("typeId",this.companyDb.typeId);
                params.set("creditCode",this.companyDb.creditCode);
                params.set("createTime",this.companyDb.createTime);
                params.set("address",this.companyDb.address);
                params.set("id",this.companyDb.id);
                axios.post("/day06/compMess/update",params)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            // 成功,跳转回到list页面
                            location.href="/day06/compMess/listVue.jsp"
                        }
                        else
                        {
                            this.msg = resp.msg;
                        }
                    })

            },
            reset(){
                this.companyDb.name="";
                this.companyDb.corporation="";
                this.companyDb.typeId="";
                this.companyDb.creditCode="";
                this.companyDb.createTime="";
                this.companyDb.address="";
                this.msg="";
            }

        },
        // 文档加载之后就执行
        created(){
            this.queryTypes();
            this.queryMessById(localStorage.getItem("id"));
        },
        // 整个页面全部加载完成后再执行
        mounted(){
        },
    })
</script>


</body>
</html>

(3)后端updatePageServlet.java代码

package com.tianju.servlet.company;

import com.alibaba.fastjson.JSON;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.tianju.entity.Company;
import com.tianju.entity.ResData;
import com.tianju.service.IComTypeService;
import com.tianju.service.ICompanyService;
import com.tianju.service.impl.ComTypeServiceImpl;
import com.tianju.service.impl.CompanyService;
import com.tianju.util.StringUtils;

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

/**
 * 修改页面的servlet:
 * 目的是把已有的信息,查询,返回给修改页面;
 * 也要共享一下类型信息
 */
@WebServlet("/company/updatePage")
public class UpdatePagServlet extends HttpServlet {
    private ICompanyService companyService = new CompanyService();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.从前端获取修改的id
        String id = req.getParameter("id");
        System.out.println(id);

        // 2.判断不为空;
        if (StringUtils.isBlank(id)){
            resp.getWriter().write(JSON.toJSONString(new ResData(1001, "未能获取要修改的公司id", null)));
            return;
        }

        // 3.查询出一条信息;
        Company companyDb = companyService.queryById(Integer.parseInt(id));
        if (companyDb==null){
            resp.getWriter().write(JSON.toJSONString(new ResData(1001, "未能根据公司id查询到公司信息", null)));
            return;
        }

        System.out.println(companyDb);
        resp.getWriter().write(JSON.toJSONString(new ResData(200, "ok", companyDb)));

    }
}

(4)后端updateServlet.java代码

package com.tianju.servlet.company;

import com.alibaba.fastjson.JSON;
import com.tianju.entity.Company;
import com.tianju.entity.ResData;
import com.tianju.service.ICompanyService;
import com.tianju.service.impl.CompanyService;
import com.tianju.util.StringUtils;

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

/**
 * 修改公司信息的servlet
 * 目的是:从前端获取要修改的信息;
 * 执行修改操作
 */

@WebServlet("/compMess/update")
public class UpdateServlet extends HttpServlet {
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private ICompanyService companyService = new CompanyService();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取要修改的id,和其他信息,更新数据库,再重定向到list页面
        // 1.从前端获取信息;
        String name = req.getParameter("name");
        String corporation = req.getParameter("corporation");
        String typeId = req.getParameter("typeId");
        String creditCode = req.getParameter("creditCode");
        String createTime = req.getParameter("createTime");
        String address = req.getParameter("address");
        // 要修改的id;
        String id = req.getParameter("id");

        // 2.判断不为空;
        if (StringUtils.isBlank(name) || StringUtils.isBlank(corporation)
        || StringUtils.isBlank(typeId) || StringUtils.isBlank(creditCode)
        || StringUtils.isBlank(createTime) || StringUtils.isBlank(address) || StringUtils.isBlank(id)
        ){
            // 共享一条msg给前端,提醒一下
            resp.getWriter().write(JSON.toJSONString(new ResData(1001, "输入为空,请输全公司信息", null)));
            return;
        }

        // 3.new company;
        Company company = new Company();
        company.setAddress(address);
        company.setName(name);
        company.setCorporation(corporation);
        company.setTypeId(Integer.parseInt(typeId));
        company.setCreditCode(creditCode);
        try {
            company.setCreateTime(sdf.parse(createTime));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        // TODO:记录是谁操作的这条信息
        company.setUserId(1);
        // 公司信息的id
        company.setId(Integer.parseInt(id));

        // 4.进行修改;
        Integer updateFlag = companyService.update(company);
        if (updateFlag<1){
            // 共享一条msg给前端,提醒一下
            resp.getWriter().write(JSON.toJSONString(new ResData(1002, "修改失败,系统繁忙,请稍后重试", null)));
            return;
        }

        resp.getWriter().write(JSON.toJSONString(new ResData(200, "ok", null)));

    }
}

4.前后端完整代码—过一遍servlet版本

(1)前端list.jsp页面相关代码:

            update(id){
                // // 1.把id存在local storage里
                // localStorage.setItem("id",id);
                // // 跳转到修改页面
                // location.href="/day06/compMess/update.jsp"
                // 2.把id交给后端的servlet,然后通过servlet给update.jsp页面
                location.href="/day06/update/company/id?id="+id;
            }

专门给update.jsp转发id的servlet:updateCompIdServlet.java

package com.tianju.servlet.company;

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

/**
 * 保存要修改的id,过一次servlet
 * 点击修改,把 id 从list页面传过来
 * servlet中共享id,转发到 update.jsp
 */
@WebServlet("/update/company/id")
public class UpdateCompIdServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        // 共享值,转发给update.jsp页面
        req.setAttribute("id", id);
        req.getRequestDispatcher("/compMess/update.jsp").forward(req,resp);
    }
}

(2)前端update.jsp页面代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>修改公司信息</title>
    <link rel="stylesheet" href="/day06/bootstrap/css/bootstrap.css">
    <script src="/day06/js/axios.min.js"></script>
    <script src="/day06/js/jquery-3.5.1.js"></script>
    <script src="/day06/bootstrap/js/bootstrap.js"></script>
    <script src="/day06/js/vue.min-v2.5.16.js"></script>

</head>
<body>

<div id="app">
    <h1>修改公司信息</h1>
    公司名:<input type="text" v-model="companyDb.name"><br>
    合伙人:<input type="text" v-model="companyDb.corporation"><br>
    公司类型:
    <select v-model="companyDb.typeId">
        <option value="">请选择</option>
        <option v-for="type in typeList" :value="type.id">{{type.name}}</option>
    </select>

    <br>
    统一信用编码:
    <input type="text" v-model="companyDb.creditCode"><br>
    公司成立时间:
    <input type="date" v-model="companyDb.createTime"><br>
    公司地址:<input type="text" v-model="companyDb.address"><br>

    <span style="color: darkred">{{msg}}</span><br>
    <button @click="update">修改</button>
    <button @click="reset">重置</button>
    <hr>
    <a href="/day06/company/messList">返回</a>
</div>

<script>
    let app = new Vue({
        // 选择操作的div区域
        el:"#app",
        // 数据区
        data:{
            typeList:[],
            // 后端传来的查询到的company对象
            companyDb:{},
            msg:"",
            // 获取经过一次servlet的id
            id:"${id}",

        },
        // 方法区
        methods:{
            // 查询所有类型的方法
            queryTypes(){
                axios.get("/day06/type/list/vue")
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        this.typeList = resp.data;
                    })
            },
            // 根据id查询出要修改的公司信息
            queryMessById(id){
                axios.get("/day06/company/updatePage?id="+id)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            this.companyDb = resp.data;
                        }
                        else
                        {
                            this.msg = resp.msg;
                        }
                    })
            },
            // 点击修改按钮,传给后端,进行修改
            update(){
                let params = new URLSearchParams();
                params.set("name",this.companyDb.name);
                params.set("corporation",this.companyDb.corporation);
                params.set("typeId",this.companyDb.typeId);
                params.set("creditCode",this.companyDb.creditCode);
                params.set("createTime",this.companyDb.createTime);
                params.set("address",this.companyDb.address);
                params.set("id",this.companyDb.id);
                axios.post("/day06/compMess/update",params)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            // 成功,跳转回到list页面
                            location.href="/day06/compMess/listVue.jsp"
                        }
                        else
                        {
                            this.msg = resp.msg;
                        }
                    })

            },
            reset(){
                this.companyDb.name="";
                this.companyDb.corporation="";
                this.companyDb.typeId="";
                this.companyDb.creditCode="";
                this.companyDb.createTime="";
                this.companyDb.address="";
                this.msg="";
            }

        },
        // 文档加载之后就执行
        created(){
            this.queryTypes();
            this.queryMessById(this.id);
        },
        // 整个页面全部加载完成后再执行
        mounted(){
        },
    })
</script>


</body>
</html>

(3)该版本的后端updatePageServlet.java代码 和 updateServlet.java代码同local storage版本

删除一条数据

1.Jsp到Js+axios+vue的变化

jsp版本的删除一条数据的业务逻辑

(1)在list页面点击删除,传给后端要删除的id,进行权限确定,

(2)删除成功后,再查数据库,共享,转发到list页面;

vue版本的删除一条数据的流程

(1)在list页面点击删除,触发点击事件;

(2)在后端进行删除业务,前端等待后端的响应;

(3)如果响应状态码是200,更新一下list页面的数据;

2.前端代码修改

在list页面给删除按钮绑定一个事件

// 删除数据的事件
            remove(id){
                axios.get("/day06/company/remove?id="+id)
                    .then(response=>{
                        let resp = response.data;
                        console.log(resp);
                        if (resp.code==200)
                        {
                            // 删除成功,再查第一页数据
                            alert("成功");
                            this.queryListByPageNum(1);
                        }
                        else
                        {
                            alert(resp.msg)
                        }
                    })
            }

3.后端代码修改

由于不涉及到权限的问题,所以代码比较简单

@WebServlet("/company/remove")
public class CompanyRemove extends HttpServlet {
    private ICompanyService companyService = new CompanyService();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 进行删除
        String id = req.getParameter("id");
        companyService.deleteById(Integer.parseInt(id));
        resp.getWriter().write(JSON.toJSONString(new ResData(200, "ok", null)));
    }
}

4.前后端完整代码–需要权限的例子

(1)前端删除事件代码:

            remove(id){
                axios.get("/day06/opus/remove/vue?id="+id)
                    .then(response=>{
                        console.log(response.data)
                        let resp = response.data;
                        if (resp.code==200)
                        {
                            alert("成功");
                            // 继续查数据库,渲染列表部分
                            this.queryList(1);
                        }
                        else
                        {
                            alert(resp.msg)
                        }
                    })
            },

(2)后端删除业务代码,权限控制

package com.tianju.servlet.opus;

import com.alibaba.fastjson.JSON;
import com.tianju.entity.Opus;
import com.tianju.entity.ResData;
import com.tianju.entity.User;
import com.tianju.service.IOpusService;
import com.tianju.service.impl.OpusServiceImpl;
import com.tianju.util.StringUtils;

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

/**
 * 删除一本书
 */

@WebServlet("/opus/remove/vue")
public class RemoveServletVue extends HttpServlet {
    private IOpusService opusService = new OpusServiceImpl();
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        // 获取要删除的id
        String id = req.getParameter("id");
        System.out.println(id);

        // 判断输入不为空
        if (StringUtils.isBlank(id)){
            System.out.println("id为空");
            return;
        }

        // TODO:控制权限
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        // 根据id查一条图书信息出来
        Opus find = opusService.queryById(Integer.parseInt(id));
        if (!find.getAuthorId().equals(user.getId())){
            // 如果修改的 人的id 修改的 不是自己 名下的 就不能修改
            System.out.println("没有权限");
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write(JSON.toJSONString(new ResData(3001, "不能删除别人", null)));
            return;
        }


        // 执行删除操作
        opusService.removeById(Integer.parseInt(id));
        resp.getWriter().write(JSON.toJSONString(new ResData(200, "删除成功", null)));
    }
}


总结

从同步到异步 & 从jsp 到 js + axios + vue 实现 数据分页显示 & 数据增删改查

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/636060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

揭秘报表新玩法!标配插件不再单调,如何用柱形图插件让你的报表瞬间高大上!

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 图表作为一款用于可视化数据的工具&#xff0c;可以帮助我们更好的分析和理解数…

flutter自定义系列之简单的K线图绘制

上篇文章讲了flutter自定义的相关流程&#xff0c; 今天继续练习下flutter的自定义K线&#xff1a; 我们可以通过自定义Painter来实现一个简单的K线图界面&#xff1a; 创建一个自定义的Painter&#xff0c;用于绘制K线图&#xff1a; import dart:ui;import package:flutte…

聊聊多线程

摘要 开发过程中&#xff0c;总会遇到一些并发安全问题。本文总结出常用的数据结构哪些是安全的&#xff0c;哪些是不安全的以及他们为什么是不安全。 java中sychronize锁的原理&#xff1a; 常见的数据结构 类型 数据结构是否安全ArrayList数组 不安全HashMap数…

Mocha Pro:AdjustTrack 模块

跟踪时由于缺乏细节或有障碍物阻挡&#xff0c;跟踪点发生了漂移&#xff0c;或者一个或多个跟踪点可能会离开画面&#xff0c;此时可考虑使用 AdjustTrack &#xff08;调整跟踪&#xff09;模块手动设置关键帧来获得更精准的跟踪数据。 尤其是当要利用表面 Surface区域进行插…

随机数组归并问题

1 问题 生成两个任意的随机数组&#xff0c;并将这两个数组按照数字大小按顺序归并到一个新数组中。 2 方法 思路&#xff1a;定义三个数组&#xff0c;两个数组自己输入值&#xff0c;第三个数组用来作归并后的数组&#xff0c;先将两个数组的值全部赋给第三个数组&#xff0c…

极简主义的远程文件浏览器Mikochi

什么是 Mikochi &#xff1f; Mikochi 是一个远程文件浏览器&#xff0c;用于自托管服务器 / NAS。它允许您浏览远程文件夹、上传文件、删除、重命名、下载和流式传输文件到 VLC/mpv。它带有一个由 JavaScript/Preact 提供支持的 Web 界面&#xff0c;以及一个内置于 Go/Gin 中…

ChatGPT 教我用 200 行代码写一个简版 Vue 框架 - OpenTiny

AI 是未来最好的老师 最近&#xff0c;我正在准备一份关于 Vue 基础的学习材料。期间我突发奇想&#xff1a;能否利用现在热门的 ChatGPT 帮我创建学习内容&#xff1f;其实 Vue 本身不难学&#xff0c;特别是基础用法&#xff0c;但是&#xff0c;如果你想深入掌握 Vue&#…

数据挖掘(7.1)--数据仓库

目录 引言 一、数据库 1.简介 2.数据库管理系统(DBMS) 二、数据仓库 数据仓库特征 数据仓库作用 数据仓库和DBMS对比 分离数据仓库和数据库 引言 数据仓库的历史可以追溯到20世纪60年代&#xff0c;当时计算机领域的主要工作是创建运行在主文件上的单个应用&#xff0…

LaravelPHP笔记-响应头去掉(隐藏)X-Powered-By

最近想搞个小项目&#xff0c;后端先用PHP&#xff0c;框架是Laravel但http响应头如下&#xff1a; 头带有X-Powered-By: PHP/7.3.33&#xff0c;这样很不安全&#xff0c;应该要隐藏&#xff0c;查了下百度。都是一个抄一个。 在代码中添加&#xff1a; header_remove(x-pow…

【几分醉意赠书活动 - 02期】 | 《前端系列丛书》

个人主页&#xff1a; 几分醉意的CSDN博客主页_传送门 个人主页&#xff1a; 陈老板的CSDN博客主页_传送门 赠书活动 | 第二期 本期好书推荐&#xff1a;《前端系列丛书》 粉丝福利&#xff1a;书籍赠送&#xff1a;共计送出30本 参与方式&#xff1a;关注公众号&#xff1a;码…

Flutter控件封装之轮播图Banner

Flutter中实现轮播图的方式有很多种&#xff0c;比如使用三方flutter_swiper&#xff0c;card_swiper等等&#xff0c;使用这些三方&#xff0c;可以很快很方便的实现一个轮播图展示&#xff0c;基本上也能满足我们日常的开发需求&#xff0c;如果说&#xff0c;想要一些定制化…

CloudFlare系列--使用第三方来自定义CDN的IP(笨牛简洁版)

原文网址&#xff1a;CloudFlare系列--使用第三方来自定义CDN的IP(笨牛简洁版)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍CloudFlare的CDN如何自定义第三方IP。 概述 CloudFlare官网接入域名的方式只能是 NS 接入&#xff0c;这样默认DNS服务器只能改为CloudFlare的D…

第3章 需求分析

第3章 需求分析 3.1 需求分析任务 3.1.1 确定对系统的综合要求 1. 功能需求 通过需求分析应该划分出必须完成的所有功能。 2. 性能需求 性能需求指定系统必须满足的定时约束或容量约束 3. 可靠性和可用性需求 可靠性需求定量地指定系统的可靠性 可用性与可靠性密切相关&…

北京某金融公司面试题,精选10道讲解!

你好&#xff0c;我是田哥 面试造火箭工作拧螺丝&#xff0c;最近一位朋友在面试中被问到各种各样的分布式微服务的面试题&#xff0c;也回答上来了。可是&#xff0c;等正式入职后&#xff0c;发现这家公司居然全部是使用单体项目&#xff0c;完全没有分布式微服务的东东&…

个人PC机使用网线与树莓派进行连接

目录 0. 前言1. 查看网络状况2. 设置网络共享3. 获取树莓派的IP 0. 前言 你需要准备一个树莓派4B&#xff0c;自己的电脑&#xff0c;以及一根超五类网线 操作系统&#xff1a;Windows10 专业版、Raspbian OS 开发环境&#xff1a;树莓派4B 1. 查看网络状况 windows控制台…

今年程序员去大厂面试的必备条件:985或211计算机专业,上家公司是大厂,毕业3年且30岁以下,之前产品qps在一万以上!...

什么样的程序员能拿到大厂的面试入场券&#xff1f; 一位网友总结&#xff0c;今年程序员想约到一二三线公司面试需要同时满足以下条件&#xff0c;缺一不可&#xff1a; 1.985或者211硕士&#xff0c;计算机专业&#xff1b; 2.上家公司是大厂&#xff1b; 3.毕业3年以上且年龄…

chatgpt赋能python:Python中的变量定义

Python中的变量定义 在Python中&#xff0c;变量是一种用来存储数据的容器。它们允许程序员为数据分配一个名称&#xff0c;并将该名称与特定的值关联起来。Python语言的灵活性和易用性使得变量定义变得极为简单。 定义变量的基本语法 在Python中&#xff0c;定义变量的语法…

pikachu靶场漏洞演练(更新中)

文章目录 一、XSS(Cross-Site Scripting)1.XSS概述2.漏洞危害3.常用payloadb.反射型XSS&#xff08;post&#xff09;c.存储型XSSd.DOM型XSSe.DOM型XSS-X 一、XSS(Cross-Site Scripting) 1.XSS概述 XSS中文叫做跨站脚本攻击&#xff08;Cross-site scripting&#xff09;&…

BitSet—位图

BitSet &#x1f50e;概念&#x1f50e;位图的模拟实现set()get()reSet()getUsedSize()完整代码 &#x1f50e;利用位图进行排序&#x1f50e;结尾 &#x1f50e;概念 位图 用某一位表示存储的状态 位图的适用场景 海量数据数据为自然数(≥ 0)数据不重复 举个栗子&#x1f3…

内网隧道代理技术(二)之LCX端口转发

LCX端口转发 LCX介绍 LCX是一款端口转发工具&#xff0c;分为Windows版和Linux版&#xff0c;Linux版本为PortMap。LCX有端口映射和端口转发两大功能&#xff0c;例如当目标的3389端口只对内开放而不对外开放时&#xff0c;可以使用端口映射将3389端口映射到目标的其他端口使…