JavaEE 进阶第十一期:Spring MVC - Web开发的“交通枢纽”(五)

专栏:JavaEE 进阶跃迁营

个人主页:手握风云

目录

一、加法计算器

[1.1. 准备工作](#1.1. 准备工作)

[1.2. 约定前后端交互接口](#1.2. 约定前后端交互接口)

[1. 概念介绍](#1. 概念介绍)

[2. 需求分析](#2. 需求分析)

[3. 接口分析](#3. 接口分析)

[1.3. 服务器代码](#1.3. 服务器代码)

二、用户登录

[2.1. 准备工作](#2.1. 准备工作)

[2.2. 约定前后端交互接口](#2.2. 约定前后端交互接口)

[1. 校验接口](#1. 校验接口)

[2. 查询登录用户接口](#2. 查询登录用户接口)

[2.3. 服务器代码](#2.3. 服务器代码)

三、留言板

[3.1. 准备工作](#3.1. 准备工作)

[3.2. 约定前后端交互接口](#3.2. 约定前后端交互接口)

[1. 需求分析](#1. 需求分析)

[2. 接口定义](#2. 接口定义)

[3.3. Lombok 介绍](#3.3. Lombok 介绍)

[3.4. 服务器后端代码](#3.4. 服务器后端代码)


一、加法计算器

1.1. 准备工作

创建SpringBoot项目:引入Spring Web依赖,把前端页面放在项目中。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <form action="calc/sum" method="post">
        <h1>计算器</h1>
        数字1:<input name="num1" type="text"><br>
        数字2:<input name="num2" type="text"><br>
        <input type="submit" value=" 点击相加 ">
    </form>
</body>

</html>

1.2. 约定前后端交互接口

1. 概念介绍

"约定前后端交互接口" 是 Web 开发(尤其是前后端分离模式下)的关键环节,这里的 "接口"(又称 API,即 Application Programming Interface)并非 JavaSE 阶段所学的 "类与接口",而是应用程序对外提供服务的描述,本质是前后端之间遵循的 "应用层协议",用于规范客户端(前端)与服务器(后端)之间的信息交换和任务执行规则。简单来说,它明确了客户端可以给服务器发送哪些 HTTP 请求,以及每种请求预期能获取到什么样的 HTTP 响应 ------ 比如客户端发起请求时应使用的路径、请求方式(GET/POST 等)、携带的参数(参数名、类型、是否必传),以及服务器返回响应时的数据格式(如 text/html、application/json)、内容结构等。

在前后端分离的开发模式中,前端与后端代码通常由不同团队负责,为避免开发过程中的混乱和对接矛盾,双方会在开发前提前约定交互接口:一般由服务提供方(后端)编写接口文档,明确上述交互细节,交由服务使用方(前端)确认。接口文档类似应用程序的 "操作说明书"。

接口文档一旦确定,需尽量保持稳定,避免随意变更;若因业务需求必须调整,需及时通知对方团队,确保前后端开发节奏一致。这种约定的核心价值在于降低前后端团队的沟通成本,明确各自开发边界,让双方可基于统一标准并行开发,最终保证前后端对接时能顺畅协作,减少因交互规则不明确导致的返工问题。

2. 需求分析

加法计算器功能,对两个整数进行相加,需要客户端提供参与计算的两个数,服务端返回这两个整数计算的结果。

3. 接口分析

html 复制代码
请求路径:calc/sum

请求方式:GET/POST

接口描述:计算两个整数相加

请求参数:

|------|---------|------|-----------|
| 参数名 | 类型 | 是否必须 | 备注 |
| num1 | Integer | 是 | 参与计算的第一个数 |
| num2 | Integer | 是 | 参与计算的第二个数 |

1.3. 服务器代码

java 复制代码
package com.yang.test1_19_5;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/calc")
@RestController
public class CalController {
    @RequestMapping("/sum")
    public String sum(Integer num1, Integer num2) {
        if (num1 == null || num2 == null) {
            return "输入的数据不合法";
        }

        Integer sum = num1 + num2;
        return "计算结果:" + sum;
    }
}

二、用户登录

2.1. 准备工作

创建SpringBoot项目:引入Spring Web依赖,把前端页面放在项目中。

html 复制代码
<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>用户登录首页</title>
</head>

<body>
    登录人: <span id="loginUser"></span>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>

    </script>
</body>

</html>
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>登录页面</title>
</head>

<body>
  <h1>用户登录</h1>
  用户名:<input name="userName" type="text" id="userName"><br>
  密码:<input name="password" type="password" id="password"><br>
  <input type="button" value="登录" onclick="login()">
  
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  <script>
    function login() {
    
    }

  </script>
</body>

</html>

2.2. 约定前后端交互接口

用户登录接口:验证用户名和密码是否正确,并返回给前端。首页:告知前端当前登录用户.如果当前已有用户登录,返回登录的账号,如果没有,返回空。

1. 校验接口

复制代码
请求路径:/user/login

请求方式:POST

接口描述:校验账号密码是否正确

|----------|--------|------|-------|
| 参数名 | 类型 | 是否必须 | 备注 |
| userName | String | 是 | 校验的账号 |
| passWord | String | 是 | 校验的密码 |

复制代码
Content-Type: text/html

响应内容:

true //账号密码验证成功
false //账号密码验证失败

2. 查询登录用户接口

复制代码
请求路径: /user/getLoginUser

请求方式: GET

接口描述: 查询当前登录的用户

Content-Type: text/html

响应内容:
zhangsan

2.3. 服务器代码

java 复制代码
package com.yang.test1_20_1;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/user")
@RestController
public class UserController {
    /**
     * 校验用户名和密码是否正确
     * @param userName 用户名
     * @param password 密码
     * @return 正确为 true,错误为 false
     */
    @PostMapping("/login")
    public Boolean login(String userName, String password, HttpSession session) {
        if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return false;
        }

        // 在开发规范中,代码嵌套最好不要超过5层
        // 使用 equals 方法时,常量尽量写前面
        if ("Bruce".equals(userName) && "12345".equals(password)) {
            // 存储 Session
            session.setAttribute("loginUser", userName);
            return true;
        }

        return false;
    }

    @GetMapping("/getLoginUser")
    public String getLoginUser(HttpServletRequest request) {
        // 参数为 false,获取的 session 为 null 时,不会创建 session
        HttpSession session = request.getSession();

        if (session != null) {
            String loginUser = (String) session.getAttribute("loginUser");
            return loginUser;
        }

        return "";
    }
}

三、留言板

3.1. 准备工作

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>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;
            }
            //2. 构造节点
            var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
            //3. 把节点添加到页面上    
            $(".container").append(divE);

            //4. 清空输入框的值
            $('#from').val("");
            $('#to').val("");
            $('#say').val("");
            
        }
        
    </script>
</body>

</html>

3.2. 约定前后端交互接口

1. 需求分析

后端需要提供两个服务:用户输入留言信息之后,后端需要把留言信息保存起来;页面展示时,需要从后端获取到所有的留言信息。

2. 接口定义

获取全部留言信息,可以用 List 表示,可以用 JSON 来描述这个 List 信息。

html 复制代码
GET /message/getList
html 复制代码
[
    {
        "from":"黑猫",
        "to":"白猫",
        "message":"喵"
    }
]

当发表新留言时,响应格式也是 JSON 数据。

html 复制代码
POST message/publish
html 复制代码
{
    "from":"黑猫"
    "to":"白猫"
    "message":"喵"
}
html 复制代码
{
    "OK":1
}

3.3. Lombok 介绍

当我们在进行面向对象编程的时候,IDEA 可以帮我们生成带参数的构造方法、Get/Set 方法等。但是如果我们想要添加其他参数时,修改这些方法就会很不方便。而 Lombok 通过注解在编译时自动生成 Getters、Setters、构造函数、toString 等代码。

Lombok 的工作原理是,当编译器(javac)开始把你的 .java 源码翻译成 .class 字节码时,它会先把代码解析成一种树状结构。Lombok 利用 Java 提供的注解处理器机制,在这个翻译过程中"插队"。它扫描到你写的 @Getter 或 @Data 等注解后,就会直接修改这棵树,把原本不存在的 get、set 方法强行"种"进去。

我们要想使用 Lombok 的这些功能,需要现在 pom.xml 里面引入依赖,同时安装插件 Lombok。

XML 复制代码
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.32</version>
    <scope>compile</scope>
</dependency>
注解 作用
@Getter 自动添加 getter 方法
@Setter 自动添加 setter 方法
@ToString 自动添加 toString 方法
@EqualsAndHashCode 自动添加 equals 和 hashCode 方法
@NoArgsConstructor 自动添加无参构造方法
@AllArgsConstructor 自动添加全属性构造方法,顺序按照属性的定义顺序
@NonNull 标记属性不能为 null
@RequiredArgsConstructor 自动添加必需属性的构造方法,final + @NonNull 的属性为必需

3.4. 服务器后端代码

java 复制代码
package com.yang.test1_21_1;

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

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

@RequestMapping("/message")
@RestController
public class MessageController {

    List<MessageInfo> messageInfoList = new ArrayList<>();

    @PostMapping("/publish")
    public Boolean publish(@RequestBody MessageInfo messageInfo) {
        if (!StringUtils.hasLength(messageInfo.getFrom())
            || !StringUtils.hasLength(messageInfo.getTo())
            || !StringUtils.hasLength(messageInfo.getMessage())) {
            return false;
        }

        messageInfoList.add(messageInfo);
        return true;
    }

    @GetMapping("/getList")
    public List<MessageInfo> getList() {
        return messageInfoList;
    }
}
相关推荐
爱上妖精的尾巴3 小时前
7-11 WPS JS宏 对象的属性值为函数的写法与用法
前端·javascript·wps·js宏·jsa
zuozewei3 小时前
零基础 | 使用LangChain框架实现ReAct Agent
前端·react.js·langchain
坠入暮云间x3 小时前
React Native for OpenHarmony开发环境搭建指南(一)
前端·react native·开源
爱上妖精的尾巴3 小时前
7-12 WPS JS宏 this、return用构造函数自定义类-1:对象内部函数,外部调用的写法
前端·javascript·wps·js宏·jsa
努力也学不会java3 小时前
【Spring Cloud】 服务注册/服务发现
人工智能·后端·算法·spring·spring cloud·容器·服务发现
har01d3 小时前
AI生成的 vue3 日历组件,显示农历与节日,日期可选择,年月可切换
前端·vue.js·节日
冲刺逆向3 小时前
【js逆向案例六】创宇盾(加速乐)通杀模版
java·前端·javascript
我穿棉裤了3 小时前
文字换行自动添加换行符“-”
前端·javascript·vue.js
six+seven3 小时前
Node.js内置模块fs
前端·node.js