CoderYanger头像
Java EE 进阶:4.Spring Web MVC 入门(第五弹)封面图

Java EE 进阶:4.Spring Web MVC 入门(第五弹)

目录

3.3 留言板

3.3.1 准备工作

3.3.2 约定前后端交互接口

需求分析

接口定义

1.获取全部留言

2.发表新留言

3.3.3 实现服务器端代码

3.3.3.1 lombok 介绍(重点)

1.引入依赖

2.使用

3.原理解释

4.更多使用

3.3.3.2 更快捷的引入依赖

1.安装插件 EditStarter,重启 IDEA​编辑​编辑

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

3.3.3.3 服务器代码实现

3.3.4 调整前端页面代码

1.在点击按钮的时候给服务器发送添加留言请求

2.添加 load 函数,用于在页面加载的时候获取数据

3.3.5 运行测试


书接上文:Java EE 进阶:4.Spring Web MVC 入门(第四弹)~~

3.3 留言板

在学习前端的时候,我们就写过这里的代码,只不过是纯页面的👇,没有前后端交互,刷新一下页面留言的内容就没了

Java EE 进阶:2.3 JavaScript 综合案例

现在我们已经学习后端了,接下来我们来完成前后端交互,存储一下留言的内容~~

需求:界面如下图所示

1.输入留言信息,点击提交,后端把数据存储起来

2.页面展示输入的表白墙的信息

3.3.1 准备工作

把前端页面放在项目中(课件中提供)

码云地址:JavaEE 进阶课程资料包

3.3.2 约定前后端交互接口

需求分析

后端需要提供两个服务

1.发表留言接口:让前端把这些数据传过来,我们把它存储下来

2.留言列表接口:刷新或者点击提交的时候,下面要显示一个列表

接口定义
1.获取全部留言

全部留言信息,我们用 List 来表示,可以用 JSON 来描述这个 List 数据

请求:

GET /message/getList

响应:JSON 格式

[
  {
    "from": "黑猫",
    "to": "白猫",
    "message": "喵"
  },
  {
    "from": "黑狗",
    "to": "白狗",
    "message": "汪"
  },
  //...
]

浏览器给服务器发送一个 GET / message / getList 这样的请求,就能返回当前一共有哪些留言记录.结果以 json 的格式返回过来

2.发表新留言

请求:body 也为 JSON 格式

POST /message/publish
{
    "from": "黑猫",
    "to": "白猫",
    "message": "喵"
}

响应:JSON 格式

{
 ok: 1
}

我们期望浏览器给服务器发送一个 POST / message / publish 这样的请求,就能把当前的留言提交给服务器

3.3.3 实现服务器端代码

3.3.3.1 lombok 介绍(重点)

我们去写一个对象的时候,要写它的属性、get 方法、set 方法,那对于这种重复性的工作,我们是否可以不做呢?比如这些构造方法我们可不可以不写,通过一些注解完成?咱们 Java 本身就有很多注解帮助我们开发的,虽然现在 get 方法、set 方法我们现在也不写,直接右键直接生成了,但是我现在连生成就懒得生成了,虽然并不用写,但是看着这么多代码也嫌烦👇接下来我们就来学一个新的东西,这些东西就可以不写了~~

Lombok 是一个 Java 工具库,通过添加注解的方式,简化 Java 的开发

简单来学习下它的使用

1.引入依赖

lombok 是一个第三方的工具包,并不是 Spring 的,所以要先引入依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

直接复制到 xml 文件里👇点击刷新后会自动为我们导入依赖👇

当然,如果你不知道这个依赖是什么,咱就可以去 Maven 中央仓库去查询👇https://mvnrepository.com/search?q=lombok

第一个就是了,然后随便找一个使用次数多的版本(有漏洞的不要选,尽量选次新的),点进去复制 依赖 即可👇

粘贴到我们的 xml 文件里,顺序不分先后👇

2.使用

lombok 通过一些注解的方式,可以帮助我们消除一些冗长代码,使代码看起来简洁一些

比如之前的 Person 对象,就可以改为

package com.bite.spring.demo;

import lombok.Data;

@Data
public class MessageInfo {
    private  String from;//谁写的
    private  String to;//写给谁的
    private  String message;//内容是啥

}

@Data 注解会帮助我们自动一些方法,包含 getter / setter,equals,toString 等

