1 留言板
需求:界面如下图所示
- 输入留言信息,点击提交。后端把数据存储起来.
- 页面展示输入的表白墙的信息

1.1 约定前后端交互接口
需求分析
后端需要提供两个服务
- 提交留言:用户输入留言信息之后,后端需要把留言信息保存起来
- 展示留言:页面展示时,需要从后端获取到所有的留言信息
接口定义
- 获取全部留言全部留言信息,我们用 List 来表示,可以用 JSON 来描述这个 List 数据.
请求:
GET /message/getList
响应:JSON 格式
html
[
{
"from": "黑猫",
"to": "白猫",
"message": "喵"
},{
"from": "黑狗",
"to": "白狗",
"message": "汪"
},...
]
浏览器给服务器发送一个 GET /message/getList 这样的请求,就能返回当前一共有哪些留言记录。结果以 json 的格式返回过来.
- 发表新留言
-
发表新留言请求:body 也为 JSON 格式.
POST /message/publish
{
"from": "黑猫",
"to": "白猫",
"message": "喵"
}
响应:JSON 格式.
{
ok: 1
}
我们期望浏览器给服务器发送一个 POST /message/publish 这样的请求,就能把当前的留言提交给服务器.
1.2实现服务器端代码
1.2.1 lombok 介绍
在这个环节,我们介绍一个新的工具包 lombokLombok 是一个 Java 工具库,通过添加注解的方式,简化 Java 的开发.简单来学习下它的使用
1.引入依赖
java
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
第二种:

2.使用
lombok 通过一些注解的方式,可以帮助我们消除一些冗长代码,使代码看起来简洁一些比如之前的 Person 对象 就可以改为
java
@Data
public class Person {
private int id;
private String name;
private String password;
}
@Data 注解会帮助我们自动一些方法,包含 getter/setter, equals, toString 等
原来需要些这个getter和setter
target里面是加载的maven后产生的核心目录
原来需要些这个getter和setter
现在只需要加入一个@data 就可以了

target里的


这个的生命周期只是source阶段的,所以我们看的这个target就不存在了
Lombok 等编译期工具的注解(如@Data)仅在源码阶段生效
3.原理解释
可以观察加了 @Data 注解之后,Idea 反编译的.
class 文件这不是真正的字节码文件,而是 Idea 根据字节码进行反编译后的文件反编译是将可执行的程序代码转换为某种形式的高级编程语言,使其具有更易读的格式。反编译是一种逆向工程,它的作用与编译器的作用相反.


可以看出来,lombok是⼀款在编译期⽣成代码的⼯具包.
Java 程序的运行原理

Lombok的作用如下图所示:

4.更多使用
如果觉得 @Data 比较粗暴 (生成方法太多),lombok 也提供了一些更精细粒度的注解
![]() |
|---|
@Data = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor
1.2更快捷的引入依赖
上述引入 lombok 依赖,需要去找 lombok 的坐标接下来介绍更简单引入依赖的方式
- 安装插件 EditStarter, 重启 Idea

- 在pom.xml⽂件中,单击右键,选择Generate,操作如下图所示

进⼊EditStarters的编辑界⾯,添加对应依赖即可

1.3 服务器代码实现
定义留言对象 MessageInfo 类
java
import lombok.Data;
@Data
public class MessageInfo {
private String from;
private String to;
private String message;
}
创建 MessageController 类使用List<MessageInfo>来存储留言板信息
java
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 {
private List<MessageInfo> messageInfos = new ArrayList<>();
@RequestMapping("/getList")
public List<MessageInfo> getList() {
return messageInfos;
}
@RequestMapping("/publish")
public boolean publish(MessageInfo messageInfo) {
System.out.println(messageInfo);
if (StringUtils.hasLength(messageInfo.getFrom())
&& StringUtils.hasLength(messageInfo.getTo())
&& StringUtils.hasLength(messageInfo.getMessage())) {
messageInfos.add(messageInfo);
return true;
}
return false;
}
}
1.4 调整前端页面代码修改 messagewall.html
- 添加 load 函数,用于在页面加载的时候获取数据
javascript
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);
}
}
});
}
- 修改原来的点击事件函数。在点击按钮的时候给服务器发送添加留言请求
javascript
function submit() {
//1. 获取留言的内容
var from = $("#from").val();
var to = $("#to").val();
var say = $("#say").val();
if (from == '' || to == '' || say == '') {
return;
}
$.ajax({
type: "post",
url: "/message/publish",
data: {
from: from,
to: to,
message: say
},
success: function (result) {
if (result) {
//2. 构造节点
var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";
//3. 把节点添加到页面上
$(".container").append(divE);
//4. 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
} else {
alert("发表留言失败!");
}
}
});
}
-
contentType: "application/json":必须和JSON.stringify()配合用 ------ 因为后端要接收 JSON 格式的请求体,所以前端要把 JS 对象({from:..., to:...})转成 JSON 字符串(JSON.stringify()的作用),同时告诉后端 "我发的是 JSON"。 -
data的格式 :如果contentType是application/json,data必须是JSON 字符串 (所以用JSON.stringify()转换);如果是默认的application/x-www-form-urlencoded,data可以直接传 JS 对象(不用转字符串)。
1.5运行测试
此时在浏览器通过 URL http://127.0.0.1:8080/messagewall.html 访问服务器,即可看到

此时我们每次提交的数据都会发送给服务器,每次打开页面的时候页面都会从服务器加载数据。因此及时关闭页面,数据也不会丢失.
但是数据此时是存储在服务器的内存中(private List<Message> messages = new ArrayList<Message>();), 一旦服务器重启,数据仍然会丢失.
要想数据不丢失,需要把数据存储在数据库中,后面再讲
刷新后数据就丢失了,我们保存的到List里面,没有重启服务器,就不会丢,但是页面不显示,是因为我们前端没有获取后端的数据
前端页面获得后端的数据
javascript
// 页面加载时获取留言列表
getMessage();
// 获取留言列表的方法
function getMessage() {
$.ajax({
url: "message/getList",
type: "get",
success: function (messageInfos) {
// 先清空列表,避免重复渲染
$("#messageList").empty();
// 遍历留言列表
for (let messageInfo of messageInfos) {
let divE = `<div>${messageInfo.from}对${messageInfo.to}说:${messageInfo.content}</div>`;
$("#messageList").append(divE);
}
}
});
}
$("#messageList").empty(); 的唯一作用是:清空选中元素(这里是 id 为 messageList 的 div)内部的所有子元素和内容,不留任何痕迹。

是Java的for- each循环
