SpringBoot小项目——简单的小区物业后台管理系统 认证鉴权 用户-角色模型 AOP切面日志 全局异常【源码】

news2024/12/27 2:06:38

在这里插入图片描述

目录

  • 引出
  • 一、应用到的技术栈
    • Spring、Spring MVC、Spring Boot基础
    • SpringBoot进阶、SpringMVC原理、AOP切面
    • MyBatis 数据库相关
    • JavaWeb基础:Session等
    • 前端Vue、JavaScript、Bootstrap
  • 二、后台管理系统的功能
    • 登录功能
      • 1.用户名密码登录
      • 2.验证码的登录
    • 报修业务的处理
    • 楼宇信息管理
    • 房屋管理
    • 业主管理【核心功能】
      • 买房的业务
      • 意向用户信息登记
      • 后端相关代码
    • 数据统计分析
  • 三、系统必备的要素
    • 登录认证
    • 权限管理
      • 采用的模型和思路
      • 自定义注解和实现
    • 另一种权限(页面不同)
      • 普通员工--夸夸自己
      • 我是boss--隐藏地图
    • 日志管理
    • 全局异常
  • 总结

引出

基于SpringBoot的简单的小区物业后台管理系统,主要功能有报修的处理,楼宇信息和房屋信息的管理,业主信息的管理【核心】,以及数据统计分析模块Echarts绘图;此外采用用户-角色权限模型,结合自定义注解实现简单的权限管理功能,采用aop切面实现日志的存储,全局异常的使用。

技术栈:Spring、Spring MVC、Spring Boot、MyBatis、Echarts、Session、Vue、JavaScript、Bootstrap

本项目后端代码git仓库为:
https://gitee.com/pet365/spring-community-manager

在这里插入图片描述

一、应用到的技术栈

Spring、Spring MVC、Spring Boot基础

  • Spring基础(核心容器)——从配置文件到注解开发 & 创建对象+成员变量赋值IOC & 增强方法AOP

  • Spring基础(Web-MVC)——在idea中新建springWeb项目 & 浏览器请求 和 服务器响应 & SpringMvc文件相关

  • Spring基础(Data Access数据库)——Spring+SpringMVC & 集成mybatis & 拦截器

在这里插入图片描述

SpringBoot进阶、SpringMVC原理、AOP切面

在这里插入图片描述

  • SpringBoot基础——追根溯源servlet是啥,tomcat是啥,maven是啥 & springBoot项目初步,maven构建,打包 & 测试

  • SpringMvc框架——【深入】SpringMVC 的运行流程:从客户端发送请求request到springMvc框架返回响应response的全流程分析 & DispatcherServlet

在这里插入图片描述

SpringAOP,切面

  • Spring进阶(AOP的理解)——静态/动态代理 & 面向切面编程AOP(Aspect Oriented Programming) & 日志记录 & 增强方法

  • Spring进阶(AOP的应用)—— 动态代理AOP后controller层的private方法访问失效的问题

在这里插入图片描述

MyBatis 数据库相关

【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身

在这里插入图片描述

  • mybatis 是一个优秀的基于 java 的持久层框架,主要应用于关系型数据库(sql),它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement ,封装数据等繁杂的过程。

  • mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。

  • 采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

JavaWeb基础:Session等

Java网络开发(Tomcat)—— Servlet学习 & Web相关背景知识 + 网页状态码(304) & JavaWeb项目初步

在这里插入图片描述

Java网络开发(Session)—— 从http请求 到 cookie 到 session & 用 session控制 删改数据的权限

在这里插入图片描述

网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域

在这里插入图片描述

前端Vue、JavaScript、Bootstrap

  • Java网络开发(Asynchronous异步)—— 从 Jsp 到 Ajax 的 axios 到 vue & 同步请求 到 异步请求

  • 前端基础(JavaScript)——基础语法(变量,分支…)& Json对象【重要】& 函数定义 & 事件

  • 前端基础(CSS)——css介绍 & 常用样式 & 案例—进化到Bootstrap——进化到Element-UI

二、后台管理系统的功能

登录功能

1.用户名密码登录

能够实现用户名和密码登录以及手机验证码登录,其中手机验证码存储到session中,键为登录的用户的手机号。

在这里插入图片描述

当时对于各种情况的用户进行了处理

在这里插入图片描述

离职员工

在这里插入图片描述

账号锁定

在这里插入图片描述

首次登录改密码

在这里插入图片描述

密码修改

在这里插入图片描述

在这里插入图片描述

2.验证码的登录

在这里插入图片描述

后台逻辑,手机号校验,多线程使用

