SSM+Shiro项目

这是第二个项目,不同于第一个项目,这次使用了intellij IDEA 来进行开发,使用相关的框架是SSM+Shiro,PageHelper 来进行分页管理,Maven来进行项目管理,还使用了MyBatis的逆向工程,这是GitHub项目地址接下来是项目总结。

项目结构

tip

数据库结构

tip

基础配置整合

Maven引入的依赖

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>SSM_Shiro1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>SSM_Shiro1 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.6.RELEASE</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- 逆向工程 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<!-- Spring整合Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!-- 返回json字符串的支持 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- JSR303 数据校验 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<!-- Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
</dependencies>

<build>
<finalName>SSM_Shiro1</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

web.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-context.xml</param-value>
</context-param>
<!-- 字符编码过滤器,一定要放在所有过滤器之前 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<!-- 官方文档 org.springframework 5.1之后使用 FormContentFilter 代替 HttpPutFormContentFilter -->
<filter>
<filter-name>FormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>

<!-- 配置shiroFilter-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 字符编码过滤器mapping -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 官方文档 org.springframework 5.1之后使用 FormContentFilter 代替 HttpPutFormContentFilter -->
<filter-mapping>
<filter-name>FormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

spring-context.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.my">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!-- Spring的配置文件,这里主要配置和业务逻辑有关的 -->
<!--=================== 数据源,事务控制,xxx ================ -->
<context:property-placeholder location="classpath:dbconfig.properties" />
<bean id="pooledDataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- Shiro配置-->
<import resource="classpath:shiro/Shiro-context.xml" />
<!-- Mybatis整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis全局配置文件的位置 -->
<property name="configLocation"
value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<!-- 指定mybatis,mapper文件的位置 -->
<property name="mapperLocations"
value="classpath:mapper/*.xml"></property>
</bean>
<!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描所有dao接口的实现,加入到ioc容器中 -->
<property name="basePackage" value="com.my.ssm.dao"></property>
</bean>

<!--============================================= -->
<!-- ===============事务控制的配置 ================ -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制住数据源 -->
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式) -->
<aop:config>
<!-- 切入点表达式 -->
<aop:pointcut
expression="execution(* com.my.ssm.service..*(..))" id="txPoint" />
<!-- 配置事务增强 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint" />
</aop:config>

<!--配置事务增强,事务如何切入 -->
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有方法都是事务方法 -->
<tx:method name="*" />
<!--以get开始的所有方法 -->
<tx:method name="get*" read-only="true" />
</tx:attributes>
</tx:advice>
</beans>

