首页 > 其他分享 >使用JSON实现前后端分离项目数据传输

使用JSON实现前后端分离项目数据传输

时间:2024-12-11 21:32:45浏览次数:3  
标签:function 模态 product 分离 JSON pno org 数据传输 servlet

目录

1.创建 Maven Web 工程

2.搭建 SpringMVC 框架 

2.1.导入maven依赖 

2.2.配置spring-mvc.xml 

2.3.配置web.xml 

3.添加实体类&业务类 

3.1.实体类 

3.2.业务类 

4.创建前端项目 

 5.实现商品列表功能

5.1.新增jsp页面 

5.2.导入js、css 

5.3.布局代码 

5.4.js代码 

6.实现新增商品功能 

7.实现删除商品功能 

8.实现编辑商品功能 


1.创建 Maven Web 工程

2.搭建 SpringMVC 框架 

① 导入 maven 依赖 ② 配置 spring-mvc.xml ③ 配置 web.xml

2.1.导入maven依赖 

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.flowerfog</groupId>
    <artifactId>SpringMvcDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<artifactId>experient</artifactId>
<packaging>war</packaging>
<name>experient Maven Webapp</name>
<url>https://maven.apache.org</url>
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <org.springframework.version>6.0.2</org.springframework.version>
    <jakarta.servlet-api.version>5.0.0</jakarta.servlet-api.version>
    <jakarta.servlet.jsp-api.version>3.0.0</jakarta.servlet.jsp-api.version>
    <jakarta.servlet.jsp.jstl-api.version>3.0.1</jakarta.servlet.jsp.jstl-api.version>
    <jakarta.servlet.jsp.jstl.version>3.0.1</jakarta.servlet.jsp.jstl.version>
    <org.junit.jupiter.api.version>5.3.1</org.junit.jupiter.api.version>
    <org.projectlombok.version>1.18.30</org.projectlombok.version>
    <jackson-databind.version>2.17.1</jackson-databind.version>
    <jersey-client.version>1.19.4</jersey-client.version>
</properties>

<dependencies>
    <!--spring web依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <!--spring-webmvc依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <!--servlet-->
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>${jakarta.servlet-api.version}</version>
    </dependency>
    <!--jsp-->
    <dependency>
        <groupId>jakarta.servlet.jsp</groupId>
        <artifactId>jakarta.servlet.jsp-api</artifactId>
        <version>${jakarta.servlet.jsp-api.version}</version>
    </dependency>
    <dependency>
        <groupId>jakarta.servlet.jsp.jstl</groupId>
        <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
        <version>${jakarta.servlet.jsp.jstl-api.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>jakarta.servlet.jsp.jstl</artifactId>
        <version>${jakarta.servlet.jsp.jstl.version}</version>
    </dependency>
    <!--Jackson依赖-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-databind.version}</version>
    </dependency>
    <!--junit5测试-->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${org.junit.jupiter.api.version}</version>
    </dependency>
    <!--lombok插件-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${org.projectlombok.version}</version>
    </dependency>
</dependencies>
<build>
    <finalName>experiment10</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

</project>


2.2.配置spring-mvc.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 将控制器扫描到容器中 -->
    <context:component-scan base-package="org.flowerfog.service"/>
    <context:component-scan base-package="org.flowerfog.controller"/>
    <!-- 开启SpringMVC框架的注解驱动 -->
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--静态资源访问映射路径-->
    <mvc:resources location="/static/" mapping="/static/**"/>

</beans>


2.3.配置web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee">
  <display-name>experiment10</display-name>
  <!-- 配置DispatcherServlet -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 自动加载ssm配置文件 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!--当值≥0时,启动时就加载;当值<0或不指定时,则表示第一次请求时加载-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 配置DispatcherServlet接受所有URL请求 -->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 编码过滤器,解决中文乱码问题 -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>


3.添加实体类&业务类 

 

3.1.实体类 

package org.flowerfog.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
    private String pno;//商品编号-主键
    private String pname;//商品名称
    private String pitem;//商品型号
    private String punit;//商品单位
    private float price;//商品单价
}




 

3.2.业务类 

package org.flowerfog.service;

