众筹系统RBAC权限项目
0 推荐视频:尚硅谷RBAC权限实战
链接:https://pan.baidu.com/s/1fJIiEhG-NCfgWhn-eyRtZA 提取码:dqvy 在第4部分,课件也在里面。课件中没有数据库sql,本文添加。代码就不怎么贴了,网盘里都有。
一 项目结构划分:
项目结构划分:Manager管理网站,portal门户网站,共同的项目common,所有的项目依赖关系parent。不能把manager和portal打包成war包,因为我们要当成整体运行,只运行一个war包,所以需要通过web的war包实现形成一个整体。这5个项目都作为maven项目创建,依赖关系可以通过maven的pom.xml体现。


1.1 parent
parent是一个maven项目。作为父项目,只做管理,不做开发,打包方式是pom方式。文件结构很简单。parent项目中不存放任何代码,只是管理多个项目之间公共的依赖。
parent-pom文件如下。可以在其中设置log、spring、jdbc等内容,以便后续项目继承parent后可以直接使用,无需再配置。也可以在后面最后的web项目的liabrary中看到这些内容。
主要是有个pom.xml,配置在这里的好处是版本变化时只需改一处。

<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>com.atguigu</groupId>
<artifactId>atcrowdfunding-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1.3-b06</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<!-- Spring整合MyBatis -->
<!-- MyBatis中延迟加载需要使用Cglib -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 控制日志输出:结合log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- ********其他****************************** -->
<!-- Ehcache二级缓存 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.6.2</version>
</dependency>
<!-- 石英调度 - 开始 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!-- 石英调度 - 结束 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.19</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>5.15.1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>5.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-explorer</artifactId>
<version>5.15.1</version>
<exclusions>
<exclusion>
<artifactId>groovy-all</artifactId>
<groupId>org.codehaus.groovy</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
这样后面在使用parent标签可以包含这些依赖。但是如果有的项目想用一部分依赖,另外一部分不需要,则可以在parent项目中用<dependencyManagement></dependencyManagement>标签指定,然后需要使用的项目写<dependency><group><artifactId>即可,不需要写版本号
在子项目B中,通过引用的项目A,可以使用A项目中中的依赖,但是不能调用A项目中自己定义的类和方法;子项目C中通过依赖的A,两者却都可以调用。
1.2 common
common是一个共同性的项目。有一些共同的代码,所以打包方式是jar包。创建maven项目。文件结构比parent多一些。主要是有一些bean、spring-context.xml、spring-mvc.xml、mybatis-config.xml

其中bean内容可以简单概括为:(这里我把get set方法删去了,应该加上)
public class User {
//用户
private Integer id;
private String username;
private String loginacct;
private String userpswd;
private String email;
private String createtime;
}
public class Role {
//角色
private Integer id;
private String name;
}
public class Permission {
//权限
private Integer id;
private String name;
private String url;
private Integer pid;
private boolean open = true;
private boolean checked = false;
private String icon;
private List<Permission> children = new ArrayList<Permission>();
}
public class Page<T> {
private List<T> datas;
private int pageno;
private int totalno;
private int totalsize;
}
public class AJAXResult {
//操作是否成功与返回的数据
private boolean success;
private Object data;
}
pom.xml
<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>
<artifactId>atcrowdfunding-common</artifactId>
<!-- parent标签代表继承,但只继承依赖,不继承java类 -->
<parent>
<groupId>com.atguigu</groupId>
<artifactId>atcrowdfunding-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
</project>
1.3 manager
打包方式是jar包。
主要是有控制层,业务层,持久层、sql映射文件xml

<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>com.atguigu</groupId>
<artifactId>atcrowdfunding-manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>atcrowdfunding-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
1.4 portal
打包方式是jar包

