spring整合shiro权限管理与数据库设计

				版权声明:本文为博主原创文章,未经博主允许不得转载。					https://blog.csdn.net/hzw2312/article/details/54612962				</div>
							            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-5edb848729.css">
					<div class="htmledit_views" id="content_views">

之前的文章中我们完成了基础框架的搭建,现在基本上所有的后台系统都逃不过权限管理这一块,这算是一个刚需了。现在我们来集成shiro来达到颗粒化权限管理,也就是从连接菜单到页面功能按钮,都进行权限都验证,从前端按钮的显示隐藏,到后台具体功能方法的权限验证。

首先要先设计好我们的数据库,先来看一张比较粗糙的数据库设计图:


具体的数据库设计代码,请查看:https://git.oschina.net/gzsjd/task/blob/master/sql/task.sql?dir=0&filepath=sql

下面我们开始根据之前的框架集成shiro

首先在pom.xml添加shiro的支持,先在properties中声明一下要倒入的版本:


 
 
  1. <properties>
  2. <shiro.version>1.3.2 </shiro.version>
  3. <commons-logging.version>1.2 </commons-logging.version>
  4. </properties>
然后在是dependency的添加:


 
 
  1. <!-- shiro权限 -->
  2. <dependency>
  3. <groupId>org.apache.shiro </groupId>
  4. <artifactId>shiro-all </artifactId>
  5. <version>${shiro.version} </version>
  6. </dependency>
  7. <!-- commons-logging -->
  8. <dependency>
  9. <groupId>commons-logging </groupId>
  10. <artifactId>commons-logging </artifactId>
  11. <version>${commons-logging.version} </version>
  12. </dependency>