在这里插入图片描述

报修业务的处理

前端页面

在这里插入图片描述

图片用的本地文件资源映射

在这里插入图片描述

批量删除当时的操作:

1.真的delete删除了,其实应该是逻辑删除,把状态修改一下,比如未处理0,已处理1,已删除2,就暂时不显示;

2.在删除之前没有做数据校验,其实按理说删除之前应该检查一下状态,是否还没有维修完成等;

在这里插入图片描述

为了前期便于测试,给了一个默认的登录用户admin,便于前期进行接口测试,不需要每次登录才能测试。

在这里插入图片描述

楼宇信息管理

快排功能

在这里插入图片描述

用动态sql

在这里插入图片描述

房屋管理

多条件查询

在这里插入图片描述

后端代码

在这里插入图片描述

用动态sql,面积后端排序

在这里插入图片描述

入住日期排除,前端实现

在这里插入图片描述

业主管理【核心功能】

业主管理的极简页面

在这里插入图片描述

详情页面

在这里插入图片描述

买房的业务

添加业主页面

在这里插入图片描述

买买买

在这里插入图片描述

买!

在这里插入图片描述

添加新的业主成功

在这里插入图片描述

在这里插入图片描述

有几个小瑕疵:

  • 身份证号码没有进行校验;
  • 记录人没有和登录的管理员绑定;

实现可买的房子到买了的房子框框中的逻辑

在这里插入图片描述

意向用户信息登记

在这里插入图片描述

在这里插入图片描述

意向用户详情页面

在这里插入图片描述

后端相关代码

开始想用这种一个参数一个参数接收的方式,但是有一个参数是ist,一直报错,后面用对象接收

在这里插入图片描述

尝试用了可变长度参数传参

在这里插入图片描述

从service到mapper

在这里插入图片描述

动态SQL的处理,可变长度参数处理
楼栋 List 是否传入执行不同的sql语句查询

在这里插入图片描述

数据统计分析

采用Echarts进行数据统计分析图表绘制

在这里插入图片描述

进行了数据校验

在这里插入图片描述

后端数据校验

在这里插入图片描述

三、系统必备的要素

登录认证

采用拦截器,如果没有登录就去登录页面

在这里插入图片描述

权限管理

采用的模型和思路

用3张表实现简单权限管理,用户对应角色
在这里插入图片描述

自定义注解和实现

处理角色权限的注解

在这里插入图片描述

拦截器,获得controller层上的注解

在这里插入图片描述

package com.tianju.interceptor;

import com.alibaba.fastjson.JSON;
import com.tianju.anno.PreAuthorize;
import com.tianju.entity.ResData;
import com.tianju.entity.User;
import com.tianju.entity.UserAuth;
import com.tianju.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

@Component
public class AuthorizeInterceptor implements HandlerInterceptor {

    @Autowired
    private IUserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        User user = (User) request.getSession().getAttribute("user");
        UserAuth userAuth = userService.queryUserAuthByUsername(user.getUsername());

        // 如果请求的资源是经过controller
        if (handler instanceof HandlerMethod){

            // 获取controller中方法上的注解
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            PreAuthorize preAuthorize = handlerMethod.getMethod().getAnnotation(PreAuthorize.class);

            // 方法上有这个注解
            if (preAuthorize!=null){
                String[] value = preAuthorize.value();
                int index = Arrays.binarySearch(value, userAuth.getRoleName());
                if (index >=0){
                    return true;
                }else {
                    response.setContentType("application/json;charset=utf-8");
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter()
                            .write(JSON.toJSONString(new ResData(300001, "没有权限访问该方法", null)));
                    return false;
                }
            }

        }

        return true;
    }
}

配置拦截器

在这里插入图片描述

package com.tianju.config;

