【开源风云】从若依系列脚手架汲取编程之道(一)

📕开源风云系列

  • 🍊本系列将从开源名将若依出发,探究优质开源项目脚手架汲取编程之道。
  • 🍉从不分离版本开写到前后端分离版,再到微服务版本,乃至其中好玩的一系列增强Plus操作
  • 🍈希望你具备如下技术栈
    • 🍎Spring
    • 🍍SpringMVC
    • 🍐Mybatis/Mybatis-plus
    • 🍅Thymeleaf
    • 🥝SpringBoot
    • 🍓Shiro
    • 🍏SpringSecurity
    • 🍌SpringCloud
    • 🍒云服务器相关知识
  • 本篇是不分离版第一篇

后期会考虑将项目和安全方面的文章迁移至vuepress,找一个好看的主题,视觉效果++!

1、拉取代码

  1. 进入若依官网:RuoYi
  1. 进入Gitee,点击Forked ,就会Forked一份代码到自己的仓库
  1. 在自己仓库找到RuoYi仓库,然后复制其 URL
  1. 打开IDEA,点击 从VCS获取 ,粘贴上方复制的URL,然后点击克隆
  1. OK,现在我们就把RuoYi的代码拉到自己本地啦!

2、创建数据库

  1. 打开Navicat ,新建数据库kuangstudy_ruoyi_fast,字符集为utf8mb4,排序规则为 utf8mb4_general_ci
  1. 右键运行SQL文件 ,导入刚才拉取代码sql里面的quartz.sqlry_20240112.sql
  1. 打开ruoyi-admin/src/main/resources/application-druid.yml,修改主库数据源
  1. 运行ruoyi-admin/src/main/java/com/ruoyi/web/RuoYiApplication.java
  1. 打开浏览器,输入http://localhost:80 ,输入默认账户密码:admin/admin123

3、项目结构

text 复制代码
com.ruoyi     
├── common            // 工具类
│       └── annotation                    // 自定义注解
│       └── config                        // 全局配置
│       └── constant                      // 通用常量
│       └── core                          // 核心控制
│       └── enums                         // 通用枚举
│       └── exception                     // 通用异常
│       └── json                          // JSON数据处理
│       └── utils                         // 通用类处理
│       └── xss                           // XSS过滤处理
├── framework         // 框架核心
│       └── aspectj                       // 注解实现
│       └── config                        // 系统配置
│       └── datasource                    // 数据权限
│       └── interceptor                   // 拦截器
│       └── manager                       // 异步处理
│       └── shiro                         // 权限控制
│       └── web                           // 前端控制
├── ruoyi-generator   // 代码生成(不用可移除)
├── ruoyi-quartz      // 定时任务(不用可移除)
├── ruoyi-system      // 系统代码
├── ruoyi-admin       // 后台服务
├── ruoyi-xxxxxx      // 其他模块

4、配置介绍

4.1、服务器配置

4.1.1、如何修改服务器端口

  • ruoyi-admin/src/main/java/application.yml下查看服务端配置
yaml 复制代码
# 开发环境配置
server:
  # 服务器的HTTP端口,默认为80
  port: 80
  servlet:
    # 应用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # 连接数满后的排队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100

假如将服务器的HTTP端口改为8090,应用的访问路径改为/admin,则访问浏览器就从localhost:80 变成 localhost:8090/admin

4.1.2、如何配置tomcat访问日志

  1. 修改application.yml中的server开发环境配置
yaml 复制代码
tomcat:
    # 存放Tomcat的日志目录
    basedir: D:\Code\IDEA\KuangStudy_RuoYi_Fast\logs\tomcat
    accesslog:
      # 开启日志记录
      enabled: true
      # 访问日志存放目录
      directory: logs
  1. 重启应用登录

  2. 进入E:\Code\IDEA\KuangStudy_RuoYi_Fast\logs\tomcat 则可查看到日志

若需要再额外配置日志,请百度:SpringBoot配置tomcat访问日志

4.2、多环境配置