下面是shiro的配置跟spring配置放在同级目录spring-shiro.xml:


 
 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:util= "http://www.springframework.org/schema/util"
  4. xmlns:aop= "http://www.springframework.org/schema/aop"
  5. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation= "
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  10. <!-- 缓存管理器 使用Ehcache实现 -->
  11. <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
  12. <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
  13. </bean>
  14. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  15. <!--认证管理器-->
  16. <property name="realm" ref="shiroSecurityRealm" />
  17. <!-- 缓存管理器 -->
  18. <property name="cacheManager" ref="cacheManager" />
  19. <!-- rememberMe管理器 -->
  20. <property name="rememberMeManager" ref="rememberMeManager"/>
  21. </bean>
  22. <!-- 会话ID生成器 -->
  23. <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
  24. <!-- 会话Cookie模板 -->
  25. <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
  26. <constructor-arg value="sid"/>
  27. <property name="httpOnly" value="true"/>
  28. <property name="maxAge" value="-1"/>
  29. </bean>
  30. <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
  31. <constructor-arg value="rememberMe"/>
  32. <property name="httpOnly" value="true"/>
  33. <property name="maxAge" value="2592000"/> <!-- 30天 -->
  34. </bean>
  35. <!-- rememberMe管理器 -->
  36. <bean id="rememberMeManager"
  37. class= "org.apache.shiro.web.mgt.CookieRememberMeManager">
  38. <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('7gzYfKjTASKdsai43ds==')}"/>
  39. <property name="cookie" ref="rememberMeCookie"/>
  40. </bean>
  41. <!-- 会话DAO -->
  42. <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
  43. <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
  44. <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
  45. </bean>
  46. <!-- 会话验证调度器 -->
  47. <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
  48. <property name="sessionValidationInterval" value="3000000"/>
  49. <property name="sessionManager" ref="sessionManager"/>
  50. </bean>
  51. <!-- 会话管理器 -->
  52. <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
  53. <property name="globalSessionTimeout" value="3000000"/>
  54. <property name="deleteInvalidSessions" value="true"/>
  55. <property name="sessionValidationSchedulerEnabled" value="true"/>
  56. <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
  57. <property name="sessionDAO" ref="sessionDAO"/>
  58. <property name="sessionIdCookieEnabled" value="true"/>
  59. <property name="sessionIdCookie" ref="sessionIdCookie"/>
  60. </bean>
  61. <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
  62. <property name="rememberMeParam" value="rememberMe"/>
  63. </bean>
  64. <bean id="sysUserFilter" class="yfkj.gz.task.security.SysUserFilter"/>
  65. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  66. <property name="securityManager" ref="securityManager"/>
  67. <property name="loginUrl" value="/login.jsp"/>
  68. <property name="successUrl" value="/page/main.action"/>
  69. <property name="filters">
  70. <util:map>
  71. <entry key="authc">
  72. <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>
  73. </entry>
  74. <entry key="sysUser" value-ref="sysUserFilter"/>
  75. </util:map>
  76. </property>
  77. <property name="filterChainDefinitions">
  78. <value>
  79. /static/** = anon
  80. /login.jsp = anon
  81. /sysuser/login.action = anon
  82. /sysuser/register.action = anon
  83. /sysuser/getEMailCount.action = anon
  84. /sysuser/getUserNameCount.action = anon
  85. /sysuser/logout.action = logout
  86. /** = user,sysUser <!-- 表示访问该地址的用户是身份验证通过或RememberMe登录的都可以 -->
  87. <!-- /** = authc 表示访问该地址用户必须身份验证通过-->
  88. </value>
  89. </property>
  90. </bean>
  91. <!-- Post processor that automatically invokes init() and destroy() methods -->
  92. <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
  93. </beans>

上面的

/static/** = anon,/login.jsp = anon...这些等于anon的就是默认不做权限验证的,我们的登录,注册,静态资源等,不需要权限验证。

权限缓存的配置(如果不用缓存的话,每次请求都要去访问数据库查询权限)ehcache-shiro.xml:


 
 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache name="shirocache">
  3. <diskStore path="java.io.tmpdir/yfkj-shiro-ehcache"/>
  4. <!-- 默认缓存 -->
  5. <defaultCache maxElementsInMemory="1000" eternal="false"
  6. overflowToDisk= "true" timeToIdleSeconds= "300" timeToLiveSeconds= "180"
  7. diskPersistent= "false" diskExpiryThreadIntervalSeconds= "120" />
  8. <!-- 登录记录缓存 -->
  9. <cache name="passwordRetryCache"
  10. maxEntriesLocalHeap= "2000"
  11. eternal= "false"
  12. timeToIdleSeconds= "3600"
  13. timeToLiveSeconds= "0"
  14. overflowToDisk= "false"
  15. statistics= "true">
  16. </cache>
  17. <!-- 授权缓存 -->
  18. <cache name="authorizationCache"
  19. maxEntriesLocalHeap= "2000"
  20. eternal= "false"
  21. timeToIdleSeconds= "3600"
  22. timeToLiveSeconds= "0"
  23. overflowToDisk= "false"
  24. statistics= "true">
  25. </cache>
  26. <!-- 认证缓存 -->
  27. <cache name="authenticationCache"
  28. maxEntriesLocalHeap= "2000"
  29. eternal= "false"
  30. timeToIdleSeconds= "3600"
  31. timeToLiveSeconds= "0"
  32. overflowToDisk= "false"
  33. statistics= "true">
  34. </cache>
  35. <cache name="shiro-activeSessionCache"
  36. maxEntriesLocalHeap= "2000"
  37. eternal= "false"
  38. timeToIdleSeconds= "3600"
  39. timeToLiveSeconds= "0"
  40. overflowToDisk= "false"
  41. statistics= "true">
  42. </cache>
  43. <cache name="shiro-kickout-session"
  44. maxEntriesLocalHeap= "2000"
  45. eternal= "false"
  46. timeToIdleSeconds= "3600"
  47. timeToLiveSeconds= "0"
  48. overflowToDisk= "false"
  49. statistics= "true">
  50. </cache>
  51. </ehcache>
自定义用户过滤类SysUserFilter:


 
 
  1. import yfkj.gz.task.service.ISysUserService;
  2. import org.apache.shiro.web.filter.PathMatchingFilter;
  3. import javax.annotation.Resource;
  4. import javax.servlet.ServletRequest;
  5. import javax.servlet.ServletResponse;
  6. /**
  7. * 自定义用户过滤器
  8. * @author 胡汉三
  9. *
  10. */
  11. public class SysUserFilter extends PathMatchingFilter {
  12. @Resource
  13. private ISysUserService sysUserService;
  14. @Override
  15. protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
  16. //可以参考http://jinnianshilongnian.iteye.com/blog/2025656
  17. return true;
  18. }
  19. }