import org.flowerfog.domain.Product;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ProductService {
    //商品列表
    private static List<Product> products = new ArrayList<>();

    public ProductService() {
        products.add(new Product("P0001", "旺仔牛奶", "WZ", "盒", 5));
        products.add(new Product("P0002", "哇哈哈", "WHH", "盒", 4));
    }

    //新增商品
    public void add(Product product) {
        products.add(product);
    }

    //获取商品列表
    public List<Product> getList() {
        return products;
    }

    //根据商品编号删除商品
    public void delete(String pno) {
        products.removeIf(product -> product.getPno().equals(pno));
    }

    //根据商品编号更新商品信息
    public void update(Product product) {
        for (Product item : products) {
            if (item.getPno().equals(product.getPno())) {
                BeanUtils.copyProperties(product, item);
            }
        }
    }

    // 根据商品编号获取商品
    public Product get(String pno) {
        return products.stream().filter(product -> product.getPno().equals(pno))
                .findFirst().orElse(null);
    }
}



 

4.创建前端项目 

 

 

 

 5.实现商品列表功能

① 新增 jsp 页面 ② 导入 js 、 css ③ 布局代码 ④ js 代码

 

5.1.新增jsp页面 

<%--
  Created by IntelliJ IDEA.
  User: flowerfog
  Date: 2024/12/9
  Time: 8:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
  <title>Title</title>
  <!-- jquery -->
  <script type="text/javascript" src="${pageContext.request.contextPath}/static/jquery-3.6.1.js"></script>
  <!-- layer -->
  <link rel="stylesheet" href="${pageContext.request.contextPath}/static/layer/theme/default/layer.css"/>
  <script type="text/javascript" src="${pageContext.request.contextPath}/static/layer/layer.js"></script>
  <!-- 引入bootstrap -->
  <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/bootstrap/css/bootstrap.css">
  <script type="text/javascript" src="${pageContext.request.contextPath}/static/bootstrap/js/bootstrap.js"></script>
  <!-- 引入bootstrap-table -->
  <link rel="stylesheet" href="${pageContext.request.contextPath}/static/bootstrap-table/bootstrap-table.css"/>
  <script type="text/javascript"
          src="${pageContext.request.contextPath}/static/bootstrap-table/bootstrap-table.js"></script>
  <script type="text/javascript"
          src="${pageContext.request.contextPath}/static/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
</head>
<body class="h-100">
<div class="container-fluid h-100">
  <h5 class="text-center">商品列表</h5>
  <div id="toolbar">
    <div class="input-group col-xs-12">
            <span class="input-group-btn">
                <button class="btn btn-info" id="btnAdd"><span class="glyphicon glyphicon-plus-sign"></span>新增商品</button>
            </span>
    </div>
  </div>
  <table id="gridTable"></table>
  <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" id="myModal">
    <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title" id="myModalLabel">编辑商品</h4>
        </div>
        <div class="modal-body">
          <form id="editForm" role="form" class="form-horizontal">
            <div class="form-group form-item-custom mt-2">
              <label class="col-sm-2 control-label form-item-label">商品编号</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" id="pno"/>
              </div>
            </div>
            <div class="form-group form-item-custom mt-2">
              <label class="col-sm-2 control-label form-item-label">商品名称</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" id="pname"/>
              </div>
            </div>
            <div class="form-group form-item-custom">
              <label class="col-sm-2 control-label form-item-label">商品型号</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" id="pitem"/>
              </div>
            </div>
            <div class="form-group form-item-custom">
              <label class="col-sm-2 control-label form-item-label">商品单位</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" id="punit"/>
              </div>
            </div>
            <div class="form-group form-item-custom">
              <label class="col-sm-2 control-label form-item-label">商品单价</label>
              <div class="col-sm-10">
                <input type="number" class="form-control" id="price"/>
              </div>
            </div>
          </form>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-warning" data-dismiss="modal">关闭</button>
          <button type="button" class="btn btn-primary" id="btnSava">保存</button>
        </div>
      </div>
    </div>
  </div>
</div>