import com.tianju.interceptor.AuthorizeInterceptor;
import com.tianju.interceptor.LoginAuthorInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * springmvc的配置类
 * 1.是配置类;@Configuration
 * 2.是springmvc的配置类;implements WebMvcConfigurer
 */
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Value("${repairImg}")
    String repairImgLocation;

    // 静态资源映射;
    // 要点:1.浏览器访问的连接 /repair/**;2.映射的位置,file:D:/620/repair/
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/repair/**")
                .addResourceLocations("file:"+repairImgLocation); // 映射的位置
    }

    // 拦截器,拦截谁,放行谁
    @Autowired
    LoginAuthorInterceptor loginAuthorInterceptor;

    @Autowired
    AuthorizeInterceptor authorizeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginAuthorInterceptor)
                .addPathPatterns("/**") //拦截谁,表示都拦截
                .excludePathPatterns(
                        "/user/loginPage","/user/login",
                        "/js/**","/css/**","/bootstrap/**","/img/**",
                        "/user/loginSms","/getSmsYzm"
                );

        registry.addInterceptor(authorizeInterceptor)
                .addPathPatterns("/**") //拦截谁,表示都拦截
                .excludePathPatterns(
                        "/user/loginPage","/user/login",
                        "/js/**","/css/**","/bootstrap/**","/img/**",
                        "/user/loginSms","/getSmsYzm"
                );
    }
}

另一种权限(页面不同)

普通员工–夸夸自己

在这里插入图片描述

我是boss–隐藏地图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

日志管理

AOP切面,用来记录日志,什么时候,谁,访问了啥,干了啥

在这里插入图片描述

package com.tianju.aop;

import com.tianju.entity.User;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;

import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;
/**
 * 记录日志,用增强方法,
 * 要点:
 * 0.是增强类 @Aspect,在容器中 @Component
 * 1.给谁做增强,
 * 2.怎么增强,@before @after @afterReturning @afterThrowing
 */

/**
 * @Component 在容器中
 * @Aspect 是增强方法
 * @Before("@within(org.springframework.stereotype.Controller)") 给controller层增强
 */
@Component
@Aspect
@Slf4j // 用lombok.extern.slf4j.Slf4j;
public class LoggingAsp {
    @Autowired // session也在容器里,所以直接可以注入
    private HttpSession session;

    // 给所有标注了@Controller注解的方法做增强
    @Before("@within(org.springframework.stereotype.Controller)")
    public void log(JoinPoint joinPoint){
        String className = joinPoint.getTarget().getClass().getSimpleName(); // 获取类名
        String methodName = joinPoint.getSignature().getName(); // 获取方法名
        Object[] args = joinPoint.getArgs(); // 获取传的参数
        // 获取当前登陆的人,从session中获取
        User user = (User) session.getAttribute("user");
        String username = (user==null)?"未登录人员":user.getUsername();
        log.info("{}访问了{}类的{}方法,传的参数为{}",
                new Date() + username,className,methodName, Arrays.toString(args));
    }
}

持久化日志到本地

在这里插入图片描述

# 日志的相关配置
logging:
  file:
    name: D:\\620\\log\\community.log
  level:
    org.springframework.web: debug
    com.tianju: debug
    org.springframework.jdbc.support.JdbcTransactionManager: debug

全局异常

如果没有全局异常处理,则异常会一层一层,从dao到service到controller,最后抛给前端,然后用户看到一堆看不懂的东西

在这里插入图片描述

兜底异常,返回统一异常信息,更进一步的返回一个页面

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


总结

1.简单的小区物业后台管理系统,主要功能有报修的处理,楼宇信息和房屋信息的管理,业主信息的管理【核心】,以及数据统计分析模块Echarts绘图;
2.此外采用用户-角色权限模型,结合自定义注解实现简单的权限管理功能;
3.采用aop切面实现日志的存储;
4.全局异常的使用。

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

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

相关文章

【多线程面试题十】、说一说notify()、notifyAll()的区别

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:说一说notify()、notify…

C++哈希表:一种快速查找和插入的方法

文章目录 1、前言2、unordered系列关联式容器2.1、 unordered_map2.1.1、unordered_map的文档介绍2.1.2、unordered_map的接口说明 2.2、 unordered_set 3. 底层结构3.1 哈希概念3.2 哈希冲突2.3 哈希函数2.4 哈希冲突解决2.4.1 闭散列2.4.2 开散列 4. 模拟实现4.1 哈希表的改造…

论文速递 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统

注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统 原文链接:https://ieeexplore.ieee.org/abstract/document/10269067 本文提出了一种稳健的久坐行为监测系统RoSeFi。…

ITSource 分享 第5期【校园信息墙系统】

项目介绍 本期给大家介绍一个 校园信息墙 系统,可以发布信息,表白墙,分享墙,校园二手买卖,咨询分享等墙信息。整个项目还是比较系统的,分为服务端,管理后台,用户Web端,小…

SHCTF 山河CTF Reverse方向[Week1]全WP 详解

文章目录 [WEEK1]ez_asm[WEEK1]easy_re[WEEK1]seed[WEEK1]signin[WEEK1]easy_math[WEEK1]ez_apk [WEEK1]ez_asm 从上往下读,第一处是xor 1Eh,第二处是sub 0Ah;逆向一下先加0A后异或1E 写个EXP data "nhuo[M7mc7uhc$7midgbTf7$7%#ubf7 …