权限认证类ShiroSecurityRealm:


 
 
  1. import javax.annotation.Resource;
  2. import org.apache.shiro.authc.AuthenticationException;
  3. import org.apache.shiro.authc.AuthenticationInfo;
  4. import org.apache.shiro.authc.AuthenticationToken;
  5. import org.apache.shiro.authc.SimpleAuthenticationInfo;
  6. import org.apache.shiro.authc.UsernamePasswordToken;
  7. import org.apache.shiro.authc.credential.Sha256CredentialsMatcher;
  8. import org.apache.shiro.authz.AuthorizationInfo;
  9. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  10. import org.apache.shiro.realm.AuthorizingRealm;
  11. import org.apache.shiro.subject.PrincipalCollection;
  12. import org.springframework.stereotype.Component;
  13. import yfkj.gz.task.dao.ISysUserDao;
  14. import yfkj.gz.task.entity.SysRole;
  15. import yfkj.gz.task.entity.SysUser;
  16. import yfkj.gz.task.service.ISysUserService;
  17. /**
  18. * 权限认证
  19. * @author 胡汉三
  20. * @date 2017年1月19日 上午10:52:17
  21. */
  22. @SuppressWarnings( "deprecation")
  23. @Component
  24. public class ShiroSecurityRealm extends AuthorizingRealm {
  25. @Resource
  26. private ISysUserService userService;
  27. @Resource
  28. private ISysUserDao sysUserDao;
  29. public ShiroSecurityRealm() {
  30. setName( "ShiroSecurityRealm"); // This name must match the name in the SysUser class's getPrincipals() method
  31. setCredentialsMatcher( new Sha256CredentialsMatcher());
  32. }
  33. /**
  34. * 登录认证
  35. */
  36. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
  37. UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
  38. SysUser user = userService.getByProerties( new String[]{ "loginAccount"}, new String[]{token.getUsername()}, null);
  39. if (user != null) {
  40. return new SimpleAuthenticationInfo(user.getUserId(), user.getLoginPass(), getName());
  41. } else {
  42. return null;
  43. }
  44. }
  45. /**
  46. * 权限认证
  47. */
  48. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  49. Long userId = (Long) principals.fromRealm(getName()).iterator().next();
  50. SysUser user = userService.get(userId);
  51. if (user != null) {
  52. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
  53. for (SysRole role : user.getRoles()) {
  54. info.addRole(role.getRoleKey());
  55. info.addStringPermissions(role.getPermissions());
  56. }
  57. return info;
  58. } else {
  59. return null;
  60. }
  61. }
  62. }
在web.xml加入:


 
 
  1. <!-- 加载spring配置文件 -->
  2. <context-param>
  3. <param-name>contextConfigLocation </param-name>
  4. <param-value>classpath:spring.xml,classpath:spring-hibernate.xml,classpath:spring-shiro.xml </param-value>
  5. </context-param>
  6. <!-- shiro权限过滤器 -->
  7. <filter>
  8. <filter-name>shiroFilter </filter-name>
  9. <filter-class>org.springframework.web.filter.DelegatingFilterProxy </filter-class>
  10. <init-param>
  11. <param-name>targetFilterLifecycle </param-name>
  12. <param-value>true </param-value>
  13. </init-param>
  14. </filter>
  15. <filter-mapping>
  16. <filter-name>shiroFilter </filter-name>
  17. <url-pattern>/* </url-pattern>
  18. </filter-mapping>
在登录方法中加上权限的登录(构造方法参数:登录账号,登录密码,记住我):


 
 
  1. //存入session
  2. Subject subject = SecurityUtils.getSubject();
  3. //记得传入明文密码
  4. subject.login( new UsernamePasswordToken(userInfo.getLoginAccount(), user.getLoginPass(), rememberMe));
完整的登录方法:


 
 
  1. /**
  2. * 用户登录
  3. * @param response
  4. * @param user
  5. * @throws IOException
  6. */
  7. @RequestMapping(value = "/login", method = { RequestMethod.POST, RequestMethod.GET })
  8. public void login(SysUser user,boolean rememberMe) throws IOException{
  9. //用户登录
  10. SysUser userInfo = userService.getByProerties( new String[]{ "loginAccount"}, new String[]{user.getLoginAccount()}, null);
  11. if(userInfo== null){
  12. result.setMessage( "用户名错误");
  13. super.writeJSON(result);
  14. return;
  15. }
  16. if(!userInfo.getLoginPass().equals( new Sha256Hash(user.getLoginPass()).toHex())){
  17. result.setMessage( "密码错误");
  18. super.writeJSON(result);
  19. return;
  20. }
  21. //存入session
  22. Subject subject = SecurityUtils.getSubject();
  23. //记得传入明文密码
  24. subject.login( new UsernamePasswordToken(userInfo.getLoginAccount(), user.getLoginPass(), rememberMe));
  25. session.setAttribute(USER_SESSION, userInfo);
  26. result.setMessage( "登录成功");
  27. result.setSuccess( true);
  28. super.writeJSON(result);
  29. }
数据库也设计好啦,该整合的也整合了,怎么来实现呢,这里先说一点点,详细的等下一篇说:

