前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >9. 前后台协议联调

9. 前后台协议联调

作者头像
捞月亮的小北
发布2023-12-01 10:41:01
1890
发布2023-12-01 10:41:01
举报
文章被收录于专栏:捞月亮的小北

1. 环境准备

  • 创建一个 Web 的 Maven 项目
  • pom.xml 添加 SSM 整合所需 jar 包
  • 创建对应的配置类
  • 编写 Controller、Service 接口、Service 实现类、Dao 接口和模型类
  • resources 下提供 jdbc.properties 配置文件

最终创建好的项目结构如下:

image
image

  1. 资料\SSM功能页面​ 下面的静态资源拷贝到 webapp 下。

image
image

  1. 因为添加了静态资源,SpringMVC 会拦截,所有需要在 SpringConfig 的配置类中将静态资源进行放行。

新建 SpringMvcSupport

代码语言:javascript
复制
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

在 SpringMvcConfig 中扫描 SpringMvcSupport

代码语言:javascript
复制
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}

接下来我们就需要将所有的列表查询、新增、修改、删除等功能一个个来实现下。

2. 列表功能

图书管理

image
image

需求:页面加载完后发送异步请求到后台获取列表数据进行展示。 1.找到页面的钩子函数,created()​ 2.created()​ 方法中调用了this.getAll()​ 方法 3.在 getAll()方法中使用 axios 发送异步请求从后台获取数据 4.访问的路径为http://localhost/books​ 5.返回数据

返回数据 res.data 的内容如下:

代码语言:javascript
复制
{
    "data": [
        {
            "id": 1,
            "type": "计算机理论",
            "name": "Spring实战 第五版",
            "description": "Spring入门经典教程,深入理解Spring原理技术内幕"
        },
        {
            "id": 2,
            "type": "计算机理论",
            "name": "Spring 5核心原理与30个类手写实践",
            "description": "十年沉淀之作,手写Spring精华思想"
        },...
    ],
    "code": 20041,
    "msg": ""
}

发送方式:

代码语言:javascript
复制
getAll() {
    //发送ajax请求
    axios.get("/books").then((res)=>{
        this.dataList = res.data.data;
    });
}

image
image

3. 添加功能

image
image

需求:完成图片的新增功能模块 1.找到页面上的新建​ 按钮,按钮上绑定了@click="handleCreate()"​ 方法 2.在 method 中找到handleCreate​ 方法,方法中打开新增面板 3.新增面板中找到确定​ 按钮,按钮上绑定了@click="handleAdd()"​ 方法 4.在 method 中找到handleAdd​ 方法 5.在方法中发送请求和数据,响应成功后将新增面板关闭并重新查询数据

handleCreate​ 打开新增面板

代码语言:javascript
复制
handleCreate() {
    this.dialogFormVisible = true;
},

handleAdd​ 方法发送异步请求并携带数据

代码语言:javascript
复制
handleAdd () {
    //发送ajax请求
    //this.formData是表单中的数据,最后是一个json数据
    axios.post("/books",this.formData).then((res)=>{
        this.dialogFormVisible = false;
        this.getAll();
    });
}

4. 添加功能状态处理

基础的新增功能已经完成,但是还有一些问题需要解决下:

需求:新增成功是关闭面板,重新查询数据,那么新增失败以后该如何处理? 1.在 handlerAdd 方法中根据后台返回的数据来进行不同的处理 2.如果后台返回的是成功,则提示成功信息,并关闭面板 3.如果后台返回的是失败,则提示错误信息

(1)修改前端页面

代码语言:javascript
复制
handleAdd () {
    //发送ajax请求
    axios.post("/books",this.formData).then((res)=>{
        //如果操作成功,关闭弹层,显示数据
        if(res.data.code == 20011){
            this.dialogFormVisible = false;
            this.$message.success("添加成功");
        }else if(res.data.code == 20010){
            this.$message.error("添加失败");
        }else{
            this.$message.error(res.data.msg);
        }
    }).finally(()=>{
        this.getAll();
    });
}

(2)后台返回操作结果,将 Dao 层的增删改方法返回值从void​ 改成int

