简单使用SpringMVC写一个图书管理系统的登入功能和图书展示功能

news2024/9/22 13:39:38

准备好前端的代码


这里已经准备好了前端的代码,这里仅仅简单的介绍登入功能,和展示图书列表的功能。

如图:

如上图所示,这里的前端代码还是比较多的,在这里我介绍,login.html还有book_list.html这两个。


login.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>
    <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({
            url:"/user/login",
            type: "post",
            data: {
                userName: $("#userName").val(),
                password: $("#password").val()
            },
            success: function(result){
                if(result==""){
                    //登录成功
                    location.href = "book_list.html";
                }else{
                    alert(result);
                }
            }
        });
        // location.href = "book_list.html";
    }
</script>
</body>

</html>

上述代码的核心在这一块,如图:

这里的代码是和后端做交互的,后端的url为/user/login ,请求的类型为post请求,然后传递数据,后端再返回结果,如果登入成功就跳转到,“book_list.html”的界面,展示图书。


book_list.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>
        <!-- <tr>
            <td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>
            <td>1</td>
            <td>大秦帝国第一册</td>
            <td>我是作者</td>
            <td>23</td>
            <td>33.00</td>
            <td>北京出版社</td>
            <td>可借阅</td>
            <td>
                <div class="op">
                    <a href="book_update.html?bookId=1">修改</a>
                    <a href="javascript:void(0)" onclick="deleteBook(1)">删除</a>
                </div>
            </td>
        </tr> -->


        </tbody>
    </table>

    <div class="demo">
        <ul id="pageContainer" class="pagination justify-content-center"></ul>
    </div>
    <script>

        getBookList();
        function getBookList() {
            $.ajax({
                type: "get",
                url: "/book/getList",
                success: function(books){
                    if(books==null){
                        return;
                    }
                    var finalHtml = "";
                    for(var book of books){
                        //拼接HTML
                        finalHtml +='<tr>';
                        finalHtml +='<td><input type="checkbox" name="selectBook" value="'+book.bookId+'" id="selectBook" class="book-select"></td>';
                        finalHtml +='<td>'+book.bookId+'</td>';
                        finalHtml +='<td>'+book.bookName+'</td>';
                        finalHtml +='<td>'+book.author+'</td>';
                        finalHtml +='<td>'+book.num+'</td>';
                        finalHtml +='<td>'+book.price+'</td>';
                        finalHtml +='<td>'+book.publishName+'</td>';
                        finalHtml +='<td>'+book.stateCN+'</td>';
                        finalHtml +='<td>';
                        finalHtml +='<div class="op">';
                        finalHtml +='<a href="book_update.html?bookId='+book.bookId+'">修改</a>';
                        finalHtml +='<a href="javascript:void(0)" onclick="deleteBook('+book.bookId+')">删除</a>';
                        finalHtml +='</div>';
                        finalHtml +='</td></tr>';
                    }
                    $("tbody").html(finalHtml);
                }
            });
        }

        //翻页信息
        $("#pageContainer").jqPaginator({
            totalCounts: 100, //总记录数
            pageSize: 10,    //每页的个数
            visiblePages: 5, //可视页数
            currentPage: 1,  //当前页码
            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);
            }
        });
        function deleteBook(id) {
            var isDelete = confirm("确认删除?");
            if (isDelete) {
                //删除图书
                alert("删除成功");
            }
        }
        function batchDelete() {
            var isDelete = confirm("确认批量删除?");
            if (isDelete) {
                //获取复选框的id
                var ids = [];
                $("input:checkbox[name='selectBook']:checked").each(function () {
                    ids.push($(this).val());
                });
                console.log(ids);
                alert("批量删除成功");
            }
        }

    </script>
</div>
</body>

</html>

上述代码,不做介绍了,我是主要写后端的代码的,关于这篇文章,仅仅展示图书即可,没涉及到增删改查。


后端代码


第一步:我们就先准备好图书的实体类


如代码:

package com.bite.springbook.model;

import lombok.Data;

import java.math.BigDecimal;
@Data
public class BookInfo {
    private Integer bookId;
    private String bookName;
    private String author;
    private Integer num;
    private BigDecimal price;
    private String publishName;
    private Integer state; //1- 可借阅   2- 不可借阅
    private String stateCN;
}

这里我们需要学习,@Data这个注解的作用,这个注解是lombok这个工具里面的,这里他会自动封装好get和set方法,还会重写toStirng方法。

以上就是实体的属性。


第二步:这里我们先写登入功能


如代码:

package com.bite.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 String login(String userName , String password , HttpSession session){
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
            return "用户不能为空";
        }
        if(!"zhangsan".equals(userName) || !"123456".equals(password)){
            return "用户或密码错误";
        }
        session.setAttribute("username" , userName);
        return "";
    }
}