springmvc-context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.my" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<mvc:resources location="/static/css/" mapping="/static/css/**"></mvc:resources>
<mvc:resources location="/static/bootstrap/" mapping="/static/bootstrap/**"></mvc:resources>
<mvc:resources location="/static/jquery/" mapping="/static/jquery/**"></mvc:resources>
<mvc:resources location="/static/script/" mapping="/static/script/**"></mvc:resources>
<mvc:resources location="/static/layer/" mapping="/static/layer/**"></mvc:resources>
<mvc:resources location="/static/ztree/" mapping="/static/ztree/**"></mvc:resources>
</beans>

Mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 驼峰命名法 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<typeAliases>
<package name="com.my.ssm.bean"/>
</typeAliases>

<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--分页参数合理化 -->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration>

Shiro-context.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!-- shiro配置 -->
<!-- Realm -->
<bean id="myRealm" class="com.my.ssm.Shiro.MyRealm">

</bean>
<!-- SecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<bean id="anyRolesAuthorizationFilter" class="com.my.ssm.Shiro.AnyRolesAuthorizationFilter"/>
<!-- shiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login" /> <!-- 登录地址 -->
<property name="unauthorizedUrl" value="/unauthorizedUrl" /> <!-- 没有授权返回地址 -->
<property name="filters">
<map>
<entry key="hasAnyRoles" value-ref="anyRolesAuthorizationFilter"/>
</map>
</property>
<property name="filterChainDefinitions">
<value> <!-- **代表任意子目录 这里重写了isAccessAllowed -->
/login = anon
/logout = anon
/main = hasAnyRoles["PM,SE,PG,TL,GL,QC,SA,CMO/CMS,SYSTEM,TS"]
/user/** = hasAnyRoles["PM,SE,PG,TL,GL,QC,SA,CMO/CMS,SYSTEM"]
/role/** = hasAnyRoles["PM,GL,TL,SA,SYSTEM"]
/permission/** = roles[PM]
</value>
</property>
</bean>

</beans>

外部文件

1
2
3
4
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/ssm_Shiro
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=123456

部分代码和相关mapper文件

user

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
package com.my.ssm.dao;

import com.my.ssm.bean.user;
import com.my.ssm.bean.userExample;

import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface userMapper {
long countByExample(userExample example);

int deleteByExample(userExample example);

int deleteByPrimaryKey(Integer id);

int insert(user record);

int insertSelective(user record);

List<user> selectByExample(userExample example);

user selectByPrimaryKey(Integer id);

//根据用户名查找是否有对应数据
user selectByUserName(String userName);

//批量删除
void BatchDeleteUser(Integer[] ids);

//查找用户名是否唯一
List<user> selectByUsers(String name);

//模糊查询
List<user> selectByLike(String queryText);

//添加角色关系表
void insert_user_role(HashMap<String, Object> map);

//删除角色关系表
void delete_user_role(HashMap<String, Object> map);

//查询用户对应权限
List<Integer> getRoleidsByUserid(Integer id);

int updateByExampleSelective(@Param("record") user record, @Param("example") userExample example);

int updateByExample(@Param("record") user record, @Param("example") userExample example);

int updateByPrimaryKeySelective(user record);

int updateByPrimaryKey(user record);

}

部分SQL

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
<!-- 模糊查询 -->
<select id="selectByLike" resultMap="BaseResultMap">
select * from user <where>
<if test="queryText!=null">
name like concat('%',#{queryText},'%')
</if>
</where>
order by id desc
</select>
<!-- 查询用户对应权限 -->
<select id="getRoleidsByUserid" resultType="int">
select roleid from user_role where userid=#{id}
</select>
<!-- 查找用户名唯一性 -->
<select id="selectByUsers" resultMap="BaseResultMap">
select * from user where name = #{name}
</select>
<!-- 根据用户名查找是否有对应数据 -->
<select id="selectByUserName" resultMap="BaseResultMap">
select * from user where name = #{userName}
</select>
<!-- 添加角色关系表 -->
<insert id="insert_user_role">
insert into user_role (userid,roleid) values <foreach collection="roleids" item="roleid"
separator=",">
(#{userid},#{roleid})
</foreach>
</insert>
<!-- 删除角色关系表 -->
<delete id="delete_user_role">
delete from user_role where userid=#{userid} and roleid in<foreach collection="roleids"
item="roleid" separator=",">
(#{roleid})
</foreach>
</delete>
<!-- 批量删除 -->
<delete id="BatchDeleteUser">
delete from user where id in <foreach close=")" collection="array" item="id" open="(" separator=",">
#{id}
</foreach>
</delete>

role

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
package com.my.ssm.dao;

import com.my.ssm.bean.role;
import com.my.ssm.bean.roleExample;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

public interface roleMapper {
long countByExample(roleExample example);

int deleteByExample(roleExample example);

int insert(role record);

int insertSelective(role record);

List<role> selectByExample(roleExample example);

//删除一个职位
void deleteByPrimaryKey(Integer id);

//批量删除
void BatchDeleteRole(Integer[] ids);

//全部查询或模糊查询
List<role> selectByLike(String queryText);

//用部门名查找是否有相同的部门,顺带用Shiro查找
List<role> getByRoleName(String name);

//用主键查找是否有相同的部门
role getByRoleId(Integer id);

//更新
void updateRole(role role);

//添加角色权限前先删除当前角色的权限
void deleteRolePermissions(Map<String, Object> paramMap);

//给角色添加相关权限
void insertRolePermission(Map<String, Object> paramMap);

//用户名查找对应职位
List<role> getByUserName(String userName);

int updateByExampleSelective(@Param("record") role record, @Param("example") roleExample example);

int updateByExample(@Param("record") role record, @Param("example") roleExample example);

}

部分SQL

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
<!-- 特地加个英文名 -->
<resultMap id="BaseENResultMap" type="com.my.ssm.bean.role">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="ENname" jdbcType="VARCHAR" property="ENname"/>
</resultMap>
<!-- 模糊查询或全部查询 -->
<select id="selectByLike" resultMap="BaseResultMap">
select * from role <where>
<if test="queryText!=null">
name like concat('%',#{queryText},'%')
</if>
</where>
</select>
<!-- 使用部门名查找是否有相同的部门 -->
<select id="getByRoleName" resultMap="BaseResultMap">
select * from role where name = #{name}
</select>
<!-- 使用主键查找是否有相同的部门 -->
<select id="getByRoleId" resultMap="BaseResultMap">
select * from role where id = #{id}
</select>
<!-- 更新 -->
<update id="updateRole">
update role set name =#{name} where id=#{id}
</update>
<!-- 给角色添加相关权限 -->
<insert id="insertRolePermission">
insert into role_permission (roleid, permissionid) values
<foreach collection="permissionids" item="permissionid" separator=",">
( #{roleid}, #{permissionid} )
</foreach>
</insert>
<!-- 根据名字查对应角色 -->
<select id="getByUserName" resultMap="BaseENResultMap">
SELECT * FROM role WHERE
id in (SELECT roleid FROM user_role WHERE userid in
(SELECT id FROM USER WHERE NAME = #{userName}))
</select>
<!-- 删除角色的所有权限 -->
<delete id="deleteRolePermissions">
delete from role_permission where roleid = #{roleid}
</delete>
<!-- 删除一个职位 -->
<delete id="deleteByPrimaryKey" >
delete from role where id = #{id}
</delete>
<!-- 批量删除 -->
<delete id="BatchDeleteRole">
delete from role where id in <foreach close=")" collection="array" item="id"
open="(" separator=",">
#{id}
</foreach>
</delete>

permission

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.my.ssm.dao;

import com.my.ssm.bean.Permission;
import com.my.ssm.bean.user;

import java.util.List;

public interface permissionMapper {

//这是递归查找子节点,比较浪费资源
//List<Permission> queryChildPermissions(Integer pid);

//查询所有节点
List<Permission> queryAll();

Permission queryById(Integer id);

//获取当前角色已经分配的许可信息
List<Integer> queryPermissionidsByRoleid(Integer roleid);


//根据userName 查找对应权限
List<Permission> getPermissionsByUserName(String userName);
}

全部SQL

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.my.ssm.dao.permissionMapper">
<resultMap id="query" type="com.my.ssm.bean.Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" property="name" />
<result column="pid" property="pid" />
<result column="icon" property="icon" />
</resultMap>
<resultMap id="queryShiro" type="com.my.ssm.bean.Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="ENname" property="ENname" />
</resultMap>
<!-- 查找所有数据 -->
<select id="queryAll" resultMap="query">
select * from permission
</select>

<!-- 回显数据 -->
<select id="queryPermissionidsByRoleid" resultType="int">
select permissionid from role_permission where roleid = #{roleid}
</select>
<!-- 根据userName 查找对应权限 -->
<select id="getPermissionsByUserName" resultMap="queryShiro">
select id,ENname from permission where id in
(select permissionid from role_permission where roleid in
(select roleid from user_role where userid in
(SELECT id FROM user where name = #{userName})))
</select>
</mapper>

登录控制

LoginAndLogoutController

这里使用Shiro来进行登录验证,并获取相关角色和权限,以供后面的页面的权限验证。

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
package com.my.ssm.controller;

import com.my.ssm.bean.Msg;
import com.my.ssm.bean.user;
import com.my.ssm.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
public class LoginAndLogoutController {
@Autowired
private UserService userService;

//初始页面
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/main")
public String main(){
return "main";
}
@RequestMapping("/unauthorizedUrl")
public String unauthorizedUrl(){
return "unauthorizedUrl";
}

/**
* 使用Shiro来进行登录验证和权限认证
* @param username 登录用户名
* @param userpswd 密码
* @param session 登录名字
* @return 是否成功
*/
@ResponseBody
@RequestMapping("/Login")
public Msg login(@RequestParam("username") String username, @RequestParam("userpswd") String userpswd,
HttpSession session){
UsernamePasswordToken token = new UsernamePasswordToken(username,userpswd);
try{
Subject subject = SecurityUtils.getSubject();
subject.login(token);
session.setAttribute("loginUser",username);
return Msg.success();
}catch (Exception ex){
ex.printStackTrace();
return Msg.fail();
}
}