此时我们测试一下,发现自动就出来了 get、set 的方法👇

    public void testLombok(){
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.
    }

但如果此时将 @Data 注解给注释掉之后就会发现报错了👇

3.原理解释

可以观察加了 @Data 注解之后,IDEA 反编译的 class 文件,运行程序后,看 @Data 帮助我们生成了哪些方法👇

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.bite.spring.demo;

public class MessageInfo {
    private String from;
    private String to;
    private String message;

    public MessageInfo() {
    }

    public String getFrom() {
        return this.from;
    }

    public String getTo() {
        return this.to;
    }

    public String getMessage() {
        return this.message;
    }

    public void setFrom(final String from) {
        this.from = from;
    }

    public void setTo(final String to) {
        this.to = to;
    }

    public void setMessage(final String message) {
        this.message = message;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof MessageInfo)) {
            return false;
        } else {
            MessageInfo other = (MessageInfo)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$from = this.getFrom();
                Object other$from = other.getFrom();
                if (this$from == null) {
                    if (other$from != null) {
                        return false;
                    }
                } else if (!this$from.equals(other$from)) {
                    return false;
                }

                Object this$to = this.getTo();
                Object other$to = other.getTo();
                if (this$to == null) {
                    if (other$to != null) {
                        return false;
                    }
                } else if (!this$to.equals(other$to)) {
                    return false;
                }

                Object this$message = this.getMessage();
                Object other$message = other.getMessage();
                if (this$message == null) {
                    if (other$message != null) {
                        return false;
                    }
                } else if (!this$message.equals(other$message)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof MessageInfo;
    }

    public int hashCode() {
        int PRIME = 59;
        int result = 1;
        Object $from = this.getFrom();
        result = result * 59 + ($from == null ? 43 : $from.hashCode());
        Object $to = this.getTo();
        result = result * 59 + ($to == null ? 43 : $to.hashCode());
        Object $message = this.getMessage();
        result = result * 59 + ($message == null ? 43 : $message.hashCode());
        return result;
    }

    public String toString() {
        String var10000 = this.getFrom();
        return "MessageInfo(from=" + var10000 + ", to=" + this.getTo() + ", message=" + this.getMessage() + ")";
    }
}

我们发现 @Data 变成了构造函数、get 和 set 方法、equals 方法、hasCode 方法、toString 方法~~

我们点进去 @Data 这个注解,会发现这个注解的生命周期是只存活在源码阶段,在 class 阶段已经变成了以上内容

那么我们以后就不用写 get 方法、set 方法了~~

闲聊:

这不是真正的字节码文件,而是 IDEA 根据字节码进行反编译后的文件

反编译是将可执行的程序代码转换为某种形式的高级编程语言,使其具有更易读的格式,反编译是一种逆向工程,它的作用与编译器的作用相反

可以看出来,lombok 是一款在编译期生成代码的工具包

Java 程序的运行原理:

Lombok 的作用如下图所示:

4.更多使用

有的时候我们并不希望它帮我生成 toString() 方法,这时候就需要其他注解了

如果觉得@Data比较粗暴(生成方法太多), lombok也提供了一些更精细粒度的注解

注解

作用

@Getter

自动添加 getter 方法

@Setter

自动添加 setter 方法

@ToString

自动添加 toString 方法

@EqualsAndHashCode

自动添加 equals 和 hashCode 方法

@NoArgsConstructor

自动添加无参构造方法

@AllArgsConstructor

自动添加全属性构造方法,顺序按照属性的定义顺序

@NonNull

属性不能为 null

@RequiredArgsConstructor

自动添加必需属性的构造方法,final + @NonNull 的属性为必需

@Data = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
+ @NoArgsConstructor

如果说咱们只想要 get 方法 和 set 方法,就可以这样写👇

package com.bite.spring.demo;

//import lombok.Data;
import lombok.Getter;
import lombok.Setter;

//@Data
@Getter
@Setter
public class MessageInfo {
    private  String from;//谁写的
    private  String to;//写给谁的
    private  String message;//内容是啥

}

此时就只剩下 get 和 set 方法了👇

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.bite.spring.demo;

public class MessageInfo {
    private String from;
    private String to;
    private String message;

    public MessageInfo() {
    }

    public String getFrom() {
        return this.from;
    }

    public String getTo() {
        return this.to;
    }

    public String getMessage() {
        return this.message;
    }

    public void setFrom(final String from) {
        this.from = from;
    }