代码语言:javascript
复制
public interface BookDao {

//    @Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
    @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
    public int save(Book book);

    @Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
    public int update(Book book);

    @Delete("delete from tbl_book where id = #{id}")
    public int delete(Integer id);

    @Select("select * from tbl_book where id = #{id}")
    public Book getById(Integer id);

    @Select("select * from tbl_book")
    public List<Book> getAll();
}

(3)在 BookServiceImpl 中,增删改方法根据 DAO 的返回值来决定返回 true/false

代码语言:javascript
复制
@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    public boolean save(Book book) {
        return bookDao.save(book) > 0;
    }

    public boolean update(Book book) {
        return bookDao.update(book) > 0;
    }

    public boolean delete(Integer id) {
        return bookDao.delete(id) > 0;
    }

    public Book getById(Integer id) {
        if(id == 1){
            throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
        }
//        //将可能出现的异常进行包装,转换成自定义异常
//        try{
//            int i = 1/0;
//        }catch (Exception e){
//            throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
//        }
        return bookDao.getById(id);
    }

    public List<Book> getAll() {
        return bookDao.getAll();
    }
}

(4)测试错误情况,将图书类别长度设置超出范围即可

image
image

处理完新增后,会发现新增还存在一个问题,

新增成功后,再次点击新增​ 按钮会发现之前的数据还存在,这个时候就需要在新增的时候将表单内容清空。

代码语言:javascript
复制
resetForm(){
	this.formData = {};
}
handleCreate() {
    this.dialogFormVisible = true;
    this.resetForm();
}

5. 修改功能

image
image

需求:完成图书信息的修改功能 1.找到页面中的编辑​ 按钮,该按钮绑定了@click="handleUpdate(scope.row)"​ 2.在 method 的handleUpdate​ 方法中发送异步请求根据 ID 查询图书信息 3.根据后台返回的结果,判断是否查询成功 如果查询成功打开修改面板回显数据,如果失败提示错误信息 4.修改完成后找到修改面板的确定​ 按钮,该按钮绑定了@click="handleEdit()"​ 5.在 method 的handleEdit​ 方法中发送异步请求提交修改数据 6.根据后台返回的结果,判断是否修改成功 如果成功提示错误信息,关闭修改面板,重新查询数据,如果失败提示错误信息

scope.row 代表的是当前行的行数据,也就是说,scope.row 就是选中行对应的 json 数据,如下:

代码语言:javascript
复制
{
  "id": 1,
  "type": "计算机理论",
  "name": "Spring实战 第五版",
  "description": "Spring入门经典教程,深入理解Spring原理技术内幕"
}

修改handleUpdate​ 方法

代码语言:javascript
复制
//弹出编辑窗口
handleUpdate(row) {
    // console.log(row);   //row.id 查询条件
    //查询数据,根据id查询
    axios.get("/books/"+row.id).then((res)=>{
        if(res.data.code == 20041){
            //展示弹层,加载数据
            this.formData = res.data.data;
            this.dialogFormVisible4Edit = true;
        }else{
            this.$message.error(res.data.msg);
        }
    });
}

修改handleEdit​ 方法

代码语言:javascript
复制
handleEdit() {
    //发送ajax请求
    axios.put("/books",this.formData).then((res)=>{
        //如果操作成功,关闭弹层,显示数据
        if(res.data.code == 20031){
            this.dialogFormVisible4Edit = false;
            this.$message.success("修改成功");
        }else if(res.data.code == 20030){
            this.$message.error("修改失败");
        }else{
            this.$message.error(res.data.msg);
        }
    }).finally(()=>{
        this.getAll();
    });
}

至此修改功能就已经完成。

6. 删除功能

​​

image
image

​​

需求:完成页面的删除功能。 1.找到页面的删除按钮,按钮上绑定了@click="handleDelete(scope.row)"​ 2.method 的handleDelete​ 方法弹出提示框 3.用户点击取消,提示操作已经被取消。 4.用户点击确定,发送异步请求并携带需要删除数据的主键 ID 5.根据后台返回结果做不同的操作 如果返回成功,提示成功信息,并重新查询数据 如果返回失败,提示错误信息,并重新查询数据