//退出
@RequestMapping("/logout")
public String LogOut(HttpSession session){
Subject subject = SecurityUtils.getSubject();
if(subject.isAuthenticated()){
subject.logout();
}
return "redirect:/login";
}

}

MyRealm

重写验证和授权两个方法,在这里面获取相关权限和角色

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
package com.my.ssm.Shiro;

import com.my.ssm.bean.Permission;
import com.my.ssm.bean.role;
import com.my.ssm.bean.user;
import com.my.ssm.service.PermissionService;
import com.my.ssm.service.RoleService;
import com.my.ssm.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private PermissionService permissionService;

//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName = (String) SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
Set<String> roles=new HashSet<String>();
List<role> rolesByUserName = roleService.getRolesByUserName(userName);
for(role role:rolesByUserName) {
roles.add(role.getENname());
}
List<Permission> permissionsByUserName = permissionService.getPermissionsByUserName(userName);
for(Permission permission:permissionsByUserName) {
info.addStringPermission(permission.getENname());
}
info.setRoles(roles);
return info;
}

//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = (String)token.getPrincipal();
user user = userService.selectByUserName(userName);
if (user != null) {
AuthenticationInfo info = new SimpleAuthenticationInfo(user.getName(), user.getUserpassword(), getName());
return info;
}else{
return null;
}
}
}

