前言
前面我们学习了 Spring MVC 的基础知识,那么这篇文章我将结合前面所学的 Spring MVC 知识为大家分享计算器、留言墙、图书管理系统的部分功能实现。
1. 计算器
这个计算器案例比较简单,也就是简单的用户输入两个数字,我们后端给返回一个这两个数的和就行了。
1.1 准备前端代码
<!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.3 完成后端代码
Java">package ***.example.springdemo20231207;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/calc")
@RestController
public class Cal***ontroller {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2) {
Integer ret = num1 + num2;
return "两数相加的结果为" + ret;
}
}
1.4 验证程序
2. 留言板
这里的留言板跟我们前面用 servlet 写的表白墙是类似的,只不过我们这里是用 Spring 来实现的。
2.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.***/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>
2.2 测试前端代码
2.3 完成前后端交互代码
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,
"say": say
},
su***ess: 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("留言错误");
}
}
});
2.4 完成后端代码
MessageInfo 类用来管理浏览信息,这里 @Data
注释稍后为大家解释。
package ***.example.springdemo20231207;
import lombok.Data;
@Data
public class MessageInfo {
private String from;
private String to;
private String say;
}
package ***.example.springdemo20231207;
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 MessageWallController {
private List<MessageInfo> messageInfos = new ArrayList<>();
@RequestMapping("/publish")
public boolean publish(MessageInfo messageInfo) {
if (!StringUtils.hasLength(messageInfo.getFrom()) || !StringUtils.hasLength(messageInfo.getTo()) || !StringUtils.hasLength(messageInfo.getSay())) {
return false;
}
messageInfos.add(messageInfo);
return true;
}
}
这样就实现了留言信息的存储,这里为什么不使用数据库来存储呢?这是因为传统的数据库操作比较麻烦,等到后面学习了数据库相关的框架了之后,会为大家介绍。
2.5 案例测试
到这里其实还没有实现全部的功能,我们还差一个功能,就是当我们刚进来这个留言板页面的时候,需要将之前存储的留言信息给加载进来,所以就是刚进来这个页面的时候就需要向我们的服务器发送一个请求来获取信息。
2.6 完善前后端交互
<script src="https://cdn.bootcdn.***/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
$.ajax({
type: "get",
url: "/message/getList",
su***ess: function(messageInfos) {
for (var messageInfo of messageInfos) {
var divE = "<div>"+messageInfo.from +"对" + messageInfo.to + "说:" + messageInfo.say+"</div>";
$(".container").append(divE);
}
}
});
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,
"say": say
},
su***ess: 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("留言错误");
}
}
});
}
</script>
2.7 完善后端代码
@RequestMapping("/getList")
public List<MessageInfo> getList() {
return messageInfos;
}
2.8 完整功能测试
因为更改后端代码之后需要重启我们的项目才会生效,而因为我们的 MessageInfo 信息是存储在 List 也就是内存当中的,所以当我们重启程序之后,List 中的数据就会被释放,所以为了测试新加入的功能,我们需要重新加入测试数据。
提交之后,我们重新进入这个页面。
重新进入这个页面之后,他会自动将之前保存的信息给显示出来。
lombok
前面我们的 @Data
注解的作用其实就相当于给 private 权限的属性设置 get 和 set 方法。
Lombok是一个Java库,它可以帮助开发人员消除Java的冗长,尤其是对于简单的Java对象(POJO)。它通过注释实现这一目的。例如,通过在开发环境中实现Lombok,开发人员可以节省构建诸如hashCode()和equals()这样的方法以及以往用来分类各种a***essor和mutator的大量时间。Lombok常用的注解有:
- @Getter:快速构建Getter方法。
- @Setter:快速构建Setter方法。
- @ToString:快速将当前对象转换成字符串类型,便于log。
- @EqualsAndHashCode:快速进行相等判断。
- @NonNull:判断变量(对象)是否为空。
- @Data:整合了Getter、Setter、ToString、EqualsAndHashCode、RequiredArgsConstructor注解。
那么如何使用 Lombok 呢,首先就需要引入这个工具包的依赖,我们可以在 maven 仓库引入,也可以在创建 Spring Boot 项目的时候勾选上 Lombok 选项即可。
Lombok 工具的更多用法。
注解 | 作用 |
---|---|
@Getter | ⾃动添加 getter ⽅法 |
@Setter | 自动添加 setter 方法 |
@ToString | 自动添加 toString 方法 |
@EqualsAndHashCode | 自动添加 equals 和 hashCode 方法 |
@NoArgsConstructor | 自动添加无参构造方法 |
@AllArgsConstructor | ⾃动添加全属性构造⽅法,顺序按照属性的定义顺序 |
@NonNull | 属性不能为 null |
@RequiredArgsConstructor | ⾃动添加必需属性的构造⽅法,final + @NonNull 的属性为必需 |
简单的方式添加Lombok工具
首先在插件中下载 Edit Starters。
在 pom.xml 文件中右键,点击 generate,选择 Edit Starters。并且添加 Lombok。
3. 图书管理系统
因为我们现在学的 Spring 知识无法实现一个完整的图书管理系统,所以这篇文章只完成部分功能。
3.1 前端代码准备
因为这个案例前端代码比较多,所以大家可以去我的 gitee 上自行查找。https://gitee.***/lmh18696433881/this-is-my-java-ee-learning/***mit/8d55ca2407429bfbb1979f0a8559fd638e05b10a
2.2 前端代码测试
2.3 登录功能前后端交互
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type: "post",
url: "/user/login",
data: {
userName: $("#userName").val(),
password: $("#password").val()
},
su***ess: function (result) {
if (result==true) {
location.href = "book_list.html";
}else {
alert("您输入的用户名或者密码错误");
}
}
});
}
</script>
2.4 后端登录功能实现
package ***.example.springbook.Controller;
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) {
//这是为了判断userName和password不为空且长度大于0
if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
return false;
}
if ("zhangsan".equals(userName) && "123".equals(password)) {
session.setAttribute("userName", userName);
return true;
}
return false;
}
}
2.5 登录功能测试
登录完成之后,就会展示出有哪些图书。
2.6 图书列表前后端交互
getBookList();
function getBookList() {
$.ajax({
type: "get",
url: "/book/getList",
su***ess: function (books) {
var finalHtml = "";
for (var book of books) {
//拼接html
finalHtml +='<tr>';
finalHtml +='<td><input type="checkbox" name="selectBook" value="'+book.id+'" id="selectBook" class="book-select"></td>';
finalHtml +='<td>'+book.id+'</td>';
finalHtml +='<td>'+book.bookName+'</td>';
finalHtml +='<td>'+book.author+'</td>';
finalHtml +='<td>'+book.count+'</td>';
finalHtml +='<td>'+book.price+'</td>';
finalHtml +='<td>'+book.publish+'</td>';
finalHtml +='<td>'+book.state***+'</td>';
finalHtml +='<td>';
finalHtml +='<div class="op">';
finalHtml +='<a href="book_update.html?bookId='+book.id+'">修改</a>';
finalHtml +='<a href="javascript:void(0)" onclick="deleteBook('+book.id+')">删除</a>';
finalHtml +='</div>';
finalHtml +='</td>';
finalHtml +='</tr>';
}
$("tbody").html(finalHtml);
}
});
}
2.7 获取图书列表后端代码
首先需要一个 BookInfo 类来存储书的信息。
package ***.example.springdemo20231207;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class BookInfo {
private Integer id;
private String bookName;
private String author;
private Integer count;
private BigDecimal price;
private String publish;
private Integer state; //1可借阅 2不可借阅
private String state***;
}
创造一些假的图书数据BookDao。
package ***.example.springdemo20231207;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BookDao {
public List<BookInfo> mockBookData() {
List<BookInfo> bookInfos = new ArrayList<>();
for (int i = 0; i < 15; i++) {
BookInfo bookInfo = new BookInfo();
bookInfo.setId(i);
bookInfo.setBookName("图书"+i);
bookInfo.setAuthor("作者"+i);
bookInfo.setCount(i*15 + 3);
bookInfo.setPrice(new BigDecimal(new Random().nextInt(100)));
bookInfo.setPublish("出版社"+i);
bookInfo.setState(i%5==0?2:1);
bookInfos.add(bookInfo);
}
return bookInfos;
}
}
图书列表操作的业务逻辑 BookService。
package ***.example.springdemo20231207;
import java.util.List;
public class BookService {
public List<BookInfo> getBookInfoList() {
BookDao bookDao = new BookDao();
List<BookInfo> bookInfos = bookDao.mockBookData();
for (BookInfo bookInfo : bookInfos) {
if (bookInfo.getState() == 1) {
bookInfo.setState***("可借阅");
}else {
bookInfo.setState***("不可借阅");
}
}
return bookInfos;
}
}
图书类的控制器。
package ***.example.springdemo20231207;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/book")
@RestController
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList() {
BookService bookService = new BookService();
return bookService.getBookInfoList();
}
}