<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>com.atguigu</groupId>
<artifactId>atcrowdfunding-portal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>atcrowdfunding-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
1.5 web
打包方式是war。此时创建maven项目结束后web项目会报错。因为web项目中会有一个web.xml文件,但我们创建maven后web.xml并没有被创建。解决方式是:右键项目、Project Facets–>去掉勾选Dynamic Web Module,点击应用,再勾选Dynamic Web Module,下方出现Further configuration availabble,点击它,会让填写上下文根地址+上下文目录,将第二个content directory填写为/src/main/webapp。再点应用。此时就不报错了,也在/src/main/webapp下生成了web.xml。
因为web的pom.xml需要关联manager和portal项目,所以打开pom.xml后点击下方的dependencies,搜索后可以直接出现,编译器就自动写好到xml中。也可以直接在pom.xml中手写。
WEB-INF中有一些JSP的view
- controller:testController.java映射的是
test/开头的页面。测试springmvc的框架,实际没什么用途。 - dispatcherController:与登录相关的控制器,没有与登录无关的其余的控制器
- LoginInterceptor:
- ServerStartupListener:
APP_PATH路径设置到application域中,以让css和js可以在JSP中使用绝对路径。

<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>com.atguigu</groupId>
<artifactId>atcrowdfunding-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>atcrowdfunding-manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>atcrowdfunding-portal</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
二 ssm框架解释:
主要解释web.xml、springContext.xml、springmvc.xml、mybatis-config.xml
建议每句都记录。我讲这部分内容写在别的文档中了。
三 权限模型
Role-Based Access Control (RBAC)
不同的角色拥有不太的权限,只要你充当了某个角色,你就拥有了相对应的功能。
四 功能实现
权限模型介绍:
多对多:双向一对多。学生与课程的案例。
需要三张表,增加一个关系表。把外键放到多的一方表中
studentID courseID
所以在权限限制中,我们有用户表、角色表、权限表 三张基本表。还有两张关系表是用户角色关联表、角色权限关联表。
此外还有很多表。
RBAC的四个级别
RBAC0
RBAC核心模型,其他的级别都建立在该级别的基础上。
一个用户最终用于的许可=这个用户拥有的角色对应的许可的合集。
一个用户可以有多个角色。权限是并集。
RBAC1
基于RBAC0模型,进行了角色的分层,也就是说角色上有了上下级的区别。有些角色是互斥的。
需要的功能
增加编辑删除用户。
分页查询。
控制器user controller;
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping("/index")
public String index(){
}
}
相对路径和绝对路径
当jsp文件变了地方的时候,如果写的css和js文件是相对路径,很可能路径就不对了。
相对路径
- 不以
/开头:默认情况下,相对路径的基准路径是以当前资源的访问路径为基准。所以我们看到的jsp并不是我们的当前资源。而是访问的路径。 - 路径以
/开头,表示的是特殊的相对路径,在不同的场景中,相对的位置会发生变化。- 前台路径:浏览器解析的。
<a href="">、<img src="">。/相对服务器的根。即http://localhost:8080 - 后台路径:服务器解析的。
forward、xml中路径。/相对web应用的根。即http://localhost:8080/u2s
- 前台路径:浏览器解析的。
http://localhost:8080/u2s/test/test.html
EL表达式的对象不对不会报错,但方法不对会报错
为了防止基准路径出错,可以写一个监听器。实现ServletContextListener接口。
public class ServerStartupListener implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce){
// 将web应用名称(路径)保存到application范围中
ServletContext application = sre.getServletContext();
String path = application.getContextPath();
application.setAttribute("APP_PATH",path);
}
public void contextDestroyed(ServletContextEvent sce){
}
}
然后在web.xml中配置监听器
<listener>
<listener-class>ServerStartupListener全类名</listener-class>
</listener>
但只适用于JSP中。
需要的功能:实现用户的增删分页查询。
分页查询
package com.atguigu.atcrowdfunding.controller;
@Controller
@RequestMapping("/user")
public class UserController {
@ResponseBody
@RequestMapping("/pageQuery")
public Object pageQuery( String queryText, Integer pageno, Integer pagesize ) {
AJAXResult result = new AJAXResult();
try {
// 分页查询
Map<String, Object> map = new HashMap<String, Object>();
map.put("start", (pageno-1)*pagesize);
map.put("size", pagesize);
map.put("queryText", queryText);
List<User> users = userService.pageQueryData( map );
// 当前页码
// 总的数据条数
int totalsize = userService.pageQueryCount( map );
// 最大页码(总页码)
int totalno = 0;
if ( totalsize % pagesize == 0 ) {
totalno = totalsize / pagesize;
} else {
totalno = totalsize / pagesize + 1;
}
// 分页对象
Page<User> userPage = new Page<User>();
userPage.setDatas(users);
userPage.setTotalno(totalno);
userPage.setTotalsize(totalsize);
userPage.setPageno(pageno);
result.setData(userPage);
result.setSuccess(true);
} catch ( Exception e ) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
/**
* 用户首页
* @return
*/
@RequestMapping("/index1")
public String index1(
@RequestParam(required=false, defaultValue="1")Integer pageno,
@RequestParam(required=false, defaultValue="2")Integer pagesize,
Model model ) {
// 传进来的是页码和页面大小。sql中是开始位置和大小,所以需要转换
// 分页查询
// limit start, size
Map<String, Object> map = new HashMap<String, Object>();
map.put("start", (pageno-1)*pagesize);
map.put("size", pagesize);
List<User> users = userService.pageQueryData( map );
model.addAttribute("users", users);
// 当前页码
model.addAttribute("pageno", pageno);
// 总的数据条数
int totalsize = userService.pageQueryCount( map );
// 最大页码(总页码)
int totalno = 0;
if ( totalsize % pagesize == 0 ) {
totalno = totalsize / pagesize;
} else {
totalno = totalsize / pagesize + 1;
}
model.addAttribute("totalno", totalno);
return "user/index";
}
}
总:
2 crowdfunding-common
这里主要是pojo/bean
public class User {
private Integer id;
private String username;
private String loginacct;
private String userpswd;
private String email;
private String createtime;
}
public class Role {
private Integer id;
private String name;
}
public class Permission {
private Integer id;
private String name;
private String url;
private Integer pid;
private boolean open = true;
private boolean checked = false;
private String icon;
private List<Permission> children = new ArrayList<Permission>();
}
public class Page<T> {
private List<T> datas;//所在页码的数据
private int pageno;//页码
private int totalno;//总页码
private int totalsize;//总大小
}
public class AJAXResult {
//操作是否成功与返回的数据
private boolean success;
private Object data;
}
3 crowdfunding-manager
控制层
UserController.java
package com.atguigu.atcrowdfunding.controller;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.atguigu.atcrowdfunding.bean.AJAXResult;
import com.atguigu.atcrowdfunding.bean.Page;
import com.atguigu.atcrowdfunding.bean.Role;
import com.atguigu.atcrowdfunding.bean.User;
import com.atguigu.atcrowdfunding.service.RoleService;
import com.atguigu.atcrowdfunding.service.UserService;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;//关联用户service层
@Autowired
private RoleService roleService;
@ResponseBody
@RequestMapping("/deletes")
public Object deletes( Integer[] userid ) {
//删除全部选中的
AJAXResult result = new AJAXResult();
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("userids", userid);
userService.deleteUsers(map);
result.setSuccess(true);
} catch ( Exception e ) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
@ResponseBody
@RequestMapping("/delete")
public Object delete( Integer id ) {
AJAXResult result = new AJAXResult();
try {
userService.deleteUserById(id);
result.setSuccess(true);
} catch ( Exception e ) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
@ResponseBody
@RequestMapping("/update")//提交编辑内容
public Object update( User user ) {
AJAXResult result = new AJAXResult();
try {
userService.updateUser(user);
result.setSuccess(true);
} catch ( Exception e ) {
e.printStackTrace();
result.setSuccess(false);
}
return result;
}
@RequestMapping("/edit")// 编辑按钮
public String edit( Integer id, Model model ) {
User user = userService.queryById(id);
model.addAttribute("user", user);
return "user/edit";
}
@RequestMapping("/assign")//查询数据库中用户的角色(未分配/已分配)信息后显示
public String assign( Integer id, Model model ) {
User user = userService.queryById(id);
model.addAttribute("user", user);
List<Role> roles = roleService.queryAll();
List<Role> assingedRoles = new ArrayList<Role>();
List<Role> unassignRoles = new ArrayList<Role>();
// 获取关系表的数据
List<Integer> roleids = userService.queryRoleidsByUserid(id);//通过id查出角色
for ( Role role : roles ) {
if ( roleids.contains(role.getId()) ) {
assingedRoles.add(role);
} else {
unassignRoles.add(role);
}
}
model.addAttribute("ass
众筹系统RBAC权限实战

本文详细介绍了一个基于RBAC(Role-Based Access Control)的众筹系统权限管理项目实战,包括项目结构划分、Maven依赖管理、Spring框架配置及前端界面设计等关键环节。
最低0.47元/天 解锁文章
396

被折叠的 条评论
为什么被折叠?