AnyRolesAuthorizationFilter

使一个URL可以供多个角色访问。

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
package com.my.ssm.Shiro;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Set;

/**
* 重写isAccessAllowed 让roles中的关系从 AND 变为 OR,一定要注册到容器里
*/
public class AnyRolesAuthorizationFilter extends RolesAuthorizationFilter {
@Override
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;

if (rolesArray == null || rolesArray.length == 0) {
//no roles specified, so nothing to check - allow access.
return true;
}

for (String roleName : rolesArray) {
if (subject.hasRole(roleName)) {
return true;
}
}
return false;
}

}

UserController

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package com.my.ssm.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.my.ssm.bean.Msg;
import com.my.ssm.bean.role;
import com.my.ssm.bean.user;
import com.my.ssm.service.RoleService;
import com.my.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;
@Autowired
private RoleService roleService;

@RequestMapping("/index")
public String index(){
return "user/index";
}

@RequestMapping("/add")
public String add(){
return "user/add";
}

/**
* @param ids 批量删除的id
* @return JSON数据
*/
@ResponseBody
@RequestMapping(value = "/deletes",method = RequestMethod.DELETE)
public Msg DeleteUsers(@RequestParam("userid") Integer[] ids){
userService.BatchDeleteUser(ids);
return Msg.success();
}

/**
* 单个删除按钮 这里忘写了 @ResponseBody 注解,前端报404,后台却删除了数据,踩了一个坑。
* @param id 删除用户的主键
* @return JSON数据
*/
@ResponseBody
@RequestMapping(value = "/delete/{id}",method = RequestMethod.DELETE)
public Msg DeleteUser(@PathVariable("id") Integer id){
try{
userService.DeleteUser(id);
return Msg.success();
}catch (Exception ex){
return Msg.fail();
}
}

/**
* 查询当前点击的按钮id的对应权限,再回显到页面上
* @param id 当前点击按钮的id值
* @param model 页面显示数据
* @return 返回页面
*/
@RequestMapping("/assign")
public String assign(Integer id, Model model){
user user = userService.getUser(id);
//不传查询条件就会查找所有数据
List<role> roles = roleService.getByLike(null);
//未分配
ArrayList<role> unassignRoles = new ArrayList<>();
//已分配
ArrayList<role> assignRoles = new ArrayList<>();
//关系表数据
List<Integer> roleids = userService.getRoleidsByUserid(id);
for (role role : roles) {
if(roleids.contains(role.getId())){
assignRoles.add(role);
}else{
unassignRoles.add(role);
}
}
model.addAttribute("unassignRoles",unassignRoles);
model.addAttribute("assignRoles",assignRoles);
model.addAttribute("userid",user.getId());
return "user/assign";
}

/**
* 添加角色关系表
* @param id userid
* @param ids roleid
* @return
*/
@ResponseBody
@RequestMapping("/doAssign")
public Msg doAssign(@RequestParam("userid") Integer id,@RequestParam("unassignroleids") Integer[] ids){
HashMap<String, Object> map = new HashMap<>();
map.put("userid",id);
map.put("roleids",ids);
try{
userService.insert_user_role(map);
return Msg.success();
}catch (Exception ex){
return Msg.fail();
}
}
/**
* 删除角色关系表
* @param id userid
* @param ids roleid
* @return
*/
@ResponseBody
@RequestMapping("/dounAssign")
public Msg dounAssign(@RequestParam("userid") Integer id,@RequestParam("assignroleids") Integer[] ids){
HashMap<String, Object> map = new HashMap<>();
map.put("userid",id);
map.put("roleids",ids);
try {
userService.delete_user_role(map);
return Msg.success();
}catch (Exception ex){
return Msg.fail();
}

}
/**
* 点击更新按钮 查出当前用户数据,回显数据
* @param id 主键
* @param mdoel 传回数据
* @return 去到更新页面
*/
@RequestMapping("/edit")
public String edit(Integer id, Model mdoel){
user user = userService.getUser(id);
mdoel.addAttribute("user",user);
return "user/edit";
}