修改handleDelete​ 方法

代码语言:javascript
复制
handleDelete(row) {
    //1.弹出提示框
    this.$confirm("此操作永久删除当前数据,是否继续?","提示",{
        type:'info'
    }).then(()=>{
        //2.做删除业务
        axios.delete("/books/"+row.id).then((res)=>{
            if(res.data.code == 20021){
                this.$message.success("删除成功");
            }else{
                this.$message.error("删除失败");
            }
        }).finally(()=>{
            this.getAll();
        });
    }).catch(()=>{
        //3.取消删除
        this.$message.info("取消删除操作");
    });
}

接下来,下面是一个完整页面

代码语言:javascript
复制
<!DOCTYPE html>

<html>
  <head>
    <!-- 页面meta -->

    <meta charset="utf-8" />

    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <title>SpringMVC案例</title>

    <meta
      content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
      name="viewport"
    />

    <!-- 引入样式 -->

    <link rel="stylesheet" href="../plugins/elementui/index.css" />

    <link
      rel="stylesheet"
      href="../plugins/font-awesome/css/font-awesome.min.css"
    />

    <link rel="stylesheet" href="../css/style.css" />
  </head>

  <body class="hold-transition">
    <div id="app">
      <div class="content-header">
        <h1>图书管理</h1>
      </div>

      <div class="app-container">
        <div class="box">
          <div class="filter-container">
            <el-input
              placeholder="图书名称"
              v-model="pagination.queryString"
              style="width: 200px;"
              class="filter-item"
            ></el-input>

            <el-button @click="getAll()" class="dalfBut">查询</el-button>

            <el-button type="primary" class="butT" @click="handleCreate()"
              >新建</el-button
            >
          </div>

          <el-table
            size="small"
            current-row-key="id"
            :data="dataList"
            stripe
            highlight-current-row
          >
            <el-table-column
              type="index"
              align="center"
              label="序号"
            ></el-table-column>

            <el-table-column
              prop="type"
              label="图书类别"
              align="center"
            ></el-table-column>

            <el-table-column
              prop="name"
              label="图书名称"
              align="center"
            ></el-table-column>

            <el-table-column
              prop="description"
              label="描述"
              align="center"
            ></el-table-column>

            <el-table-column label="操作" align="center">
              <template slot-scope="scope">
                <el-button
                  type="primary"
                  size="mini"
                  @click="handleUpdate(scope.row)"
                  >编辑</el-button
                >

                <el-button
                  type="danger"
                  size="mini"
                  @click="handleDelete(scope.row)"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>

          <!-- 新增标签弹层 -->

          <div class="add-form">
            <el-dialog title="新增图书" :visible.sync="dialogFormVisible">
              <el-form
                ref="dataAddForm"
                :model="formData"
                :rules="rules"
                label-position="right"
                label-width="100px"
              >
                <el-row>
                  <el-col :span="12">
                    <el-form-item label="图书类别" prop="type">
                      <el-input v-model="formData.type" />
                    </el-form-item>
                  </el-col>

                  <el-col :span="12">
                    <el-form-item label="图书名称" prop="name">
                      <el-input v-model="formData.name" />
                    </el-form-item>
                  </el-col>
                </el-row>

                <el-row>
                  <el-col :span="24">
                    <el-form-item label="描述">
                      <el-input
                        v-model="formData.description"
                        type="textarea"
                      ></el-input>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>

              <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取消</el-button>

                <el-button type="primary" @click="handleAdd()">确定</el-button>
              </div>
            </el-dialog>
          </div>

          <!-- 编辑标签弹层 -->

          <div class="add-form">
            <el-dialog
              title="编辑检查项"
              :visible.sync="dialogFormVisible4Edit"
            >
              <el-form
                ref="dataEditForm"
                :model="formData"
                :rules="rules"
                label-position="right"
                label-width="100px"
              >
                <el-row>
                  <el-col :span="12">
                    <el-form-item label="图书类别" prop="type">
                      <el-input v-model="formData.type" />
                    </el-form-item>
                  </el-col>

                  <el-col :span="12">
                    <el-form-item label="图书名称" prop="name">
                      <el-input v-model="formData.name" />
                    </el-form-item>
                  </el-col>
                </el-row>

                <el-row>
                  <el-col :span="24">
                    <el-form-item label="描述">
                      <el-input
                        v-model="formData.description"
                        type="textarea"
                      ></el-input>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>

              <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible4Edit = false"
                  >取消</el-button
                >

                <el-button type="primary" @click="handleEdit()">确定</el-button>
              </div>
            </el-dialog>
          </div>
        </div>
      </div>
    </div>
  </body>

  <!-- 引入组件库 -->

  <script src="../js/vue.js"></script>

  <script src="../plugins/elementui/index.js"></script>

  <script type="text/javascript" src="../js/jquery.min.js"></script>

  <script src="../js/axios-0.18.0.js"></script>

  <script>
    var vue = new Vue({
      el: "#app",
      data: {
        pagination: {},
        dataList: [], //当前页要展示的列表数据
        formData: {}, //表单数据
        dialogFormVisible: false, //控制表单是否可见
        dialogFormVisible4Edit: false, //编辑表单是否可见
        rules: {
          //校验规则
          type: [
            { required: true, message: "图书类别为必填项", trigger: "blur" },
          ],
          name: [
            { required: true, message: "图书名称为必填项", trigger: "blur" },
          ],
        },
      },

      //钩子函数,VUE对象初始化完成后自动执行
      created() {
        this.getAll();
      },

      methods: {
        //列表
        getAll() {
          //发送ajax请求
          axios.get("/books").then((res) => {
            this.dataList = res.data.data;
          });
        },

        //弹出添加窗口
        handleCreate() {
          this.dialogFormVisible = true;
          this.resetForm();
        },

        //重置表单
        resetForm() {
          this.formData = {};
        },

        //添加
        handleAdd() {
          //发送ajax请求
          axios
            .post("/books", this.formData)
            .then((res) => {
              console.log(res.data);
              //如果操作成功,关闭弹层,显示数据
              if (res.data.code == 20011) {
                this.dialogFormVisible = false;
                this.$message.success("添加成功");
              } else if (res.data.code == 20010) {
                this.$message.error("添加失败");
              } else {
                this.$message.error(res.data.msg);
              }
            })
            .finally(() => {
              this.getAll();
            });
        },

        //弹出编辑窗口
        handleUpdate(row) {
          // console.log(row);   //row.id 查询条件
          //查询数据,根据id查询
          axios.get("/books/" + row.id).then((res) => {
            // console.log(res.data.data);
            if (res.data.code == 20041) {
              //展示弹层,加载数据
              this.formData = res.data.data;
              this.dialogFormVisible4Edit = true;
            } else {
              this.$message.error(res.data.msg);
            }
          });
        },

        //编辑
        handleEdit() {
          //发送ajax请求
          axios
            .put("/books", this.formData)
            .then((res) => {
              //如果操作成功,关闭弹层,显示数据
              if (res.data.code == 20031) {
                this.dialogFormVisible4Edit = false;
                this.$message.success("修改成功");
              } else if (res.data.code == 20030) {
                this.$message.error("修改失败");
              } else {
                this.$message.error(res.data.msg);
              }
            })
            .finally(() => {
              this.getAll();
            });
        },

        // 删除
        handleDelete(row) {
          //1.弹出提示框
          this.$confirm("此操作永久删除当前数据,是否继续?", "提示", {
            type: "info",
          })
            .then(() => {
              //2.做删除业务
              axios
                .delete("/books/" + row.id)
                .then((res) => {
                  if (res.data.code == 20021) {
                    this.$message.success("删除成功");
                  } else {
                    this.$message.error("删除失败");
                  }
                })
                .finally(() => {
                  this.getAll();
                });
            })
            .catch(() => {
              //3.取消删除
              this.$message.info("取消删除操作");
            });
        },
      },
    });
  </script>
</html>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 环境准备
  • 2. 列表功能
  • 3. 添加功能
  • 4. 添加功能状态处理
  • 5. 修改功能
  • 6. 删除功能
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档