4、SpringMVC 实战小项目【加法计算器、用户登录、留言板、图书管理系统】

本文主要是介绍4、SpringMVC 实战小项目【加法计算器、用户登录、留言板、图书管理系统】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SpringMVC 实战小项目

    • 3.1 加法计算器
      • 3.1.1 准备⼯作
        • 前端
      • 3.1.2 约定前后端交互接⼝
        • 需求分析
        • 接⼝定义
        • 请求参数:
        • 响应数据:
      • 3.1.3 服务器代码
    • 3.2 ⽤⼾登录
      • 3.2.1 准备⼯作
      • 3.2.2 约定前后端交互接⼝
      • 3.2.3 实现服务器端代码
    • 3.3 留⾔板
      • 实现服务器端代码
    • 3.4 图书管理系统
      • 准备
      • 后端

3.1 加法计算器

需求: 输⼊两个整数, 点击"点击相加"按钮, 显⽰计算结果

在这里插入图片描述

3.1.1 准备⼯作

创建SpringBoot项⽬: 引⼊Spring Web依赖, 把前端⻚⾯放在项⽬中(课件中提供)

前端
<!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>

3.1.2 约定前后端交互接⼝

需求分析

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

接⼝定义

在这里插入图片描述

请求路径:calc/sum
请求⽅式:GET/POST
接⼝描述:计算两个整数相加
请求参数:

在这里插入图片描述

⽰例: num1=5&num2=3

响应数据:
Content-Type: text/html
响应内容: 计算机计算结果: 8

3.1.3 服务器代码

@RestController
@RequestMapping("/calc")
public class CalcController {@RequestMapping("/sum")public String sum(Integer num1,Integer num2){Integer sum = num1+num2;return "<h1>计算机计算结果: "+sum+"</h1>";}
}

3.2 ⽤⼾登录

需求: ⽤⼾输⼊账号和密码, 后端进⾏校验密码是否正确

  1. 如果不正确, 前端进⾏⽤⼾告知
  2. 如果正确, 跳转到⾸⻚. ⾸⻚显⽰当前登录⽤⼾
  3. 后续再访问⾸⻚, 可以获取到登录⽤⼾信息

在这里插入图片描述

3.2.1 准备⼯作

把前端⻚⾯放在项⽬中(课件中提供)
码云地址: 前端代码/⽤⼾登录