</body>
<script>
  $(function (){
    // 设置dataGrid
    initDataGrid();
    // 绑定新增按钮的点击事件
    $('#btnAdd').click(function () {
      fillData({
        pno: '',
        pname: '',
        pitem: '',
        punit: '',
        price: 0,
      },'add');
    });
    // 绑定模态框中保存按钮的单击事件(关闭按钮的单击事件通过设置data-dismiss属性实现)
    $("#btnSava").click(function(){
      if(formCheck()===false) return;
      //准备需提交的数据
      let postData={
        "pno": $("#pno").val(),
        "pname": $("#pname").val(),
        "pitem": $("#pitem").val(),
        "punit": $("#punit").val(),
        "price": $("#price").val(),
      };
      //执行异步提交
      $.ajax({
        type: "post",
        url: "${pageContext.request.contextPath}/product/save",
        data:JSON.stringify(postData),
        dataType: "json",
        contentType: "application/json;charset=UTF-8",
        success: function (rdata) {
          if (rdata.code===200) {
            // 关闭编辑数据模态窗
            $("#myModal").modal('hide');
            // 刷新列表数据
            $('#gridTable').bootstrapTable('refresh');
          } else {
            // 显示提交错误(不关闭编辑数据模态窗)
            layer.msg(rdata.msg);
          }
        }
      });
    });
    // 首次页面加载,加载数据
    $('#gridTable').bootstrapTable('refresh');
  })

  // 返回选中行数据
  function getSelectedRowsData(selector) {
    return $.map(selector.bootstrapTable("getSelections"),
            function(row) {
              return row; // 返回选中行数据
            });
  }

  // 填充数据到模态框
  function fillData(rowData,op) {
    $("#pno").val(rowData.pno);
    $("#pname").val(rowData.pname);
    $("#pitem").val(rowData.pitem);
    $("#punit").val(rowData.punit);
    $("#price").val(rowData.price);
    $("#btnSava").show();
    // 编辑商品时,禁止修改主键,商品编号只读
    $("#pno").attr("readonly", op==='edit');
    // 模态窗标题
    $('#myModalLabel').html(op==='edit'?'修改商品':'新增商品');
    // 显示编辑数据模态窗
    $("#myModal").modal();
  }
  // 获取表格数据的异步请求
  function ajaxRequest(params) {
    $.ajax({
      url: '${pageContext.request.contextPath}/product/getListData',
      type: "post",
      dataType: "json",
      contentType: "application/json;charset=UTF-8",
      data: JSON.stringify(params.data),
      success: function (res) {
        if (res.code === 200) {
          params.success({ //注意,必须返回参数 params
            total: res.data.length,
            rows: res.data
          });
        } else {
          layer.msg(res.msg);
        }
      },
      error: function (error) {
        console.log(error)
        layer.msg('系统错误,请联系管理员!');
      }
    });
  }
  // 初始化表格数据
  function initDataGrid(){
    $('#gridTable').bootstrapTable({
      ajax: 'ajaxRequest',
      toolbar:'#toolbar',
      queryParams: {},
      idField: 'pno', // 主键字段
      pagination: false,// 不分页
      cache: false,// 不使用缓存
      maintainSelected :true,
      showColumns: true,
      columns: [
        {checkbox: true, visible: true},
        {title: '商品编号', field: 'pno'},
        {title: '商品名称', field: 'pname'},
        {title: '商品型号', field: 'pitem'},
        {title: '商品单位', field: 'punit'},
        {title: '商品单价', field: 'price'},
        {
          title: '操作', field: "operates",
          formatter: function (value, row, index) {
            let btnHtml = '';
            if (row.pno) {
              btnHtml += '<button class="btn btn-info btn-xs mr-1" id="rowDelete"><span class="glyphicon glyphicon-remove-circle"></span>删除</button>';
              btnHtml += '<button class="btn btn-info btn-xs mr-1" id="rowEdit"><span class="glyphicon glyphicon-edit"></span>编辑</button>';
            }
            return btnHtml;
          },
          events: {
            'click #rowDelete': function (e, value, row, index) {//行删除按钮的单击事件
              layer.confirm('您确定要删除编号为'+row.pno+'的商品吗?', {
                btn: ['确定', '取消']
              }, function (index) {//点确定
                layer.close(index);
                //根据主键删除
                $.ajax({
                  type: "get",
                  url: "${pageContext.request.contextPath}/product/delete/" + row.pno,
                  dataType: "json",
                  cache: false,
                  async: false,
                  success: function (rdata) {
                    if (rdata.code == 200) {
                      // 刷新列表数据
                      $('#gridTable').bootstrapTable('refresh');
                    } else {
                      layer.msg(data);
                    }
                  },
                });
              });
            },
            'click #rowEdit': function (e, value, row, index) {//行编辑按钮的单击事件
              fillData(row,'edit');
            }
          }
        },
      ]
    });
  }
  // 模态框保存数据前进行数据验证
  function formCheck() {
    return true;
  }