如上述所述,这里我们用StringUntils的haslength方法,判断输入是否为空,这样可以节约代码量,然后判断用户是否输入错误,其次存储session信息,最后返回结果,和前端校验。

登入代码这些就结束了。


第三步:书写图书的展示功能


1)controller层

如代码:

package com.bite.springbook.controller;


import com.bite.springbook.model.BookInfo;
import com.bite.springbook.Service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RequestMapping("/book")
@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping("/getList")
    public List<BookInfo> getList(){
        List<BookInfo> bookInfos = bookService.getList();
        return bookInfos;
    }


}

这里我们主要是和前端响应数据用的,controller层调用service层,service层是用于处理业务数据的,这里我们用到了,依赖注入的属性注入来获取service层的对象,如代码中的@Autowired注解。

2)service层

如代码:

package com.bite.springbook.Service;

import com.bite.springbook.dao.BookDao;
import com.bite.springbook.model.BookInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;
    public List<BookInfo> getList(){
        List<BookInfo> bookInfos = bookDao.mockData();
        for(BookInfo bookInfo : bookInfos){
            if (bookInfo.getState()==1){
                bookInfo.setStateCN("可借阅");
            }else {
                bookInfo.setStateCN("不可借阅");
            }
        }
        return bookInfos;
    }
}

如图这里通过调用dao层的数据,来进行处理,也用到了对属性注入依赖,在这里我们用到了@Service注解,为了把对象交给Spring管理,通过依赖注入就可以取到对象。

3)dao层

如代码:

package com.bite.springbook.dao;

import com.bite.springbook.model.BookInfo;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Repository
public class BookDao {
    public List<BookInfo> mockData() {
        List<BookInfo> bookInfos = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            BookInfo bookInfo = new BookInfo();
            bookInfo.setBookId(i);
            bookInfo.setBookName("图书"+i);
            bookInfo.setAuthor("作者"+i);
            bookInfo.setNum(15*i+1);
            bookInfo.setPrice(new BigDecimal(22*i+5-0.5*i));
            bookInfo.setPublishName("出版社"+i);
            bookInfo.setState(i%5==0?2:1);
            bookInfos.add(bookInfo);
        }
        return bookInfos;
    }
}

如图上述是自动生成的数据,到后面我会运用mybatis写一个完整的图书系统。这里的@Repository注解和service层的@Service作用一样。

如图运行结果:

等到后面,我会写一个完整的图书管理系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot智慧草莓基地管理系统--论文源码调试讲解

3 系统分析 当用户确定开发一款程序时&#xff0c;是需要遵循下面的顺序进行工作&#xff0c;概括为&#xff1a;系统分析-->系统设计-->系统开发-->系统测试&#xff0c;无论这个过程是否有变更或者迭代&#xff0c;都是按照这样的顺序开展工作的。系统分析就是分析…

golang 基础 泛型编程

&#xff08;一&#xff09; 示例1 package _caseimport "fmt"// 定义用户类型的结构体 type user struct {ID int64Name stringAge uint8 }// 定义地址类型的结构体 type address struct {ID intProvince stringCity string }// 集合转列表函数&#…

83. UE5 RPG 实现属性值的设置

在前面&#xff0c;我们实现了角色升级相关的功能&#xff0c;在PlayerState上记录了角色的等级和经验值&#xff0c;并在变动时&#xff0c;通过委托广播的形式向外广播&#xff0c;然后在UI上&#xff0c;通过监听委托的变动&#xff0c;进行修改等级和经验值。 在这一篇里&a…

GoogleCTF2023 Writeup

GoogleCTF2023 Writeup Misc NPC Crypto LEAST COMMON GENOMINATOR? Web UNDER-CONSTRUCTION NPC A friend handed me this map and told me that it will lead me to the flag. It is confusing me and I don’t know how to read it, can you help me out? Attach…

Unity 批处理详讲(含URP)

咱们在项目中&#xff0c;优化性能最重要的一个环节就是合批处理&#xff0c;&#xff0c;在早期Unity中&#xff0c;对于合批的处理手段主要有三种&#xff1a; Static Batching Dynamic Batching GPU Instancing 如今Unity 为了提升合批范围与效率&#xff0c;提供了…

昇思 25 天学习打卡营第 15 天 | mindspore 实现 VisionTransformer 图像分类

1. 背景&#xff1a; 使用 mindspore 学习神经网络&#xff0c;打卡第 15 天&#xff1b;主要内容也依据 mindspore 的学习记录。 2. Vision Transformer 介绍&#xff1a; mindspore 实现 VisionTransformer 图像分类&#xff1b;VisionTransformer 论文地址 VisionTransfo…