/**
* 更新用户的操作
* @param user 序列化数据
* @param result JSR303数据校验
* @return 返回处理是否成功和错误信息
*/
@ResponseBody
@RequestMapping(value = "/update",method = RequestMethod.PUT)
public Msg updateUser(@Valid user user, BindingResult result){
List<user> users = userService.getUsers(user.getName());
if (users.size()==1){
if(users.get(0).getId()==user.getId()) {
if(result.hasErrors()) {
Map<String,Object> map = new HashMap<String, Object>();
//校验失败,返回失败 页面显示信息
List<FieldError> errors = result.getFieldErrors();
for (FieldError fieldError : errors) {
System.out.println("错误的字段名:"+fieldError.getField());
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorMsg", map);
}else{
userService.updateUser(user);
return Msg.success();
}
}else{
return Msg.fail().add("nameisnotunique","notunique");
}
}else{
if(result.hasErrors()) {
Map<String,Object> map = new HashMap<String, Object>();
//校验失败,返回失败 页面显示信息
List<FieldError> errors = result.getFieldErrors();
for (FieldError fieldError : errors) {
System.out.println("错误的字段名:"+fieldError.getField());
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorMsg", map);
}else{
userService.updateUser(user);
return Msg.success();
}
}
}

/**
* 添加用户,可以考虑拿来写注册用
* @param user 页面序列化过来的数据
* @param result JSR303数据校验
* @return 返回JSON数据
*/
@ResponseBody
@RequestMapping("/insert")
public Msg AddUser(@Valid user user, BindingResult result){
List<user> byLike = userService.getUsers(user.getName());
if(byLike.size()==0){
if(result.hasErrors()) {
Map<String,Object> map = new HashMap<String, Object>();
//校验失败,返回失败 页面显示信息
List<FieldError> errors = result.getFieldErrors();
for (FieldError fieldError : errors) {
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorFields", map);
}
else {
userService.addUser(user);
return Msg.success();
}
}else{
return Msg.fail().add("usernameisnotunique","uniquename");
}
}
/**
* 分页查询
* @param pn 页数
* @param queryText 是否有查询条件,只能查询用户名,后期考虑是否加上邮箱
* @return 返回JSON数据
*/
@RequestMapping("/pageQuery")
@ResponseBody
public Msg pageQuery(@RequestParam(value = "pn", defaultValue = "1",required = false) Integer pn,
@RequestParam(value ="queryText",required = false) String queryText){
// 引入PageHelper分页插件
// 在查询之前只需要调用,传入页码,以及每页的大小
PageHelper.startPage(pn, 7);
// startPage后面紧跟的这个查询就是一个分页查询
List<user> users = userService.getByLike(queryText);
// 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就行了。
// 封装了详细的分页信息,包括有我们查询出来的数据,传入连续显示的页数
PageInfo page = new PageInfo(users, 6);
return Msg.success().add("pageInfo",page);
}

}

RoleController

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package com.my.ssm.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.my.ssm.bean.Msg;
import com.my.ssm.bean.role;
import com.my.ssm.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;

@RequestMapping("/index")
public String index(){
return "role/index";
}

@RequestMapping("/add")
public String add(){
return "role/add";
}

@RequestMapping("/assign")
public String assign(){
return "role/assign";
}

/**
* 添加角色权限
* @param roleid
* @param permissionids
* @return
*/
@ResponseBody
@RequestMapping("/doAssign")
public Msg doAssign( Integer roleid, Integer[] permissionids ) {

try {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("roleid", roleid);
paramMap.put("permissionids", permissionids);
roleService.insertRolePermission(paramMap);
return Msg.success();
} catch ( Exception e ) {
e.printStackTrace();
return Msg.fail();
}
}

/**
* 先查找数据然后跳转页面
* @param id 主键
* @param model 回显数据
* @return
*/
@RequestMapping("/edit")
public String edit(@RequestParam("id") Integer id,Model model){
role role = roleService.selectByRole(id);
model.addAttribute("role",role);
return "role/edit";
}

/**
* 更新部门
* @param role
* @return
*/
@ResponseBody
@RequestMapping(value = "update",method = RequestMethod.PUT)
public Msg updateRole(role role){
List<role> roles = roleService.getByRoleName(role.getName());
if(roles.size()==1){
if(roles.get(0).getId()==role.getId()){
roleService.updateRole(role);
return Msg.success();
}else{
return Msg.fail().add("errorMsg","fail");
}
}else{
roleService.updateRole(role);
return Msg.success();
}
}


/**
* @param ids 批量删除的id
* @return
*/
@ResponseBody
@RequestMapping(value = "/deletes",method = RequestMethod.DELETE)
public Msg BatchDeleteRole(@RequestParam("roleid") Integer[] ids){
roleService.BatchDeleteRole(ids);
return Msg.success();
}

/**
* 单个删除按钮 这里忘写了 @ResponseBody 注解,前端报404,后台却删除了数据,踩了一个坑。
* @param id 删除用户的主键
* @return
*/
@ResponseBody
@RequestMapping(value = "/delete/{id}",method = RequestMethod.DELETE)
public Msg DeleteRole(@PathVariable("id") Integer id){
try{
roleService.DeleteRole(id);
return Msg.success();
}catch (Exception ex){
return Msg.fail();
}
}

/**
* 用部门名先查找是否存在相同部门,如果存在提示,反之保存
* @param role
* @return
*/
@ResponseBody
@RequestMapping("/insert")
public Msg insertRole(role role){
List<role> roles = roleService.getByRoleName(role.getName());
if(roles.size()==1){
return Msg.fail();
}else{
roleService.insertRole(role);
return Msg.success();
}
}


/**
* 分页查询
* @param pn 页数
* @param queryText 是否查询
* @return
*/
@RequestMapping("/pageQuery")
@ResponseBody
public Msg pageQuery(@RequestParam(value = "pn", defaultValue = "1",required = false) Integer pn,
@RequestParam(value ="queryText",required = false) String queryText){
// 引入PageHelper分页插件
// 在查询之前只需要调用,传入页码,以及每页的大小
PageHelper.startPage(pn, 10);
// startPage后面紧跟的这个查询就是一个分页查询
List<role> roles = roleService.getByLike(queryText);
// 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就行了。
// 封装了详细的分页信息,包括有我们查询出来的数据,传入连续显示的页数
PageInfo page = new PageInfo(roles, 6);
return Msg.success().add("pageInfo",page);
}
}

PermissionController

这里使用Map来进行根节点查询

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
package com.my.ssm.controller;

import com.my.ssm.bean.Msg;
import com.my.ssm.bean.Permission;
import com.my.ssm.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("/permission")
@Controller
public class PermissionController {
@Autowired
PermissionService permissionService;

@RequestMapping("/add")
public String add() {
return "permission/add";
}

@RequestMapping("/index")
public String index() {
return "permission/index";
}


/**
* 回显数据
* @param roleid
* @return
*/
@ResponseBody
@RequestMapping("/loadAssignData")
public Object loadAssignData( Integer roleid ) {
List<Permission> permissions = new ArrayList<Permission>();
List<Permission> ps = permissionService.queryAll();

// 获取当前角色已经分配的许可信息
List<Integer> permissionids = permissionService.queryPermissionidsByRoleid(roleid);

Map<Integer, Permission> permissionMap = new HashMap<Integer, Permission>();
for (Permission p : ps) {
if ( permissionids.contains(p.getId()) ) {
p.setChecked(true);
} else {
p.setChecked(false);
}
permissionMap.put(p.getId(), p);
}
for ( Permission p : ps ) {
Permission child = p;
if ( child.getPid() == 0 ) {
permissions.add(p);
} else {
Permission parent = permissionMap.get(child.getPid());
parent.getChildren().add(child);
}
}

return permissions;
}

/**
* zTree的数据结构,使用Map来进行根节点查询,缩短时间复杂度
* @return 返回节点结构
*/
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
List<Permission> permissions = new ArrayList<>();
// 查询所有的许可数据
List<Permission> ps = permissionService.queryAll();
Map<Integer, Permission> permissionMap = new HashMap<Integer, Permission>();
for (Permission p : ps) {
permissionMap.put(p.getId(), p);
}
for ( Permission p : ps ) {
Permission child = p;
if ( child.getPid() == 0 ) {
permissions.add(p);
} else {
Permission parent = permissionMap.get(child.getPid());
parent.getChildren().add(child);
}
}
return permissions;
}
}

总结

这个项目使用了很常见的框架,非常适合新手练手,其它的具体信息可以前往我的Github仓库下载此项目查看。

原创技术分享,您的支持将鼓励我继续创作
0%