</script>

</html>



5.2.导入jscss 

 

5.3.布局代码 

 

 

5.4.js代码 

设置bootstrap-table—设置

ajax异步加载列表数据—加载

初始化表格数据—绑定

6.实现新增商品功能 

新增按钮事件

  显示模态框

  模态框标题设置

  模态框数据填充

异步提交数据

  成功->关闭模态框并刷新列表

  失败->显示错误

7.实现删除商品功能 

列表行删除按钮事件定义

删除前提醒对话框

异步删除操作

  成功->刷新列表

  失败->显示错误原因

 

8.实现编辑商品功能 

列表行编辑按钮事件定义

获取选中行数据

模态框数据填充

模态框标题设置

显示模态框

异步保存修改结果

  成功->关闭模态框,并刷新列表

  失败->显示错误原因

 

 

 

 

 

 

标签:function,模态,product,分离,JSON,pno,org,数据传输,servlet
From: https://blog.csdn.net/m0_73302939/article/details/144337198

相关文章

  • 为什么前后端分离的项目中,后端代码比如java servlet中session就无法跟踪客户端
    这是由于前、后端分离架构的特性导致的。原因如下:1.传统的Web应用vs前后端分离:1.传统Web应用:服务器直接生成完整的HTML页面,session可以轻松地通过cookie来维护。2.前后端分离:前端(通常是单页应用SPA)和后端(API服务)是分开的,它们可能运行在不同的域名下。 2.Session的工作原......
  • TCP 数据传输的拆包和粘包了解吗?
    前言:上一篇我们了解了什么是TCP协议,以及TCP协议3次握手4次挥手的原因,本篇来分享一下TCP数据的传输过程的拆包和粘包,以及TCP数据传输过程中的一些细节。计算机网络往期文章TCP为什么是3次握手4次挥手?TCP数据是如何发送接收的?我们知道TCP是传输层协议......
  • 【测试基础】jsonpath使用详解
    jsonpath介绍JsonPath是用来解析多层嵌套的JSON数据。可以认为JsonPath就是JSON版本的XPath。它是一种信息抽取类库,是从JSON文档中抽取指定信息的工具。JsonPath对于JSON来说,就相当于XPath之于XML。JsonPath在线解析:https://jsonpath.com/python在进行接口关联的时候经常会用......
  • 校园二手物品交易市场系统|Java|SSM|VUE| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......
  • 校园点餐系统|Java|SSM|JSP| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......
  • 摊位管理系统|Java|SSM|JSP| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......
  • JsonPath表达式
    JsonPath表达式JsonPath是一种用于查询JSON文档的语言,其语法和用途类似于XPath在XML文档中的应用。JsonPath提供了一种简洁而强大的方式,用于从复杂的JSON结构中提取和定位所需的数据。以下是对JsonPath表达式的详细介绍。基本语法根元素:使用符号$表示JSON文档的根元素。例如,$......
  • go json
    在Go语言中,当爬虫返回JSON数据时,可以通过encoding/json包解析JSON数据并提取其中的值。以下是两种常见方法来解析JSON数据并获取特定字段(如code)。示例JSON数据假设你爬取到的JSON数据如下:json复制代码{"code":200,"message":"成功","data":{......
  • 部署达梦8读写分离集群
    一、原理读写分离集群其实是主备集群的升级版本,在双机热备的基础上把用户写和读的会话事务分别放在主库和备库上执行。写事务会被分发到主库上执行,读事务则部分分发到备库上执行,分发比例在dm_svc.conf中控制,如:RW_PERCENT=25,指的是25%的读分发到主库。由接口负责读写事务的分发......
  • 驾校预约系统|Java|SSM|VUE| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......