您的位置:首页 > 运维架构 > 网站架构

QiYu Admin-架构搭建

2017-04-06 09:52 211 查看

简述

自从上周写了第一篇博客,我就开始不停的忙活起来我的项目了,真佩服现在的我还有那么大的精神,半夜4点突然醒了,然后就睡不着了,想着想着就打开了我的电脑,开始编写我那没有回报的后台管理系统的项目,我现在称之为QiYu Admin。只因为我的女儿叫做七语。

这个星期只要是下班时间我就疯狂的想我的博客,但是总得出点东西才能写啊,一周过去了,基本上时间都在框架和前端页面的封装上了,到现在还算出了一点点东西了,那就先出一篇吧,动漫在慢也会每周更新一集啊,先看下集成哪些东西吧:

shiro集成(认证)
Thymeleaf3.0集成和Shiro标签
异常页面自定义
一些前端框架的封装(layer、sweetalert、bootstrap-table等)
用户分页列表
用户修改页面

成果

一、首页



二、用户管理



表格用的BootStrap-table,分页自动影藏和展现,当超过设定每页的条数时自动回出来分页。

三、选中一个用户点击修改(Layer弹出和用户信息页面)



四、微妙微笑的弹出提示框

不能多选



不能选择一个



更多弹出框将在后续出来。

五、异常页面



具体实现

接下来就是对上述的成果进行详细的说明喽。

Shiro的配置和Thymeleaf标签

package com.qiyu.admin.auth.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* Shiro 配置 Apache Shiro 核心通过 Filter 来实现,就好像SpringMvc 通过DispachServlet 来主控制一样。
* 既然是使用 Filter 一般也就能猜到,是通过URL规则来进行过滤和权限校验,所以我们需要定义一系列关于URL的规则和访问权限。
*/
@Configuration
public class ShiroConf {
/**
* ShiroFilterFactoryBean 处理拦截资源文件问题。
* 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
* 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
* Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roles
*/
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器.
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/assets/**", "anon");
// 配置记住我或认证通过可以访问的地址
// filterChainDefinitionMap.put("/index", "user");
// filterChainDefinitionM
4000
ap.put("/", "user");
// <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(customRealm());
// 注入记住我管理器;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
/**
* 身份认证realm; (这个需要自己写,账号密码校验;权限等)
* @return
*/
@Bean
public AuthCustomRealm customRealm() {
AuthCustomRealm customRealm = new AuthCustomRealm();
customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
}
/**
* 凭证匹配器 (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* 所以我们需要修改下doGetAuthenticationInfo中的代码; )
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(3);// 散列的次数,比如散列两次,相当于md5(md5(""));
hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
return hashedCredentialsMatcher;
}
/**
* 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* cookie对象;
* @return
*/
@Bean
public SimpleCookie rememberMeCookie() {
// 这个参数是cookie的名称,对应前端的checkbox 的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
// <!-- 记住我cookie生效时间30天 ,单位秒;-->
simpleCookie.setMaxAge(259200);
return simpleCookie;
}
/**
* cookie管理对象;
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
return cookieRememberMeManager;
}
/**
* ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
* @return
*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
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
120
121
122
123
124
125
126
127
128
129


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
120
121
122
123
124
125
126
127
128
129
备注:至于源码很多都不是我自己原创出来的,都是通过网上的一些网友和朋友借鉴而来。其中比较有名是我的一个朋友林祥纤开设了专栏,《从零开始学spring boot》。

异常页面配置

其实也就是实现了ErrorController类(这些都可以在《从零开始学spring boot》里面找到),这里就不做赘述。

Layer封装

其实没啥技术含量就是把layer.open给封装了一下,方便以后类似的功能调用。

var layerOpen=function(title,width,height,content){
return layer.open({
type:2,
skin:"qiyu-custom-layer",
title: title,
area: [width,height],
fix: false, //不固定
shadeClose: true,
shade: 0.8,
scrollbar: false,
content: content
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13


1
2
3
4
5
6
7
8
9
10
11
12
13

sweetalert封装(同上)

var bootstrapSweetAlert=function (sa_title,sa_message,sa_type) {
swal({
title: sa_title,
text: sa_message,
type: sa_type
});
}
1
2
3
4
5
6
7


1
2
3
4
5
6
7

Bootstrap-table封装(同上)

var initBootStrapTable=function(table,ajaxUrl,columns) {
table.bootstrapTable({
method: 'get',
url: ajaxUrl,
cache: false,
dataType: "json",
striped: false,  //使表格带有条纹
sortable: true,
pagination: true,   //在表格底部显示分页工具栏
pageSize: 8,
pageNumber: 1,
pageList: [5, 8, 10],
idField: "id",  //标识哪个字段为id主键
showToggle: false,   //名片格式
cardView: false,//设置为True时显示名片(card)布局
singleSelect: false,//复选框只能选择一条记录
search: false,//是否显示右上角的搜索框
clickToSelect: true,//点击行即可选中单选/复选框
sidePagination: "server",//表格分页的位置
queryParamsType: "", //参数格式,发送标准的RESTFul类型的参数请求
strictSearch: true,
showColumns: false,     //是否显示所有的列
showRefresh: false,     //是否显示刷新按钮
minimumCountColumns: 2,    //最少允许的列数
responseHandler: function (res) {
return {
"rows": res.dataList,
"total": res.total
};
},
silent: true,  //刷新事件必须设置
formatNoMatches: function () {  //没有匹配的结果
return '无符合条件的记录';
},
rowStyle: function (row, index) {
return {classes: "cursorHand"}
},
columns: columns
});
}
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


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

结语

其实都是站在巨人的肩膀上来做的,所以我把自己定位为我不是一个程序员、我不是一个架构师、我不是一个设计师。

转自:山竹之七语:QiYu Admin-架构搭建
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息