Spring MVC (三) —— 实战演练

项目设计

我们会将前端的代码放入 static 包下:

高内聚,低耦合

这是我们在实现项目的设计思想,一个项目里存在很多个模块,每一个模块内部的要求类与类、方法与方法要相互配合紧密联系,这就是高内聚,低耦合追求的是不同模块之间的联系不能太高,即使一个模块崩溃了,也不会影响其他模块的正常运行。

Lombok

通过在 MAVEN 中添加 Lombok 依赖,我们可以使用 Lombok 的注解实现对类自动添加 Getter、Setter、toString、equals、hasCode等可以自动由 IDEA 创建的方法,使用注解,提高了代码的美观度,也提高了开发效率。

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

举个例子:

这是你代码要添加的方法:

java 复制代码
public class UserInfo {
    String name;
    int gender;
    int age;

    public UserInfo() {
    }

    public UserInfo(String name, int gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "name='" + name + '\'' +
                ", gender=" + gender +
                ", age=" + age +
                '}';
    }
}

通过使用 Lombok 注解:就可以实现和上面一样的效果

java 复制代码
import lombok.Data;

@Data
public class UserInfo {
    String name;
    int gender;
    int age;
}

我们来看一下注解的源码:

@Data 是类注解



Getter 和 Setter 可以添加到类上方,这样就是该类下所有的属性都添加 Getter 和 Setter 方法。

也可以单独添加到某些属性上,这样就只对这些指定的属性添加 Getter 和 Setter 方法。

Lombok 的所有的注解都是作用在 源码阶段,一旦经过了编译生成了 .class 文件之后,就会将注解删掉,取而代之的是对应的方法。

EditStarters 插件

EditStarters 插件可以导入 Spring 项目需要的依赖。

安装方式:首先 点击 File ,点击 Setting ,然后安装下图的点击,搜索 EditStarters ,然后点击 Installed 下载安装即可。

添加对应的依赖也很简单:

找到 pom 文件,在文件内容下,右键然后点击 Generate

三层架构

下图是 MVC 架构:

view 是视图,现在视图不交给后端做,一般是前端处理,Controller 就是后端提供的接口,Model 就是业务处理和数据查询


除此之外,在Java 后端中,我们还有一种新的分层架构:分别是 表现层、业务逻辑层、数据层

  1. 表现层: 就是展示数据结果和接受用户指令的,是最靠近用户的⼀层;
  2. 业务逻辑层: 负责处理业务逻辑 , 里面有复杂业务的具体实现;
  3. 数据层: 负责存储和管理与应用程序相关的数据

根据这新三层架构,我们一般会创建三个包与之对应,分别是 controller(类名以 Controller 为结尾,主要是提供给前端的接口)、service (类名以 Service 结尾,存放的是业务逻辑的代码)、dao (类名 以 Dao 为结尾,主要存放查询数据的代码),最后我们会再创建一个包【model、pojo、entity】来存放其他类(例如图书馆里系统有个图书类,包含图书的属性...)

Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。

Service:业务逻辑层。处理具体的业务逻辑。

Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

MVC 与 新三层架构对应如下图所示:

加法计算器

前端代码:

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>

后端代码:

java 复制代码
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/calc")
@RestController
public class CalcController {
    @RequestMapping("/sum")
    public String sum(Integer num1, Integer num2) {
        if(num1 == null || num2 == null) {
            return "<h1>参数输入有误,请重新检查后再输入</h1>";
        }
        int sum = num1 + num2;
        return "<h1>计算结果为 " + sum + "</h1>";
    }
}

用户登录

前端代码:这里使用 JQuery 封装的 ajax 来写前端接口

index.html:

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="js/jquery.min.js"></script>
    <script>

        $.ajax({
            type: "get",
            url: "/user/getLoginUser",
           success: function (userName) {
               $("#loginUser").text(userName);
           }
        });

    </script>
</body>

</html>

login.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="js/jquery.min.js"></script>
  <script>
    function login() {
       $.ajax({
         type: "post",
         url: "/user/login",
         data: {
           userName: $("#userName").val(),
           password: $("#password").val()
         },
         success: function (result) {
            if(result) {
              location.href = "index.html";
            } else {
              alert("账号或者密码错误,请重新输入");
            }
         }
       });
    }

  </script>
</body>

</html>

后端代码:

java 复制代码
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/user")
@RestController
public class UserController {

    @RequestMapping("/login")
    public boolean login(String userName, String password, HttpSession session) {
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return false;
        }
        if("admin".equals(userName) && "admin".equals(password)) {
            session.setAttribute("name","admin");
            return true;
        }
        return false;
    }

    @RequestMapping("/getLoginUser")
    public String getLoginUserName(HttpSession session) {
        return (String) session.getAttribute("name");
    }
}

留言墙

前端代码:

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="js/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 = "";
                    for (var m of messages) {
                        finalHtml += "<div>" + m.from + "对" + m.to + "说:" + m.message + "</div>";
                    }
                    $(".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),
            success: function (result) {

                var jsonObj = JSON.parse(result);

                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>

后端代码:

java 复制代码
import org.example.springbootdemo.test2.model.MessageInfo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
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> messageInfoList = new ArrayList<>();

    @RequestMapping(value = "/publish",produces = "text/json")
    public String publish(@RequestBody MessageInfo messageInfo) {
        if(!StringUtils.hasLength(messageInfo.getFrom()) || !StringUtils.hasLength(messageInfo.getTo()) ||
            !StringUtils.hasLength(messageInfo.getMessage())) {
            return "{\"err\": 0}";
        }
        messageInfoList.add(messageInfo);
        return "{\"ok\": 1}";
    }

    @RequestMapping("/getList")
    public List<MessageInfo> getList() {
        return messageInfoList;
    }
}
java 复制代码
import lombok.Data;

@Data
public class MessageInfo {
    private String from;
    private String to;
    String message;
}
相关推荐
安之若素^4 分钟前
启用不安全的HTTP方法
java·开发语言
魔芋红茶10 分钟前
spring-initializer
python·学习·spring
ruanjiananquan9911 分钟前
c,c++语言的栈内存、堆内存及任意读写内存
java·c语言·c++
chuanauc38 分钟前
Kubernets K8s 学习
java·学习·kubernetes
一头生产的驴1 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao1 小时前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc7871 小时前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张33 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx6 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