在我们的日常开发中,生产环境的配置测试环境的配置 以及开发环境的配置基本上都是不相同的,每次到部署环境的时候,就需要手动的切换配置文件,如果在切换的过程中一不小心的话就会出错,所以在开发中,一般会搞个配置文件检查的功能,来避免出错,而Spring Boot则充分考虑了这种情况,为开发人员提供了天然的多环境配置支持。

  1. 配置文件的名字可以是application-{profile}.yml
  2. 在配置文件中指定:spring.profiles.active={profile}

我们可以创建三个配置文件,分别为:

  • application-test.yml : 测试环境

  • application-dev.yml : 开发环境

  • application-prod.yml : 生产环境

application-test.yml 内容如下,测试端口为81:

yaml 复制代码
# 开发环境配置
server:
    # 服务器的HTTP端口,测试环境为81
    port: 81
    servlet:
        # 应用的访问路径
        context-path: /
    tomcat:
        # tomcat的URI编码
        uri-encoding: UTF-8
        # 连接数满后的排队数,默认为100
        accept-count: 1000
        threads:
            # tomcat最大线程数,默认为200
            max: 800
            # Tomcat启动初始化的线程数,默认值10
            min-spare: 100

# 数据源配置
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        druid:
            # 主库数据源
            master:
                url: jdbc:mysql://localhost:3306/kuangstudy_ruoyi_fast?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                username: root
                password: 123456
            # 从库数据源
            slave:
                # 从数据源开关/默认关闭
                enabled: false
                url: 
                username: 
                password: 
            # 初始连接数
            initialSize: 5
            # 最小连接池数量
            minIdle: 10
            # 最大连接池数量
            maxActive: 20
            # 配置获取连接等待超时的时间
            maxWait: 60000
            # 配置连接超时时间
            connectTimeout: 30000
            # 配置网络超时时间
            socketTimeout: 60000
            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # 配置一个连接在池中最小生存的时间,单位是毫秒
            minEvictableIdleTimeMillis: 300000
            # 配置一个连接在池中最大生存的时间,单位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # 配置检测连接是否有效
            validationQuery: SELECT 1 FROM DUAL
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            webStatFilter: 
                enabled: true
            statViewServlet:
                enabled: true
                # 设置白名单,不填则允许所有访问
                allow:
                url-pattern: /druid/*
                # 控制台管理用户名和密码
                login-username: ruoyi
                login-password: 123456
            filter:
                stat:
                    enabled: true
                    # 慢SQL记录
                    log-slow-sql: true
                    slow-sql-millis: 1000
                    merge-sql: true
                wall:
                    config:
                        multi-statement-allow: true
  • application-dev.yml 开发环境同上,只是端口为80
  • application-prod.yml 生产环境同上,只是端口为82

之后在 application.ymlspring.profile.active指定环境即可:

yaml 复制代码
# Spring配置
spring:
  profiles:
  	# active: test
  	# active: dev
  	# active: prod
    active: druid

4.2.1、文档块简洁配置

除了上述配置方法外,我们还可以使用文档块配置,更简洁:

  1. application.yml添加
yaml 复制代码
---
spring:
 profiles: dev

# 开发环境配置
server:
    # 服务器的HTTP端口,测试环境为81
    port: 81
    servlet:
        # 应用的访问路径
        context-path: /
    tomcat:
        # tomcat的URI编码
        uri-encoding: UTF-8
        # 连接数满后的排队数,默认为100
        accept-count: 1000
        threads:
            # tomcat最大线程数,默认为200
            max: 800
            # Tomcat启动初始化的线程数,默认值10
            min-spare: 100
            
            
---
spring:
 profiles: test
 
# 测试环境配置
server:
    # 服务器的HTTP端口,测试环境为81
    port: 81
    servlet:
        # 应用的访问路径
        context-path: /
    tomcat:
        # tomcat的URI编码
        uri-encoding: UTF-8
        # 连接数满后的排队数,默认为100
        accept-count: 1000
        threads:
            # tomcat最大线程数,默认为200
            max: 800
            # Tomcat启动初始化的线程数,默认值10
            min-spare: 100


---
spring:
 profiles: prod
 
# 生产环境配置
server:
    # 服务器的HTTP端口,生产环境为82
    port: 82
    servlet:
        # 应用的访问路径
        context-path: /
    tomcat:
        # tomcat的URI编码
        uri-encoding: UTF-8
        # 连接数满后的排队数,默认为100
        accept-count: 1000
        threads:
            # tomcat最大线程数,默认为200
            max: 800
            # Tomcat启动初始化的线程数,默认值10
            min-spare: 100

4.2.2、jar包指定环境

如果我们将项目打成 jar 包,如何指定环境运行呢?

bash 复制代码
# 以开发环境运行
java -jar RuoYi.jar --spring.profiles.active=dev
# 以测试环境运行
java -jar RuoYi.jar --spring.profiles.active=test
# 以生产环境运行
java -jar RuoYi.jar --spring.profiles.active=prod

4.3、读取application.yml

ruoyi-admin/src/main/resources/application.yml里面有项目相关配置,我们来看在代码层面是怎么获取的

yaml 复制代码
# 项目相关配置
ruoyi:
  # 名称
  name: RuoYi
  # 版本
  version: 4.7.8
  # 版权年份
  copyrightYear: 2023
  # 实例演示开关
  demoEnabled: true
  # 上传的文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/ruoyi/uploadPath
  # 获取ip地址开关
  addressEnabled: false

# Shiro
shiro:
  user:
    # 登录地址
    loginUrl: /login
    # 权限认证失败地址
    unauthorizedUrl: /unauth
    # 首页地址
    indexUrl: /index
    # 验证码开关
    captchaEnabled: true
    # 验证码类型 math 数字计算 char 字符验证
    captchaType: math
  cookie:
    # 设置Cookie的域名 默认空,即当前访问的域名
    domain:
    # 设置cookie的有效访问路径
    path: /
    # 设置HttpOnly属性
    httpOnly: true
    # 设置Cookie的过期时间,天为单位
    maxAge: 30
    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
    cipherKey:
  session:
    # Session超时时间,-1代表永不过期(默认30分钟)
    expireTime: 30
    # 同步session到数据库的周期(默认1分钟)
    dbSyncPeriod: 1
    # 相隔多久检查一次session的有效性,默认就是10分钟
    validationInterval: 10
    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
    maxSession: -1
    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
    kickoutAfter: false
  rememberMe:
    # 是否开启记住我
    enabled: true

ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java类是全局配置类,类上面有两个注解:

  • @Component : 把这个类交给Spring处理
  • @ConfigurationProperties(prefix = "ruoyi") : 把配置文件application.yml 里面的值映射到类里面,指定前缀是 ruoyi

所以要在其他类中读取到这些信息,可以使用如下第一种方式

  1. 导入RuoYiConfig 类,使用 RuoYiConfig.xxx 来访问
  2. 在Spring中注入使用
java 复制代码
@AutoWired
private RuoYiConfig ruoYiConfig;

// xxx
// 调用方法
ruoYiConfig.getName();

也可以使用第二种方式 :例如application.yml里面的shiro配置

yaml 复制代码
# Shiro
shiro:
  user:
    # 登录地址
    loginUrl: /login
    # 权限认证失败地址
    unauthorizedUrl: /unauth
    # 首页地址
    indexUrl: /index
    # 验证码开关
    captchaEnabled: true
    # 验证码类型 math 数字计算 char 字符验证
    captchaType: math
  cookie:
    # 设置Cookie的域名 默认空,即当前访问的域名
    domain:
    # 设置cookie的有效访问路径
    path: /
    # 设置HttpOnly属性
    httpOnly: true
    # 设置Cookie的过期时间,天为单位
    maxAge: 30
    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
    cipherKey:
  session:
    # Session超时时间,-1代表永不过期(默认30分钟)
    expireTime: 30
    # 同步session到数据库的周期(默认1分钟)
    dbSyncPeriod: 1
    # 相隔多久检查一次session的有效性,默认就是10分钟
    validationInterval: 10
    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
    maxSession: -1
    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
    kickoutAfter: false
  rememberMe:
    # 是否开启记住我
    enabled: true

src/main/java/com/ruoyi/framework/config/ShiroConfig.java类中使用@Value注解来注入值

复习:

  • 当类中使用了@Value@Bean注解,需要加@Configuration注解。
  • @Configuration 用于标识一个类作为应用程序上下文的配置类

4.4、自定义资源映射

src/main/java/com/ruoyi/framework/config/ResourcesConfig.java 是静态资源映射的路径:

  • 默认的/是转发跳转到首页
  • 对于上传的文件其实是上传到本地的D:/ruoyi/uploadPath路径下

怎么验证呢,我们登录若依,并修改自己的头像,修改好的头像会上传到本机D:/ruoyi/uploadPath目录下。

5、Shiro相关

5.1、登录的实现

  1. src/main/resources/templates/login.html是我们的登录的 html,在 src/main/resources/static/ruoyi/login.js 是我们登录的 js,这里看一下登录表单的验证

表单验证方法为function validateRule() 方法,若未填写账户密码会提示文字 message。

  1. 当表单验证成功后会进入 $.validator.setDefaults() 方法,会调用 login()方法进行登录
  1. 我们看一下后端的登录接口,在src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

里面的 Post 方法登录:

  1. 我们自定义的Realm是在src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java中,调用了我们自己的 loginService.login() 方法
  1. src/main/java/com/ruoyi/framework/shiro/service/SysLoginService.java 登录逻辑里面做了用户名和密码的校验

5.2、验证码实现

  1. src/main/java/com/ruoyi/framework/config/CaptchaConfig.java 里面可以设置验证码的设置
  1. application.yml里面有验证码的开关和验证码的类型

5.3、记住我实现

  1. login.html里面有 input 标签,对应 login.js 里面会传递一个 rememberMe布尔值
  1. SysLoginController.java里面会接收前端传递的布尔值,进而在ShiroConfig里面进行放置到Cookie中,最终通过securityManager()方法将这些信息注入到安全管理器里面。
  • 如图,在yml中配置cookie的属性
  • rememberMeManager注入到安全管理器securityManager
  • 最重要的是ShiroConfig的Shiro过滤器配置,这里表示对于user,kickout,onlineSession,syncOnlineSession这些路径点击记住我之后就可以被访问。

5.4、权限控制实现

  1. 角色管理可以控制对应角色的菜单权限

在前端代码层面是使用shiro:hasPermission="xxx:xxx:xxx" 来控制按钮的权限,当然我们也可以加shiro:hasRole="admin" 这样的话这个按钮就只能由权限字符为 admin 的用户操作了。

当然关于角色权限字符串 可以在sys_role表中查看:

对于权限标识可以在sys_menu中查看:

  1. 在后端也有相应的权限控制@RequiresPermissions("xxx.xxx.xxx")

[!note]

为什么前后端都要设置权限呢?

  • 前端权限是为了展示出操作按钮,恶意用户总有可能尝试绕过前端直接对后端接口发起请求。 因此,后端必须对每一个请求进行权限检查,确保只有拥有足够权限的用户才能执行相关操作

5.5、退出

Shiro自身带有退出的过滤器,所以若依是重写了过滤器的方法。

同时在ShiroConfig里面指明请求/logout路径的过滤器为logout,过滤器logout指向的就是若依自己写logoutFilter,在这个退出过滤器里面重写了方法。

相关推荐
sinovoip4 小时前
Banana Pi BPI-CanMV-K230D-Zero 采用嘉楠科技 K230D RISC-V芯片设计
人工智能·科技·物联网·开源·risc-v
OpenAnolis小助手4 小时前
开源生态发展合作倡议
开源·操作系统·龙蜥社区·龙蜥·openanolis
杭州奥能充电桩5 小时前
移动充储机器人“小奥”的多场景应用(上)
开源·能源
lsjweiyi1 天前
极简AI工具箱网站开源啦!
opencv·开源·微信支付·支付宝支付·百度ai·极简ai工具箱·ai图像处理
开源社1 天前
一场开源视角的AI会议即将在南京举办
人工智能·开源
FreeIPCC1 天前
谈一下开源生态对 AI人工智能大模型的促进作用
大数据·人工智能·机器人·开源
海害嗨1 天前
阿里巴巴官方「SpringCloudAlibaba全彩学习手册」限时开源!
学习·开源
生命是有光的1 天前
【开源风云】从若依系列脚手架汲取编程之道(八)
开源
HuggingFace1 天前
Halo 正式开源: 使用可穿戴设备进行开源健康追踪
开源·健康追踪
时光追逐者1 天前
.NET 9 中 LINQ 新增功能实操
开发语言·开源·c#·.net·.netcore·linq·微软技术