    public void setTo(final String to) {
        this.to = to;
    }

    public void setMessage(final String message) {
        this.message = message;
    }
}

那如果说我不想全生成,我只想生成 from 的 get 和 set 方法,那就可以这么写👇

package com.bite.spring.demo;

//import lombok.Data;
import lombok.Getter;
import lombok.Setter;

//@Data
//@Getter
//@Setter
public class MessageInfo {
    @Getter @Setter
    private  String from;//谁写的
    private  String to;//写给谁的
    private  String message;//内容是啥

}

此时就会只生成 from 的 get 和 set 方法👇

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.bite.spring.demo;

public class MessageInfo {
    private String from;
    private String to;
    private String message;

    public MessageInfo() {
    }

    public String getFrom() {
        return this.from;
    }

    public void setFrom(final String from) {
        this.from = from;
    }
}
3.3.3.2 更快捷的引入依赖

上述引入lombok 依赖是比较通用的方式, 需要去 Maven 找 lombok 的依赖 
接下来介绍更简单引入依赖的方式(注意,这种便捷式的添加依赖并不一定能找到所有依赖,但是上面那种通用方式是可以找到所有依赖的~~)

1.安装插件 EditStarter,重启 IDEA

单击右键,看到这个就说明安装好了👇

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

默认选 GitHub 就可以~~

进入Edit Starters的编辑界面, 添加对应依赖即可

点击 OK 之后就自动帮我们生成好了👇

这个好像跟刚才的不太一样,没带版本号,没有关系,因为我们不指定版本的话,SpringBoot 也已经帮我们指定了版本,把鼠标放在 lombok 上就能看到👇

在哪里进行管理的呢?在上面的 spring-boot-starter-parent 这里👇

点进去后,再点这个👇

再点进去,发现里面是有 Lombok 版本的👇

也就是说,我们没有指定版本,它就默认使用这个版本,如果我们指定了版本,它就按照我们的指定的版本

注意:
不是所有依赖都可以在这里添加的, 这个界面和SpringBoot创建项目界面一样.
依赖不在这里的, 还需要去Maven仓库查找坐标, 添加依赖.

3.3.3.3 服务器代码实现

 定义留言对象 MessageInfo 类

import lombok.Data;

@Data
public class MessageInfo {
    private String from;
    private String to;
    private String message;
}

创建 MessageController 类
使用List<MessageInfo> 来存储留言板信息

package com.bite.spring.demo;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: CoderYanger
 * Date: 2026-10-24
 * Time: 16:13
 */
@RequestMapping("/message")
@RestController
public class MessageController {
    private List<MessageInfo> messageInfoList=new ArrayList<>();
    
    @PostMapping(value = "/publish",produces = "application/json")
    public String publish(@RequestBody MessageInfo messageInfo){
        //@RequestBody是从请求正文中拿数据,而JSON的请求数据就在请求正文中
        //@ResponseBody是响应正文的数据
        //先判断是否为空
        if(!StringUtils.hasLength(messageInfo.getFrom())
                ||!StringUtils.hasLength(messageInfo.getTo())
                ||!StringUtils.hasLength(messageInfo.getMessage())){
            return "{\"ok\":0}";//上面加上produces = "application/json"以转成JSON
        }
        //把传的请求放进来
        messageInfoList.add(messageInfo);
        return "{\"ok\":1}";
    }
    
    @GetMapping("/getList")
    public List<MessageInfo> getList(){
        return messageInfoList;
    }
}

使用 Postman 自测一下,发现都没问题👇

在一开始的时候确实是空的,没问题

这时候我们再 get 一下,发现就能获取到了👇

答疑:不加 @RequestBody 会怎么样??

@RequestBody 表示请求参数为 JSON,我们把 @RequestBody 去掉后重新启动程序👇

咱们再来去发布一个 publish 👇

此时报了一个 0,在代码中走到这里了👇

        if(!StringUtils.hasLength(messageInfo.getFrom())
                ||!StringUtils.hasLength(messageInfo.getTo())
                ||!StringUtils.hasLength(messageInfo.getMessage())){
            return "{\"ok\":0}";//上面加上produces = "application/json"以转成JSON
        }

也就是说我们的 messageInfo 这个值它拿到的是一个空的对象

下面我们打断点 Debug 调试一下,Debug 方式跟之前也是一样的👇打好断点之后点击上方的小虫子调试