Go命令行参数操作:os.Args、flag包

Go命令行参数操作:os.Args、flag包 最近在写项目时,需要用到命令行传入的参数,正好借此机会整理一下。 1 os.Args:程序运行时,携带的参数(包含exe本身) package mainimport ("fmt"&q…

ZYNQ连载02-开发环境

ZYNQ连载02-开发环境 1. 官方文档 ZYNQ开发使用的软件为Vivado/Vitis/PetaLinux,软件体积比较大,硬盘保留100G以上的空间,赛灵思提供详细的文档,链接如下: ZYNQ文档 2. Vivido和Vitis安装 赛灵思统一安装程序 3. PetaLinux安装…

OV-VG: A Benchmark for Open-Vocabulary Visual Grounding

OV-VG: A Benchmark for Open-Vocabulary Visual Grounding 一、Abstract 写在前面 又是一周周末,光调代码去了,都没时间看论文了,汗。   这是一篇关于开放词汇定位的文章,也是近两年的新坑,但是资源也是需要不少。 …

波士顿房价预测

目录 1.初始化库并导入数据 2.查看是否有缺失值,查看各个变量的相关性 3.探究各变量之间的相关关系 4.初始化并训练线性模型 5.可视化预测情况 6.模型优化 idea1:减少决策变量 idea2:数据归一化 idea3:尝试其他模型 XGB…

Vue $nextTick 模板解析后在执行的函数

this.$nextTick(()>{ 模板解析后在执行的函数 })

智慧矿山AI算法助力护帮板支护监测,提升安全与效率

在智慧矿山AI算法系列中,护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分,在矿山生产中起到了关键的作用。那么,护帮板在哪种状态下是正常打开的呢?本文将对此进行介绍。 护帮板的…

搭建MyBatis

文章目录 1.创建Maven 工程创建MyBatis的核心配置文件创建mapper接口创建MyBatis的映射文件通过junit测试功能加入log4j日志功能核心配置文件详解1.这里实现了jdbc.properties jdbc.properties文件 默认的类型别名MyBatis的增删改查 1.创建Maven 工程 打包方式:jar…

从0到1之微信小程序快速入门(03)

目录 什么是生命周期函数 WXS脚本 ​编辑 与 JavaScript 不同 纯数据字段 组件生命周期 定义生命周期方法 代码示例 组件所在页面的生命周期 代码示例 插槽 什么是插槽 启用多插槽 ​编辑 定义多插槽 组件通信 组件间通信 监听事件 触发事件 获取组件实例 自…

【2023年NCST C语言新生培训】| 五次培训总结 | C到C++内容补充 | 排位赛详细题解 |《万字长文》

文章目录 一,四次培训总结1,第一次培训( 培训介绍 Onilne Judge,编译语言,编译器的选择 )2,第二次培训1,本次培训安排2,基本的运算式结构 3,第三次培训1,选择…

第 369 场周赛 (3题,递归式动态规划)

第一题 简单题,就不多写了 class Solution:def findKOr(self, nums: List[int], k: int) -> int:ans [0] * 31for n in nums:for i in range(31):if 2**i & n 2**i:ans[i] 1return sum([2**i if ans[i] > k else 0 for i in range(31)])第二题 0 至少…

【Linux】CentOS8.4 安装docker

🦄 🎐个人主页 🎐✨🍁 🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油!🪁🍁🪁&…

【数据结构练习题】删除有序数组中的重复项

✨博客主页:小钱编程成长记 🎈博客专栏:数据结构练习题 🎈相关博文:消失的数字 — 三种解法超详解 删除有序数组中的重复项 1.🎈题目2. 🎈解题思路3. 🎈具体代码🎇总结 1…

多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测

多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测 目录 多输入多输出 | Matlab实现k-means-LSTM(k均值聚类结合长短期记忆神经网络)多输入多输出组合预测预测效果基本描述程序设计参…

提升工作效率:轻松按关键字名称归类并批量移动文件

在忙碌的工作中,我们经常需要处理大量的文件,无论是文档、图片还是其他类型的文件。如果每次都需要手动将这些文件进行分类和移动,那么将花费大量的时间和精力。因此,本文将介绍云炫文件管理器高效的方法,帮助您轻松按…

【不用开发板学习STM32】可设置电子时钟

• 实验环境 工程文件下载链接!https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247551559&idx1&sn721b9238bc58936ac41e6ad1b9988554&chksmfcfb1990cb8c9086490b11c05bc76c08da15c71caa38715a047c49d36f25a149920aee482f3e&token204641…