jsp页面引入page指令:

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
 
 
在要做验证的按钮上加上shiro标签的判断:


 
 
  1. <shiro:hasPermission name="${ROLE_KEY}:role:role_add">
  2. <button id="btn_add" type="button" class="btn btn-default">
  3. <span class="glyphicon glyphicon-plus" aria-hidden="true"> </span>新增
  4. </button>
  5. </shiro:hasPermission>
${ROLE_KEY}:role:role_add的意思就是:

${ROLE_KEY}角色

role是指菜单(页面)

role_add指的功能

联合起来就是,当前角色在role菜单(页面)中有没有role_add新增的功能,如果有就会显示,没有就不显示这个按钮啦。

在后台方法中验证:

在对应的方法中加入代码:


 
 
  1. Subject subject = SecurityUtils.getSubject();
  2. subject.checkPermission(getCurrentRoleKey()+ ":role:role_add");
如果没有通过checkPermission,则会直接返回错误,不执行下面的代码啦。


实体Base类BaseEntity:


 
 
  1. import java.io.Serializable;
  2. import java.util.LinkedHashMap;
  3. import java.util.Map;
  4. /**
  5. * 实体父类
  6. * @author 胡汉三
  7. * @date 2017年1月18日 上午11:03:11
  8. */
  9. public class BaseEntity implements Serializable{
  10. /**
  11. *
  12. */
  13. private static final long serialVersionUID = 3730369554400423966L;
  14. /**
  15. * 排序
  16. */
  17. private Map<String, String> sortedConditions = new LinkedHashMap<String, String>();
  18. public Map<String, String> getSortedConditions() {
  19. return sortedConditions;
  20. }
  21. public void setSortedConditions(Map<String, String> sortedConditions) {
  22. this.sortedConditions = sortedConditions;
  23. }
  24. }

用户实体SysUser:


 
 
  1. import java.util.HashSet;
  2. import java.util.Set;
  3. import javax.persistence.Column;
  4. import javax.persistence.Entity;
  5. import javax.persistence.FetchType;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.Id;
  8. import javax.persistence.JoinTable;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.ManyToMany;
  11. import javax.persistence.Table;
  12. import org.hibernate.annotations.Cache;
  13. import org.hibernate.annotations.CacheConcurrencyStrategy;
  14. import yfkj.gz.support.BaseEntity;
  15. /**
  16. * 用户的实体类
  17. */
  18. @Entity
  19. @Table(name = "sys_user")
  20. public class SysUser extends BaseEntity{
  21. /**
  22. *
  23. */
  24. private static final long serialVersionUID = 2491111485758197830L;
  25. /**主键**/
  26. @Id
  27. @GeneratedValue
  28. @Column(name = "user_id")
  29. private Long userId;
  30. /**登录账号**/
  31. @Column(name = "login_account" ,length = 30 , unique = true )
  32. private String loginAccount;
  33. /**登录密码**/
  34. @Column(name = "login_pass" ,length = 65)
  35. private String loginPass;
  36. /**昵称**/
  37. @Column(name = "user_name" ,length = 20)
  38. private String userName;
  39. /**头像**/
  40. @Column(name = "user_head" ,length = 30)
  41. private String userHead;
  42. /**手机**/
  43. @Column(name = "user_phone" ,length = 20)
  44. private String userPhone;
  45. /**邮箱**/
  46. @Column(name = "user_email" ,length = 30)
  47. private String userEmail;
  48. /**性别**/
  49. @Column(name = "user_sex")
  50. private Integer userSex;
  51. /**生日**/
  52. @Column(name = "user_birthday" ,length = 30)
  53. private String userBirthday;
  54. /**注册时间**/
  55. @Column(name = "register_time" ,length = 30)
  56. private String registerTime;
  57. /**部门编码**/
  58. @Column(name = "department_key" ,length = 20)
  59. private String departmentKey;
  60. /**用户角色**/
  61. @ManyToMany(fetch = FetchType.EAGER)
  62. @JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
  63. @Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
  64. private Set<SysRole> roles = new HashSet<SysRole>();
  65. /**get/set**/
  66. /**主键**/
  67. public Long getUserId(){
  68. return userId;
  69. }
  70. /**主键**/
  71. public void setUserId(Long userId){
  72. this.userId= userId;
  73. }
  74. /**登录账号**/
  75. public String getLoginAccount(){
  76. return loginAccount;
  77. }
  78. /**登录账号**/
  79. public void setLoginAccount(String loginAccount){
  80. this.loginAccount= loginAccount;
  81. }
  82. /**登录密码**/
  83. public String getLoginPass(){
  84. return loginPass;
  85. }
  86. /**登录密码**/
  87. public void setLoginPass(String loginPass){
  88. this.loginPass= loginPass;
  89. }
  90. /**昵称**/
  91. public String getUserName(){
  92. return userName;
  93. }
  94. /**昵称**/
  95. public void setUserName(String userName){
  96. this.userName= userName;
  97. }
  98. /**头像**/
  99. public String getUserHead(){
  100. return userHead;
  101. }
  102. /**头像**/
  103. public void setUserHead(String userHead){
  104. this.userHead= userHead;
  105. }
  106. /**手机**/
  107. public String getUserPhone(){
  108. return userPhone;
  109. }
  110. /**手机**/
  111. public void setUserPhone(String userPhone){
  112. this.userPhone= userPhone;
  113. }
  114. /**邮箱**/
  115. public String getUserEmail(){
  116. return userEmail;
  117. }
  118. /**邮箱**/
  119. public void setUserEmail(String userEmail){
  120. this.userEmail= userEmail;
  121. }
  122. /**性别**/
  123. public Integer getUserSex(){
  124. return userSex;
  125. }
  126. /**性别**/
  127. public void setUserSex(Integer userSex){
  128. this.userSex= userSex;
  129. }
  130. /**生日**/
  131. public String getUserBirthday(){
  132. return userBirthday;
  133. }
  134. /**生日**/
  135. public void setUserBirthday(String userBirthday){
  136. this.userBirthday= userBirthday;
  137. }
  138. /**注册时间**/
  139. public String getRegisterTime(){
  140. return registerTime;
  141. }
  142. /**注册时间**/
  143. public void setRegisterTime(String registerTime){
  144. this.registerTime= registerTime;
  145. }
  146. public Set<SysRole> getRoles() {
  147. return roles;
  148. }
  149. public void setRoles(Set<SysRole> roles) {
  150. this.roles = roles;
  151. }
  152. }