等断点上的红点点出现 √ 时说明已经走到断点处了,此时我们再发送请求 Postman 就会一直加载👇

我们发现它确实没有拿到这个值,全都是 null👇

所以 @RequestBody 肯定是要加的~~

下面给大家说一下原理是什么

请求方式①:在 Body 里面发 JSON

此时我们抓包时,数据也是在 Body 这里,也是 JSON

请求方式②:普通对象就在 Params 里

我们发现 请求的参数全放在上面了👇

请求方式③:Body 的 x-www-form-urlencoded 部分

我们发现它的请求参数只是从上面挪到下面来了,但是它的结构方式时不一样的

第一种方式是 JSON 的方式,下面这两种方式是用 & 和 = 把参数连接起来的方式

所以我们的前端和后端是要对应上的,我们既然定义的是 JSON,那么我们刚才测试的时候也是使用这个来发起请求

3.3.4 调整前端页面代码

后端既然提供两个接口,那么前端也是要发两个请求的~~

闲聊:前端知识复习~~

JS 声明变量

var:早期声明变量的方式

let:最近流行的声明变量的方式

const:声明常量的方式

{} 表示对象,里面的属性都是 key-value 的形式

修改 messagewall.html

1.在点击按钮的时候给服务器发送添加留言请求
<!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>A 对 B 说: 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;
            }
            var data={
                from:from,
                to:to,
                message:say
            };

            $.ajax({
                type:"post",
                url:"/message/publish",
                contentType:"application/json",
                data:JSON.stringify(data),//把对象转成JSON
                success:function (result){
                    //如果后端发送的值是JSON,那么前端是可以直接当作对象来用的
                    if(result.ok==1){
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);//追加在后面

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败");
                    }
                }
            });
        }
        
    </script>
</body>

</html>

上述代码中涉及新的知识👇

并且存在着对应关系👇

服务运行后,我们来抓包测试一下👇

此时的抓包结果👇

我们通过 浏览器 抓包也是一样的👇

答疑:

Q1:如果把前端的 contentType:"application/json"去掉怎么样??👇

我们会发现 Fiddler 和 浏览器 说的都一样:这种类型不支持,就是这种类型是不对的👇

此时 Content-Type 类型为:application/x-www-form-urlencoded,类型对不上~~

Q2:那如果把后端的 produces="application/json" 去掉会怎么样??👇

我们当时为了改成 JSON,通过这种方式手动给改了,那如果不改,那么返回来的就是一个字符串,咱们再来测试👇

我们发现 Content-Type 是文本类型👇

那么文本类型为什么留言失败了??我们来分析一下👇

            success:function (result){
                    if(result.ok==1){
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);//追加在后面

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败");
                    }
                }
            });

我们发现肯定 result.ok ==1 为 false 了,但事实结果上咱们的状态确实是 result.ok =1,这咋回事儿??对于初学者,咱们最好的方式就是打印日志👇

            success:function (result){
                    //打印日志观察两者类型的差异
                    console.log(result);
                    console.log(result.ok);
                    if(result.ok==1){
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);//追加在后面

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败");
                    }
                }
            });

重新启动服务后再来观察👇

我们发现第一个没问题,但是第二个类型却是未定义类型,这是为什么呢??

因为当返回类型为 text/plain 的时候,会认为 {"ok":1} 是个字符串,那么它就是个整体,而 result.ok 的这个 ".",说明是个对象我们才能用 "." 找属性才能拿到值,那么现在是个字符串,不是对象,根本 "." 不出来,所以就会在这个地方发生错误

所以我们前后端,你接口定义的什么,就要按照那个规定去定义,不能说看结果都是 {"ok":1}一样就行了,Content-Type 类型也是要关注的

Q3:我有没有办法可以不改后端,就返回这个字符串,然后让前端运行成功??我们的前端可不可把这个 result 转换成 JSON,也就是能不能转换成对象??

我们上面学了把 对象 转成 JSON 👇

data:JSON.stringify(data),//把对象转成JSON

当然,把 JSON 转成 对象 也是可以的👇

            success:function (result){
                    // //打印日志观察两者类型的差异
                    // console.log(result);
                    // console.log(result.ok);
                    var jsonObj=JSON.parse(result);//JSON转对象
                    if(jsonObj.ok==1){
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);//追加在后面

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败");
                    }
                }
            });

这时候就正常了👇