<!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() {$.ajax({type: "post",url: "/login/check",data:{userName: $("#userName").val(),password: $("#password").val()},success: function(result){if(result==true){//用户名和密码正确location.href = "index.html";// location.assign("index.html");// location.replace("index.html")}else{alert("用户名或密码错误!");}}});}</script>
</body></html>

3.2.2 约定前后端交互接⼝

需求分析
对于后端开发⼈员⽽⾔, 不涉及前端⻚⾯的展⽰, 只需要提供两个功能

  1. 登录⻚⾯: 通过账号和密码, 校验输⼊的账号密码是否正确, 并告知前端
  2. ⾸⻚: 告知前端当前登录⽤⼾. 如果当前已有⽤⼾登录, 返回登录的账号, 如果没有, 返回空

接⼝定义

  1. 校验接⼝
请求路径:/user/login
请求⽅式:POST
接⼝描述:校验账号密码是否正确

在这里插入图片描述

3.2.3 实现服务器端代码

@RequestMapping("/login")
@RestController
public class LoginController {@RequestMapping("/check")public boolean check(String userName, String password, HttpSession session){System.out.println("接收到参数 userName:"+userName + ",password:"+password);//校验账号和密码是否为空
//        if (userName==null || "".equals(userName) || password==null || "".equals(password)){
//            return false;
//        }if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){return false;}//校验账号和密码是否正确//数据模拟if ("zhangsan".equals(userName) && "123456".equals(password)){session.setAttribute("userName",userName);return true;}return false;}@RequestMapping("/index")public String index(HttpSession session){String userName = (String)session.getAttribute("userName");return userName;}
}

3.3 留⾔板

需求:
界⾯如下图所⽰

  1. 输⼊留⾔信息, 点击提交. 后端把数据存储起来.
  2. ⻚⾯展⽰输⼊的表⽩墙的信息

在这里插入图片描述

<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>//页面加载时, 显示留言信息//从后端获取到留言信息, 并显示在页面上$.ajax({type: "get",url: "/message/getList",success: function(messages){for(var message of messages){var html = "<div>"+message.from+" 对 "+message.to+" 说: "+message.message+"</div>";$(".container").append(html);}}});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,message: say},success: function (result) {if (result == true) {//添加成功//2. 构造节点var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";//3. 把节点添加到页面上$(".container").append(divE);//4. 清空输入框的值$('#from').val("");$('#to').val("");$('#say').val("");}else{alert("发表失败");}}});}</script>
</body></html>

实现服务器端代码

@Data
public class MessageInfo {private Integer id;private String from;private String to;private String message;private Integer deleteFlag;private Date createTime;private Date updateTime;}

@RequestMapping("/message")
@RestController
public class MessageController {@Autowiredprivate MessageService messageService;private List<MessageInfo> messageInfos = new ArrayList<>();@RequestMapping("/publish")public boolean publishMessage(MessageInfo messageInfo){if (!StringUtils.hasLength(messageInfo.getFrom())|| !StringUtils.hasLength(messageInfo.getTo())|| !StringUtils.hasLength(messageInfo.getMessage())){return false;}//暂时存放在内存中
//        messageInfos.add(messageInfo);//把数据放在mysql当中messageService.insertMessage(messageInfo);return true;}@RequestMapping("/getList")public List<MessageInfo> getList(){return messageService.queryList();}
}

3.4 图书管理系统

需求:

  1. 登录: ⽤⼾输⼊账号,密码完成登录功能
  2. 列表展⽰: 展⽰图书

在这里插入图片描述

准备

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/bootstrap.min.css"><link rel="stylesheet" href="css/login.css"><script type="text/javascript" src="js/jquery.min.js"></script>
</head><body><div class="container-login"><div class="container-pic"><img src="pic/computer.png" width="350px"></div><div class="login-dialog"><h3>登陆</h3><div class="row"><span>用户名</span><input type="text" name="userName" id="userName" class="form-control"></div><div class="row"><span>密码</span><input type="password" name="password" id="password" class="form-control"></div><div class="row"><button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button></div></div></div><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){console.log(result);if(result.code==200 && result.data==true){//验证成功location.href = "book_list.html";}else{alert("用户名或密码失败");}}});}</script>
</body></html>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图书列表展示</title><link rel="stylesheet" href="css/bootstrap.min.css"><link rel="stylesheet" href="css/list.css"><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/bootstrap.min.js"></script><script src="js/jq-paginator.js"></script></head><body><div class="bookContainer"><h2>图书列表展示</h2><div class="navbar-justify-between"><div><button class="btn btn-outline-info" type="button" onclick="location.href='book_add.html'">添加图书</button><button class="btn btn-outline-info" type="button" onclick="batchDelete()">批量删除</button></div></div><table><thead><tr><td>选择</td><td class="width100">图书ID</td><td>书名</td><td>作者</td><td>数量</td><td>定价</td><td>出版社</td><td>状态</td><td class="width200">操作</td></tr></thead><tbody></tbody></table><div class="demo"><ul id="pageContainer" class="pagination justify-content-center"></ul></div><script>getBookList();function getBookList() {$.ajax({type: "get",url: "/book/getListByPage" + location.search,success: function (result) {console.log("后端返回成功");if (result.code == -1) {alert("发生内部错误, 请联系管理员");return;}var data = result.data;var books = data.records;console.log(books);var finalHtml = "";for (var book of books) {//拼接htmlfinalHtml += '<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.stateCN + '</td>';finalHtml += '<td>';finalHtml += '<div class="op">';finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';finalHtml += '<a href="javascript:void(0)" οnclick="deleteBook(' + book.id + ')">删除</a>';finalHtml += '</div>';finalHtml += '</td>';finalHtml += '</tr>';}$("tbody").html(finalHtml);//处理翻页信息//翻页信息$("#pageContainer").jqPaginator({totalCounts: data.count, //总记录数pageSize: 10,    //每页的个数visiblePages: 5, //可视页数currentPage: data.pageRequest.currentPage,  //当前页码first: '<li class="page-item"><a class="page-link">首页</a></li>',prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',//页面初始化和页码点击时都会执行onPageChange: function (page, type) {console.log("第" + page + "页, 类型:" + type);if (type == "change") {// console.log("book_list.html"+location.search);location.href = "book_list.html?currentPage=" + page;}}});},error: function (error) {console.log(error);if (error != null && error.status == 401) {location.href = "login.html";}}});}function deleteBook(id) {var isDelete = confirm("确认删除?");//弹出确认框if (isDelete) {console.log(id);//删除图书$.ajax({type: "post",url: "/book/updateBook",data: {id: id,status: 0},success: function (result) {if (result.code == 200 && result.data == true) {alert("删除成功");location.href = "book_list.html";}}});}}function batchDelete() {var isDelete = confirm("确认批量删除?");if (isDelete) {//获取复选框的idvar ids = [];$("input:checkbox[name='selectBook']:checked").each(function () {ids.push($(this).val());});console.log(ids);$.ajax({type: "post",url: "/book/batchDelete?ids=" + ids,success: function (result) {if (result.code==200 && result.data == true) {//删除成功location.href = "book_list.html";} else {alter("删除失败, 请联系管理员");}}});}}</script></div>
</body></html>

根据需求可以得知, 后端需要提供两个接⼝

  1. 账号密码校验接⼝: 根据输⼊⽤⼾名和密码校验登录是否通过
  2. 图书列表: 提供图书列表信息

在这里插入图片描述

后端

@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/login")public boolean login(String name, String password, HttpSession session){//账号或密码为空if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)){return false;}//模拟验证数据, 账号密码正确if("admin".equals(name) && "admin".equals(password)){session.setAttribute("userName",name);return true;}//账号密码错误return false;}
}
@RequestMapping("/book")
@RestController
public class BookController {@RequestMapping("/getList")public List<BookInfo> getList(){//获取数据List<BookInfo> books = mockData();//处理⻚⾯展⽰for (BookInfo book:books){if (book.getStatus()==1){book.setStatusCN("可借阅");}else {book.setStatusCN("不可借阅");}}return books;}/*** 数据Mock 获取图书信息** @return*/public List<BookInfo> mockData() {List<BookInfo> books = new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}

这篇关于4、SpringMVC 实战小项目【加法计算器、用户登录、留言板、图书管理系统】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088801

相关文章

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Spring AI使用tool Calling和MCP的示例详解

《SpringAI使用toolCalling和MCP的示例详解》SpringAI1.0.0.M6引入ToolCalling与MCP协议,提升AI与工具交互的扩展性与标准化,支持信息检索、行动执行等... 目录深入探索 Spring AI聊天接口示例Function CallingMCPSTDIOSSE结束语

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测