springboot+mybatis+maven角色权限框架

发布时间:2018-10-24
 
技术:springboot,mybatis,maven,shiro
 

概述

Springboot作为基础框架,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为模板引擎,shiro作为安全框架,主流技术,“一网打尽” 基于注解的sql写法,零XML,极简配置,一键前后台代码生成

详细

一、前言

 

1,java服务端开发人员

2,初级人员开发人员

3,了解spring springboot+maven+mybatis+shrio

3,对框架基本掌握

(2) 你需要准备什么?

1,积极主动学习

2,java框架搭建部署

3,java后端几大框架掌握如(spring springboot maven mybatis)

二、前期准备工作

 

软件环境:eclipse

官方下载:https://www.eclipse.org/downloads/

1丶基本需求

1,实现后台权限管理

  1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。

  2. 机构管理:配置系统组织机构(公司、部门、小组),树结构展现,可随意调整上下级。

  3. 区域管理:系统城市区域模型,如:国家、省市、地市、区县的维护。

  4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。

  5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。

  6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护,如:是否、男女、类别、级别等。

  7. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。

  8. 连接池监视:监视当期系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。

  9. 工作流引擎:实现业务工单流转、在线流程设计器。

前端
1. Bootstrap
2. jQuery
3. bootstrap-table
4. layer
5. jsTree 
6. summernote
7. jquery-validate
8. jquery-treegrid

三、项目结构

项目目录结构

image.png

数据库表

image.png

 

eclipse导入,选择到项目以后,选择maven,一路默认选择到打开项目

sql文件复制并在mysql中运行创建好数据库表

打开application-dev.yml文件,修改其中的数据库连接+用户名+密码。另外一个application-pro.yml文件是 生产环境使用,具体使用哪一个是在application.yml中指定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server:
  port: 8080
  tomcat:
    uri-encoding: utf-8
  context-path: /
spring:
  thymeleaf:
    mode: LEGACYHTML5
    cache: false
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  profiles:
    active: dev
  http:
    multipart:
      max-file-size: 30Mb
      max-request-size: 30Mb
  devtools:
    restart:
      enabled: true   
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: mybatis/**/*Mapper.xml
  typeAliasesPackage: com.system.**.domain

 

四、程序实现

loginCotrller 登录接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.system.contrller;
 
import java.util.List;
 
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.system.common.annotation.Log;
import com.system.common.domain.Tree;
import com.system.common.utils.MD5Utils;
import com.system.common.utils.R;
import com.system.common.utils.ShiroUtils;
import com.system.domain.MenuDO;
import com.system.service.MenuService;
 
 
@Controller
public class loginCotrller extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
    @Autowired
    MenuService menuService;
 
    @GetMapping({ "/", "" })
    String welcome(Model model) {
        return "redirect:/login";
    }
 
    @Log("请求访问主页")
    @GetMapping({ "/index" })
    String index(Model model) {
        List<Tree<MenuDO>> menus = menuService.listMenuTree(getUserId());
        model.addAttribute("menus", menus);
        model.addAttribute("name", getUser().getName());
        model.addAttribute("username", getUser().getUsername());
        return "index_v1";
    }
 
    @GetMapping("/login")
    String login() {
        return "login";
    }
 
    @Log("登录")
    @PostMapping(value="/login")
    @ResponseBody
    R ajaxLogin(String username, String password) {
        password = MD5Utils.encrypt(username, password);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return R.ok();
        } catch (AuthenticationException e) {
            return R.error("用户或密码错误");
        }
    }
 
    @GetMapping("/logout")
    String logout() {
        ShiroUtils.logout();
        return "redirect:/login";
    }
 
    @GetMapping("/main")
    String main() {
        return "main";
    }
 
    @GetMapping("/403")
    String error403() {
        return "403";
    }
 
}

如何配置让shiro执行我们的自定义sessionManager呢?下面看ShiroConfig类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import com.system.shiro.UserRealm;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
 
@Configuration
public class ShiroConfig {
    @Bean
    public EhCacheManager getEhCacheManager() {
        EhCacheManager em = new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:config/ehcache.xml");
        return em;
    }
 
    @Bean
    UserRealm userRealm(EhCacheManager cacheManager) {
        UserRealm userRealm = new UserRealm();
        userRealm.setCacheManager(cacheManager);
        return userRealm;
    }
    @Bean
    SessionDAO sessionDAO() {
        MemorySessionDAO sessionDAO = new MemorySessionDAO();
        return sessionDAO;
    }
 
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Collection<SessionListener> listeners = new ArrayList<SessionListener>();
        listeners.add(new BDSessionListener());
        sessionManager.setSessionListeners(listeners);
        sessionManager.setSessionDAO(sessionDAO());
        return sessionManager;
    }
 
    @Bean
    SecurityManager securityManager(UserRealm userRealm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(userRealm);
        manager.setCacheManager(getEhCacheManager());
        manager.setSessionManager(sessionManager());
        return manager;
    }
 
    @Bean
    ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/qrimg/**", "anon");
        filterChainDefinitionMap.put("/docs/**", "anon");
        filterChainDefinitionMap.put("/druid/**", "anon");
        filterChainDefinitionMap.put("/upload/**", "anon");
        filterChainDefinitionMap.put("/files/**", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/blog", "anon");
        filterChainDefinitionMap.put("/wx/**", "anon");
        filterChainDefinitionMap.put("/dist/**", "anon");
        filterChainDefinitionMap.put("/blog/open/**", "anon");
        filterChainDefinitionMap.put("/**", "anon");
        filterChainDefinitionMap.put("/swagger-ui/**", "anon");
         
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
 
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
 
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }
 
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
 
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
            @Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
 
}

 

五、项目运行效果

 

代码太多不一一贴出来了让我们看下展示效果

访问地址 localhost:8080 如图

 

1,用户管理

image.png

 

2,角色管理

image.pngimage.png

3,系统菜单

image.png

 

 

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

posted on   demo例子集  阅读(2528)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
历史上的今天:
2018-03-06 SearchView的全面解析
2018-03-06 网页聊天软件
2018-03-06 android实现免费短信验证
2018-03-06 使用 JavaScript开发的跨平台音乐、书籍播放器
2018-03-06 Bmob实现android云端存储
2018-03-06 基于JWT的Token开发案例
2018-03-06 Vue-cli + Express 构建的SPA Blog(前后分离)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示