所以说我们的前后端是要相互配合的,前端也可以改后端也可以改,那如果测试人员真测出 Bug 了,这是前端改还是后端改呢??看接口文档,如果接口文档说的就是返回类型是 JSON,那么就是后端改,如果说的是返回类型为文本,那么就是前端改了~~

闲聊:要是边界划分不清晰的话,大概率会商量一下,哪边改容易就哪边改,咱们程序员这个圈子还是比较纯洁的~~

Q4:感觉每次都要重启服务好麻烦,有没有不吃操作的方式??

有的,这种方式叫”热部署“,但是这种方式也很麻烦,原理就是不用你重启了,IDEA 帮你重启了,但是也很麻烦,有时候你代码都改完了,它还没重启呢,机制大概就是等5秒,这5秒你没有任何操作,它才会重启,但往往咱等不了5秒~~大家感兴趣直接搜“热部署IDEA”就行了

2.添加 load 函数,用于在页面加载的时候获取数据

写到现在其实看着跟之前没啥区别,也是一刷新就没了,下面我们来学如何将列表存储下来~~

刷新的话其实就是获取留言列表,咱们的列表信息全在 messageInfoList 存着呢👇

所以我们只需要前端去调用 getList 这个接口,然后给它显示到页面上就可以了

我们希望在刷新的时候去显示留言列表,就是加载页面的时候获取留言列表信息,也就是已进入页面的时候就应该发送 Ajax 请求,这种页面一进来就需要加载的内容,我们就直接写在 script 下面👇

        load();//封装
        function load(){
            $.ajax({
                type:"get",
                url:"/message/getList",
                success:function(messages){
                    if(messages!=null&&messages.length>0){
                        var finalHtml="";
                        //类似Java的for(MessageInfo messageInfo:messageInfoList)
                        for(var m of messages){
                            //给每一个元素都拼接上这样一行HTML代码
                            var item="<div>"+m.from+"对"+m.to+"说:"+m.message+"</div>";
                            //拼成一个大的HTML代码放在下面,字符串代码直接加就行
                            finalHtml+=item;
                        }
                        //放进去
                        $(".container").append(finalHtml);
                    }
                }
            });
        }

完整代码👇

<!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>A 对 B 说: hello</div> -->
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        load();//封装
        function load(){
            $.ajax({
                type:"get",
                url:"/message/getList",
                success:function(messages){
                    if(messages!=null&&messages.length>0){
                        var finalHtml="";
                        //类似Java的for(MessageInfo messageInfo:messageInfoList)
                        for(var m of messages){
                            //给每一个元素都拼接上这样一行HTML代码
                            var item="<div>"+m.from+"对"+m.to+"说:"+m.message+"</div>";
                            //拼成一个大的HTML代码放在下面,字符串代码直接加就行
                            finalHtml+=item;
                        }
                        //放进去
                        $(".container").append(finalHtml);
                    }
                }
            });
        }
        function submit(){
            //1. 获取留言的内容
            var from = $('#from').val();
            var to = $('#to').val();
            var say = $('#say').val();
            if (from== '' || to == '' || say == '') {
                return;
            }
            var data={
                from:from,
                to:to,
                message:say
            };

            $.ajax({
                type:"post",
                url:"/message/publish",
                contentType:"application/json",
                data:JSON.stringify(data),//把对象转成JSON
                success:function (result){
                    //如果后端发送的值是JSON,那么前端是可以直接当作对象来用的
                    // //打印日志观察两者类型的差异
                    // console.log(result);
                    // console.log(result.ok);
                    var jsonObj=JSON.parse(result);//JSON转对象
                    if(jsonObj.ok==1){
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);//追加在后面

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败");
                    }
                }
            });
        }
        
    </script>
</body>

</html>

3.3.5 运行测试

此时在浏览器通过 URL http://127.0.0.1:8080/messagewall.html 访问服务器, 即可看到

留言板前后端交互演示

此时我们每次提交的数据都会发送给服务器. 每次打开页面的时候页面都会从服务器加载数据. 因此即使关闭页面, 数据也不会丢失.
但是数据此时是存储在服务器的内存中 ( private List<Message> messages = new
ArrayList<Message>(); ), 一旦服务器重启, 数据仍然会丢失.
要想数据不丢失, 需要把数据存储在数据库中, 后面再讲~~

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/Miraitowa_6/article/details/168342633

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--