角色实体SysRole:


 
 
  1. import java.util.Set;
  2. import javax.persistence.Column;
  3. import javax.persistence.ElementCollection;
  4. import javax.persistence.Entity;
  5. import javax.persistence.GeneratedValue;
  6. import javax.persistence.Id;
  7. import javax.persistence.JoinColumn;
  8. import javax.persistence.JoinTable;
  9. import javax.persistence.Table;
  10. import org.hibernate.annotations.Cache;
  11. import org.hibernate.annotations.CacheConcurrencyStrategy;
  12. import yfkj.gz.support.BaseEntity;
  13. /**
  14. * 角色的实体类
  15. */
  16. @Entity
  17. @Table(name = "sys_role")
  18. @Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
  19. public class SysRole extends BaseEntity{
  20. // 各个字段的含义请查阅文档的数据库结构部分
  21. private static final long serialVersionUID = 6019103858711599150L;
  22. @Id
  23. @GeneratedValue
  24. @Column(name = "role_id")
  25. private Long roleId;
  26. @Column(name = "role_key", length = 40, nullable = false, unique = true)
  27. private String roleKey;
  28. @Column(name = "role_value", length = 40, nullable = false)
  29. private String roleValue;
  30. @Column(name = "create_time", length = 30)
  31. private String createTime;
  32. @Column(name = "description", length = 200)
  33. private String description;
  34. @ElementCollection
  35. @JoinTable(name = "sys_role_permission", joinColumns = { @JoinColumn(name = "role_id") })
  36. @Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
  37. private Set<String> permissions;
  38. @Column(name= "company_id")
  39. private Long companyId;
  40. public SysRole() {
  41. }
  42. public Long getRoleId() {
  43. return roleId;
  44. }
  45. public void setRoleId(Long roleId) {
  46. this.roleId = roleId;
  47. }
  48. public String getRoleKey() {
  49. return roleKey;
  50. }
  51. public void setRoleKey(String roleKey) {
  52. this.roleKey = roleKey;
  53. }
  54. public String getRoleValue() {
  55. return roleValue;
  56. }
  57. public void setRoleValue(String roleValue) {
  58. this.roleValue = roleValue;
  59. }
  60. public String getCreateTime() {
  61. return createTime;
  62. }
  63. public void setCreateTime(String createTime) {
  64. this.createTime = createTime;
  65. }
  66. public String getDescription() {
  67. return description;
  68. }
  69. public void setDescription(String description) {
  70. this.description = description;
  71. }
  72. public Set<String> getPermissions() {
  73. return permissions;
  74. }
  75. public void setPermissions(Set<String> permissions) {
  76. this.permissions = permissions;
  77. }
  78. public Long getCompanyId() {
  79. return companyId;
  80. }
  81. public void setCompanyId(Long companyId) {
  82. this.companyId = companyId;
  83. }
  84. }
项目结构图:


源码地址: https://git.oschina.net/gzsjd/task










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值