Spring MVC (三) —— 实战演练
项目设计
我们会将前端的代码放入 static 包下:
高内聚,低耦合
这是我们在实现项目的设计思想,一个项目里存在很多个模块,每一个模块内部的要求类与类、方法与方法要相互配合紧密联系,这就是高内聚,低耦合追求的是不同模块之间的联系不能太高,即使一个模块崩溃了,也不会影响其他模块的正常运行。
Lombok
通过在 MAVEN 中添加 Lombok 依赖,我们可以使用 Lombok 的注解实现对类自动添加 Getter、Setter、toString、equals、hasCode等可以自动由 IDEA 创建的方法,使用注解,提高了代码的美观度,也提高了开发效率。
@Data = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor
举个例子:
这是你代码要添加的方法:
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 注解:就可以实现和上面一样的效果
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 后端中,我们还有一种新的分层架构:分别是 表现层、业务逻辑层、数据层
- 表现层: 就是展示数据结果和接受用户指令的,是最靠近用户的⼀层;
- 业务逻辑层: 负责处理业务逻辑 , 里面有复杂业务的具体实现;
- 数据层: 负责存储和管理与应用程序相关的数据
根据这新三层架构,我们一般会创建三个包与之对应,分别是 controller(类名以 Controller 为结尾,主要是提供给前端的接口)、service (类名以 Service 结尾,存放的是业务逻辑的代码)、dao (类名 以 Dao 为结尾,主要存放查询数据的代码),最后我们会再创建一个包【model、pojo、entity】来存放其他类(例如图书馆里系统有个图书类,包含图书的属性…)
Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
Service:业务逻辑层。处理具体的业务逻辑。
Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查。
MVC 与 新三层架构对应如下图所示:
加法计算器
前端代码:
<!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>
后端代码:
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:
<!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:
<!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>
后端代码:
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");
}
}
留言墙
前端代码:
<!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>
后端代码:
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;
}
}
import lombok.Data;
@Data
public class MessageInfo {
private String from;
private String to;
String message;
}