项目实战_表白墙(简易版)

你能学到什么

  • 一个比较简单的项目:表白墙(简易版),浏览器:谷歌
  • 升级版将在下个博客发布

效果如下
在这里插入图片描述

正文

说明

我们是从0开始一步一步做这个项目的,里面的各种问题,我也会以第一人称视角来解决,希望你们看了能感同身受,有所收获。

第一步:把项目建起来

在这里插入图片描述
在这里插入图片描述

注意:

你所创建的所有package或者class 必须和启动类在同一个路径上,启动类是什么:就是一开始就自动生成的,并且以Application结尾的那个类。
所以我们必须在leavemessage_blogs下面建包,或者建类。
在这里插入图片描述
对于测试代码和开发的规则也是一样的,要在 leavemessage_blogs下面建包或者建类。

第二步:配置文件

由于文件不能导入,所以前端的代码直接自己新建就行了,然后复制我的代码到你的前端html文件里。注意:你新建的文件可能有一些自动生成的代码,复制我的代码直接覆盖就行了。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 代码如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>留言板</title><style>.container {width: 350px;height: 300px;margin: 0 auto;/* border: 1px black solid; */text-align: center;}.grey {color: grey;}.container .row {width: 350px;height: 40px;display: flex;justify-content: space-between;align-items: center;}.container .row input {width: 260px;height: 30px;}#submit {width: 350px;height: 40px;background-color: orange;color: white;border: none;margin: 10px;border-radius: 5px;font-size: 20px;}</style>
</head><body><div class="container"><h1>留言板</h1><p class="grey">输入后点击提交, 会将信息显示下方空白处</p><div class="row"><span>:</span> <input type="text" name="" id="from"></div><div class="row"><span>对谁:</span> <input type="text" name="" id="to"></div><div class="row"><span>说什么:</span> <input type="text" name="" id="say"></div><input type="button" value="提交" id="submit" onclick="submit()"><!-- <div>AB : hello</div> --></div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>function submit(){//1. 获取留言的内容var from = $('#from').val();var to = $('#to').val();var say = $('#say').val();if (from== '' || to == '' || say == '') {return;}//2. 构造节点var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";//3. 把节点添加到页面上    $(".container").append(divE);//4. 清空输入框的值$('#from').val("");$('#to').val("");$('#say').val("");}</script>
</body></html>

搞完前端的文件配置以后我们就能测试了,启动程序,然后用浏览器访问这个html页面,看看我们复制的对不对
在这里插入图片描述

看到这个以后就证明我们复制的没问题,如果你此时直接在该网页输入数据测试,也是没有错误的,但那是前端的实现,一刷新就没了,我们是要使用后端实现的,所以我们还要改代码,设计后端接口,熟悉理解后端接口才是此项目的目的。

在这里插入图片描述

第三步:约定前后端交互接⼝

需求分析:
后端需要提供两个服务

  1. 提交留⾔: ⽤⼾输⼊留⾔信息之后, 后端需要把留⾔信息保存起来
  2. 展⽰留⾔: ⻚⾯展⽰时, 需要从后端获取到所有的留⾔信息
  • 浏览器给服务器发送⼀个 GET /message/getList 这样的请求, 就能返回当前⼀共有哪些留⾔记录. 结果以 json 的格式返回过来.

第四步:编写服务器代码

实体类代码

定义留⾔对象 MessageInfo 类,我们将实体类都单独放在包model里,这是应用分层里的规范。

在这里插入图片描述

在这里插入图片描述

package com.example.leavemessage_blogs.model;import lombok.Data;@Data
public class MessageInfo {private String from;private String to;private String message;
}

controller代码

依据应用分层的概念,我们依旧是建了一个package存放controller类。
在这里插入图片描述

package com.example.leavemessage_blogs.Controller;import com.example.leavemessage_blogs.model.MessageInfo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;@RequestMapping("/message")
@RestController
public class MessageController {//创建一个list来储存数据public List<MessageInfo> list = new ArrayList<>();@RequestMapping("getList")public List<MessageInfo> getList(){return list;}@RequestMapping("/addInfo")public boolean addInfo(MessageInfo messageInfo){if(StringUtils.hasLength(messageInfo.getFrom())&&StringUtils.hasLength(messageInfo.getTo())&&StringUtils.hasLength(messageInfo.getMessage())){list.add(messageInfo);return true;}return false;}
}

写完controller代码后我们就能测试了

测试getList接口

可以看出来没有问题,因为此时我们还没有添加元素呢,所以返回为空
在这里插入图片描述

测试addInfo接口

可以看到:也没有太大的问题,如果你感觉看不到效果,不放心,你可一再次调用getList接口,看看这个信息是否被添加进来了。
在这里插入图片描述
为了验证,我们调用getList接口验证信息是否被添加进来了,可以看到:没有问题
在这里插入图片描述

第五步:修改前端代码

为什么是修改而不是编写:因为我们以后端的开发为主要,所以前端的代码能大概看懂就好,不要求掌握,以后的前端代码也是以开源的形式直接复制粘贴的。

1,添加 load 函数, ⽤于在⻚⾯加载的时候获取数据

    load();function load() {$.ajax({type: "get",url: "/message/getList",success: function (result) {for (var message of result) {var divE = "<div>" + message.from + "对" + message.to + "说:" + message.message + "</div>";$(".container").append(divE);}}});}

在这里插入图片描述

这个代码能复制就复制,看懂个大概就行了

  • 注意:在这里插入图片描述

2. 修改原来的点击事件函数submit

可以将这段代码直接覆盖掉原来的submit函数,也可以自己看着注释的思路敲一遍,这里面有很多重复的代码,能直接复制的很多,可以尝试一下,并不费劲。

function submit(){//1. 获取留言的内容var from = $('#from').val();var to = $('#to').val();var say = $('#say').val();if (from== '' || to == '' || say == '') {return;}//在这里将请求发送到后端,也是采用ajax的方式$.ajax({type: "post",url: "message/addInfo",//这里的url不要弄错了data:{from:from,to:to,message:say},success:function (ret){//如果后端返回了true证明添加成功了,就将数据全部添加到网页上if(ret){//这里面都是添加页面元素的操作,了解即可//2. 构造节点var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";//3. 把节点添加到页面上$(".container").append(divE);//4. 清空输入框的值$('#from').val("");$('#to').val("");$('#say').val("");}else{alert("留言失败!")}}});}

第六步:测试

以上就是该简易表白墙的所有内容,此时我们就能启动程序,再次访问message.html页面,看看他是否能正常运行。

注意:

  • 1,此时的前端页面可能会有缓存,可以使用ctrl+F5进行强刷,然后右键查看网页源代码,看看我们的前端代码是否改过来了。在这里插入图片描述
  • 2,我用的是谷歌浏览器,因为他的兼容性……在现今的浏览器中属于很nb的那种,可以去官网下载一下,很好用。
    在这里插入图片描述
    此时意外发生了,在我填完信息之后,我点击提交按钮后,前端是没有反应的,证明有bug了。

排查bug

  • 第一步:按F12,看前端页面有没有报错,如果有大于一个报错的话,看第二个报错(原因一会儿说)
    在这里插入图片描述
  • 第二步:看是前端的问题还是后端的问题
    如果你点了蓝色的字,会自动帮你定位错误的位置,很实用的小技巧
    之后我就看到了他给我的一个逗号标上了错误,但他也不是中文符号啊,为啥报错呢?于是我重新写了一个英文逗号,然后再在前端强刷了一下,就好了,估计是idea识别的问题吧。
  • 上面我们说到了要看第二个报错,这是因为即使程序成功运行了,也会有一个错误,所以:“ 没有报错 ” == “ 有一个默认错误 ”,如下:(所以我们通常看第二个错误)
    在这里插入图片描述

遇到bug的处理歩奏

  • 1,按F12,看前端页面有没有报错,如果有大于一个报错的话,看第二个
  • 2,如果前端有报错,直接处理前端代码
  • 3,如果前端没有报错,那就在接受参数的函数第一行,加入执行的日志,看看参数传递到底有没有问题
    在这里插入图片描述
  • 4,如果传参没有问题,那就是后端的问题,通过调试等方法找问题
  • 5,如果传参有问题,那就是前端的参数没有传递到后端,到前端检查问题
  • 6,另外还有一个隐藏的问题就是缓存,如果实在检查不出来问题了,那就请一下缓存试试,看是否是代码是不是没有更新,双击clean就是清理缓存。还有就是前端的强刷,也很常用,搞不出来就试试。

修复bug成功:

此时我们提交一个留言就会显示一个留言,这样就成功了,此时无论我们怎么刷新数据都不会掉了,因为此时的数据是保存在内存中的,是由后端来做的,而不是由前端直接管理,这也能作为评判我们是用后端代码实现的还是用前端代码实现的。
说到这里我们会发现,如果这样搞,那我们每次重启后端代码之后,我们以前存储的数据就会丢失,这是因为,我们将数据都储存在内存中了,那么有没有一种方式能够长久的保存我的数据呢?这样我每次启动后端的时候数据就不会丢失了。这样的方式当然是有的:那就使用数据库来存储那些信息,由于以往的单纯的sql传递十分繁琐,所以我们会使用Mybatis来操作数据库,这种方式更加方便,这也是我们的表白墙进阶要使用的方式。

在这里插入图片描述

如果在此过程中,遇到什么报错了,欢迎评论留言,我们一起解决。

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

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

相关文章

yolov10在地平线旭日X3派上的部署和测试(Python版本和C++版本)

0、搭建开发环境 当前的测试根据一下的步骤并修改源码是可以实现yolov8的板端运行&#xff0c;如果不想再搭建环境和测试代码bug上浪费更多的时间可以直接获取本人的测试虚拟机&#xff0c;所有的测试代码、虚拟环境和板端测试工程以全部打包到了虚拟机&#xff0c;需要的可以…

OpenBayes 教程上新 | 文生图、图生图、图像修复三合一神器, HiDiffusion 一键启动教程现已上线!

扩散模型已成为高分辨率图像合成的主流方法&#xff0c;传统的扩散模型虽然在图像合成方面取得了显著进展&#xff0c;但在扩展到更高分辨率时往往面临对象重复和计算成本增加的问题。 旷世科技开源的高分辨率框架 HiDiffusion&#xff0c;由分辨率感知 U-Net (RAU-Net) 和改进…

求最大公约数与最小公倍数(C语言 简洁快速版)

求最大公约数 辗转相除法&#xff08;首选&#xff0c;因为简单快捷&#xff09; 思路&#xff1a; 1.将两整数求余 a%b c 2.如果c 0;则b为最大公约数 3.如果c ! 0,则 a b&#xff1b;b c&#xff1b;继续从1开始执行 4.也就是说该循环的是否继续的判断条件就是c是否为0 …

3.4、图

图的介绍 图也是一种非线性结构&#xff0c;图中任意两个节点间都可能有直接关系。相关定义如下&#xff1a; 无向图&#xff1a;图的结点之间连接线是没有箭头的&#xff0c;不分方向。 有向图&#xff1a;图的结点之间连接线是箭头&#xff0c;区分A到B,和B到A是两条线。 …

Codeforces 962 div3 A-F

A 题目分析 签到 C代码 #include<iostream> using namespace std; int main(){int t;cin>>t;while(t--){int n;cin>>n;cout<<n/4n%4/2<<endl;} } B 题目分析 将n*n的方格分成若干个k*k的方格&#xff0c;每个k*k的方格中所有的数都相同 遍历…

SwiftUI知识点(四)

NavigationStack import SwiftUIstruct NavigationStackBootcamp: View {let fruits ["Apple", "Orange", "Banana"]///路径数组State private var stackPath: [String] []var body: some View {NavigationStack(path: $stackPath) {VStack{B…

RocketMQ的Admin Tool工具

文档&#xff1a;https://github.com/apache/rocketmq/blob/develop/docs/cn/operation.md写的很全面&#xff0c;我写了一半就偷懒了&#xff0c;地址放这里。 命令大全&#xff1a;https://github.com/apache/rocketmq/blob/develop/docs/cn/operation.md 1. 删除讨厌的告警…

文献笔记|综述|A Survey of Large Language Models (前3章)

A Survey of Large Language Models 题目&#xff1a;大语言模型综述 作者&#xff1a;Wayne Xin Zhao, Kun Zhou, Junyi Li et al. 来源&#xff1a;arXiv 单位&#xff1a;中国人民大学高瓴人工智能学院、中国人民大学信息学院 关键词&#xff1a;Large Language Models; Eme…

AI之AI by Hand:AI by Hand(手动自定义AI算法的数学逻辑)的简介、使用方法、案例应用之详细攻略

AI之AI by Hand&#xff1a;AI by Hand(手动自定义AI算法的数学逻辑)的简介、使用方法、案例应用之详细攻略 目录 AI by Hand的简介 AI by Hand的使用方法 1、解读混合专家&#xff08;MoE&#xff09; 2、解读LSTM (Long Short-Term Memory) AI by Hand的案例应用 AI by …

学习大数据DAY25 Shell脚本的书写2与Shell工具的使用

目录 自定义函数 递归-自己调用自己 上机练习 12 Shell 工具 sort sed awk 上机练习 13 自定义函数 name(){ action; } function name { Action; } name 因为 shell 脚本是从上到下逐行运行&#xff0c;不会像其它语言一样先编译&#xff0c;所以函数必 须在调…

MyBatis-Plus自动生成代码

目录 前言一. 什么是 MyBatis-Plus1. Mybatis-Plus 的特点2. Mybatis-Plus 结构二. MyBatis-Plus 自动生成步骤1. 数据库准备2. 环境准备(1) 创建一个空的 Spring Boot 工程(2) 导入pom依赖(3) 编辑application.yml文件(4) 在启动类加入 @MapperScan 注解3. 配置代码4. 运行三.…

江科大/江协科技 STM32学习笔记P15

文章目录 TIM输出比较1、输出比较简介2、PWM简介3、输出比较通道&#xff08;高级&#xff09;4、输出比较通道&#xff08;通用&#xff09;5、输出比较模式6、PWM基本结构参数计算 7、舵机简介8、直流电机及驱动简介驱动芯片 TIM输出比较 1、输出比较简介 CNT计数器&#x…

VUE3——003、VUE 项目中的文件结构(index.html、main.ts、App.vue)

虽然是号称是小白初学&#xff0c;但本文只是对 VUE 小白&#xff0c;其它的基功还是有一丢丢的&#xff0c;不太懂的同学去看看一下详解&#xff0c;我这里记述的是自己的理解和观点。见谅&#xff01; index.html&#xff1a;入口文件&#xff08;以创建 vue3 项目的默认文件…

ElasticSearch(es)倒排索引

目录 一、ElasticSearch 二、倒排索引 1. 正向索引 2. 倒排索引 具体细节 1. 文档分析 2. 索引构建 3. 索引存储 4. 词条编码 5. 索引优化 6. 查询处理 示例 总结 3. 正向和倒排 三、总结 倒排索引的基本概念 为什么倒排索引快 一、ElasticSearch Elasticsear…

Vue 3 中使用 InMap 绘制热力图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 3 中使用 InMap 绘制热力图 应用场景介绍 InMap 是一款强大的地图组件库&#xff0c;它提供了一系列丰富的可视化功能&#xff0c;包括热力图。热力图可以将数据点在地图上以颜色编码的方式可视化&#x…

论文阅读_字节的语音生成模型_Seed-TTS

英文名称: Seed-TTS: A Family of High-Quality Versatile Speech Generation Models 中文名称: Seed-TTS&#xff1a;高质量多功能语音生成模型系列 链接: http://arxiv.org/abs/2406.02430v1 代码: https://github.com/BytedanceSpeech/seed-tts-eval (评测工具) 演示网站&am…

找出所有点到一个点的距离的最小值

这个题的看一眼有点像树形dp&#xff0c;但是要怎么去优化我们转移方程呢 这是为什么呢&#xff0c;我们的树形dp很难考虑来之前的答案&#xff0c;那么d[y] 怎么办&#xff0c;我们可以先以1为根计算出以1为根的答案 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.…

js 计算小数精度问题 ,引入decimal.js库 解决

安装 npm install --save decimal.js 引入 import Decimal from "decimal.js" 使用 new Decimal function adddDecimals (...decimals) { let sum new Decimal(0) decimals.forEach(decimal > { sum sum.plus(decimal) }) return sum.toNumber() } const res …

【刷题汇总 -- 笨小猴、 主持人调度(一)、分割等和子集】

C日常刷题积累 今日刷题汇总 - day0251、笨小猴1.1、题目1.2、思路1.3、程序实现 2、主持人调度&#xff08;一&#xff09;2.1、题目2.2、思路2.3、程序实现 3、分割等和子集3.1、题目3.2、思路3.3、程序实现 -- 0/1背包问题 4、题目链接 今日刷题汇总 - day025 1、笨小猴 1…