掌握Python:三本不可错过的经典书籍

强烈推荐Python初学者用这三本书入门! Python3剑客 一、《Python编程从入门到实践》 这本书适合零基础的Python读者&#xff0c;旨在帮助他们快速入门Python编程&#xff0c;并达到初级开发者的水平。书中深入浅出地介绍了Python的基础概念&#xff0c;如变量、循环、函数等…

华清数据结构day4 24-7-19

链表的相关操作 linklist.h #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h> typedef int datatype; typedef struct Node {union{int len;datatype data;};struct Node *next; } Node, *NodePtr;NodePtr list_create(); NodePtr apply_node(datatype e); …

开源XDR-SIEM一体化平台 Wazuh (1)基础架构

简介 Wazuh平台提供了XDR和SIEM功能&#xff0c;保护云、容器和服务器工作负载。这些功能包括日志数据分析、入侵和恶意软件检测、文件完整性监控、配置评估、漏洞检测以及对法规遵从性的支持。详细信息可以参考Wazuh - Open Source XDR. Open Source SIEM.官方网站 Wazuh解决…

秒懂C++之string类(上)

目录 一.string类的常用接口说明 二.不太常用接口&#xff08;了解接口&#xff09; 三.string类的遍历访问 3.1 迭代器iterator 3.2 反向迭代器 四.string的其他功能 4.1 reserve(扩容&#xff09; 4.2 resize 4.3 at 4.4 append 4.5 4.6 insert 一.string类的常用…

VS2015加断点(红色),修改过后,断点变为白色不能命中

实际这个问题是因为&#xff1a;源文件和原始版本不同。解决方法有二&#xff1a; 一&#xff0c;在断点上右键&#xff0c;选择“位置”》勾选”允许源代码与原始版本不同&#xff1b; 二&#xff0c;点击菜单栏“调试”》“选项和设置”》“常规”》去掉“要求源文件与原始…

外卖霸王餐运营规划,系统该怎么选择?

在当今的外卖市场中&#xff0c;竞争日益激烈&#xff0c;如何吸引并留住消费者成为了每个餐饮商家关注的焦点。霸王餐作为一种创新的营销策略&#xff0c;以其独特的魅力&#xff0c;吸引了大量消费者的目光。然而&#xff0c;如何有效地运营霸王餐活动&#xff0c;选择合适的…

浅谈断言之XML Schema断言

浅谈断言之XML Schema断言 “XML Schema断言”是一种专门用于验证基于XML的响应是否遵循特定XML Schema定义的标准和结构的断言类型。下面我们将详细探讨XML Schema断言的各个方面。 XML Schema断言简介 XML Schema断言&#xff08;XML Schema Assertion&#xff09;允许用户…

EXO项目解析:pynvml怎么实现监控的,包括什么参数

目录 pynvml怎么实现监控的,包括什么参数 pynvml实现监控的方式 pynvml包括的主要参数 GPU功耗的组成 举例说明 注意事项 EXO项目解析:https://github.com/exo-explore/exo?tab=readme-ov-file 这段代码是一个使用setuptools库编写的Python包安装脚本,主要用于定义和…

std的时间函数——chrono

参考&#xff1a; C 标准库 分数运算&#xff08;ratio库&#xff09; 再也不被时间束缚&#xff1a;C stdchrono时间库全面解析 C11时间类 c11 chrono全面解析(最高可达纳秒级别的精度) C std::chrono库使用指南 (实现C 获取日期,时间戳,计时等功能) 一、std的分数ratio…

Android 防止重复点击

1.第一种方式&#xff1a; private static final int MIN_DELAY_TIME 2000; // 两次点击间隔不能少于2000ms private static long lastClickTime System.currentTimeMillis(); public static boolean isFastClick() { boolean flag true; long currentClickTime …

JMeter接口测试-3.断言及参数化测试

1. 断言 JMeter官方断言&#xff08;Assertion&#xff09;的定义 用于检查测试中得到的响应数据是否符合预期&#xff0c;用于保证测试过程中的数据交互与预期一致 断言的目的&#xff1a; 一个取样器可以添加多个不同形式的断言&#xff0c;根据你的检查需求来添加相应的…

dou dian滑块captchaBody

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi a…

基于生物地理算法的MLP多层感知机优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 生物地理算法&#xff08;BBO&#xff09;原理 4.2 多层感知机&#xff08;MLP&#xff09; 4.3 BBO优化MLP参数 5.完整程序 1.程序功能描述 基于生物地理算法的MLP多层感知机优化mat…

Git之repo sync -l与repo forall -c git checkout用法区别(四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…