SSM框架的RBAC权限实战

6 篇文章 0 订阅
1 篇文章 0 订阅

项目完整视频点这里点这里

密码:vpt2

实际内容大概如下:

目录

项目完整视频点这里点这里

1. 项目结构

2. 环境配置

3. 环境测试

3.1 spring测试

3.2 mybatis测试

4. 登陆验证

4.1 原始方法:

4.2 改进(AJAX提交) 

4.3 退出设置

5. 遍历及模糊查询

6. 获取项目名

7. 新增用户

8. 用户更新

9. 删除用户

9.1 单个删除

9.2 批量删除

10. 角色分配功能

11. 树形菜单

12. 菜单功能

13. 角色分配功能

13.1 分配角色

13.2 显示已分配角色

14. 用户权限

15. 拦截器

15.1 登陆拦截器

15.2 权限拦截器


1. 项目结构

parent设为pom,做管理层

common设为jar,做持久层

manager设为jar,做控制层

web设为war,做显示层

2. 环境配置

ssm的各种xml配置

3. 环境测试

3.1 spring测试

新建jsp/index.jsp

web下的测试类TestController.java:

@Controller
public class TestController {

	@RequestMapping("/index")
	public String index() {
		return "index";
	}
	
	@ResponseBody
	@RequestMapping("/json")
	public Object json() {
		Map<Object, String> map=new HashMap<Object, String>();
		map.put("username", "json");
		return map;
	}

http://localhost:8080/Atcrowdfunding-web/index

3.2 mybatis测试

@Autowired
private UserService userService;

@ResponseBody
@RequestMapping("/queryAll")
public Object queryAll() {
	List<User> users=userService.queryAll();
	return users;
}

service与impl:

public interface PermissionService {

	Permission queryRootPermission();
@Service
public class UserServiceImpl implements UserService{
	@Autowired
	public UserDao userDao;

	@Override
	public List<User> queryAll() {
		return userDao.queryAll();
	}

bean:

public class User {
	private Integer id;
	private String username;

dao:

public interface UserDao {

	@Select("select * from t_user")
	public List<User> queryAll();

4. 登陆验证

4.1 原始方法:

引入资源:

<script src="layer/layer.js"></script>

html:

<h1 style="color:red">${param.errorMsg}</h1>
<form id="loginForm" action="doLogin" method="post" class="form-signin" role="form">
  <h2 class="form-signin-heading"><i class="glyphicon glyphicon-user"></i> 用户登录</h2>
	 <input type="text" class="form-control"  name="loginacct" id="loginacct" placeholder="请输入登录账号" autofocus>
         <input type="text" class="form-control" name="userpswd" id="userpswd" placeholder="请输入登录密码" style="margin-top:10px;">

js:

function dologin() {
        //非空校验
        var loginacct=$("#loginacct").val();
        if(loginacct==""){
        	//alert("用户名不能为空");   	
			layer.msg("用户名不能为空", {time:2000, icon:5, shift:6}, function(){
			});
        	return ;
        }  
        var userpswd=$("#userpswd").val();
        if(userpswd==""){
        	//alert("密码不能为空");
        	layer.msg("密码不能为空", {time:2000, icon:5, shift:6}, function(){
			});
        	return ;
        }  
        //提交表单
        $("#loginForm").submit();

User:

public class User {
	private Integer id;
	private String username;
	private String loginacct;
	private String userpswd;
	private String email;
	private String createtime;

DispatherController.java:

@Controller
public class DispatherController {
	@Autowired
	private UserService userService;
@RequestMapping("/doLogin")
public String doLogin(User user,Model model) {
	User dbUser=userService.query4Login(user);
	if (dbUser!=null) {
		return "main";
	}
	else{
		//跳回登陆页面
		String errorMsg="登陆账号或密码不存在";
		model.addAttribute("errorMsg",errorMsg);
		return "redirect:login";
	}
}

service impl...

dao:

@Select("select * from t_user where loginacct=#{loginacct} and userpswd=#{userpswd}")
public User query4Login(User user);

main.jsp...

4.2 改进(AJAX提交) 

新建AJAXResult.java为bean类:

public class AJAXResult {
	private boolean success;
	private Object data;

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
	
}

js:

function dologin() {
        //非空校验
        var loginacct=$("#loginacct").val();
        if(loginacct==""){
        	//alert("用户名不能为空");   	
			layer.msg("用户名不能为空", {time:2000, icon:5, shift:6}, function(){
			});
        	return ;
        }  
        var userpswd=$("#userpswd").val();
        if(userpswd==""){
        	//alert("密码不能为空");
        	layer.msg("密码不能为空", {time:2000, icon:5, shift:6}, function(){
			});
        	return ;
        }  
        //提交表单
        //$("#loginForm").submit();
        //ajax提交
        var loadingIndex=null;
        $.ajax({
        	type:"post",
        	url :"doAJAXLogin",
        	data:{
        		"loginacct":loginacct,
        		"userpswd" :userpswd
        	},
        	beforeSend:function(){
        		//加载
    			loadingIndex = layer.msg('处理中', {icon: 16});
        	},
        	success:function(result){
        		layer.close(loadingIndex);
        		if(result.success){
        			window.location.href="${pageContext.request.contextPath}/main";
        		}else{
        			layer.msg("用户名或密码错误,请重新输入", {time:2000, icon:5, shift:6}, function(){
        			});
        		}
        	}
        });
    }

 java:

	@ResponseBody
	@RequestMapping("/doAJAXLogin")
	public Object doAJAXLogin(User user,HttpSession session) {
		AJAXResult result=new AJAXResult();
		User dbUser=userService.query4Login(user);
		if (dbUser!=null) {
			session.setAttribute("loginUser",dbUser);
			session.setAttribute("rootPermission", root);
			result.setSuccess(true);		
		}else{
			result.setSuccess(false);
		}
		return result;
	}

4.3 退出设置

java:

@RequestMapping("/logout")
	public String logout(HttpSession session) {
		//session.removeAttribute("loginUser");
		session.invalidate();
		return "redirect:login";
	}

5. 遍历及模糊查询

动态生成分页的数据

html:

<tbody id="userData">
   <!-- 遍历信息 -->	
</tbody>
<tfoot>
    <tr >
        <td colspan="6" align="center">
	        <ul class="pagination">
	        <!-- 页码 -->									
	        </ul>
        </td>
    </tr>
</tfoot>

js:

//判断是否查询
var likeflg=false;
$(function () {
//页面原有结构
$(".list-group-item").click(function(){
    if ( $(this).find("ul") ) {
		$(this).toggleClass("tree-closed");
		if ( $(this).hasClass("tree-closed") ) {
			$("ul", this).hide("fast");
		} else {
			$("ul", this).show("fast");
		}
	}
});
//显示本页时查询
pageQuery(1);
$("#queryBtn").click(function(){
    var queryText=$("#queryText").val();
    if(queryText==""){
    	likeflg=false;
    }else{
    	likeflg=true;
    }
    pageQuery(1);			
})
})});

js:

//分页查询        
var likeflg=false;
function pageQuery(pageno){
	var loadingIndex=null;
	//pageno:分页数目,pagesize:一页10行
	var jsonData = {"pageno" : pageno, "pagesize" : 10};
	if(likeflg==true){
		jsonData.queryText=$("#queryText").val();
	}
	
	$.ajax({
		type:"POST",
		url :"${APP_PATH}/user/pageQuery",
		data: jsonData,  
		beforeSend:function(){
    		//加载
		loadingIndex = layer.msg('处理中', {icon: 16});
    	},
    	success:function(result){
    		layer.close(loadingIndex);
    		if(result.success){
 			
    			//局部刷新页面数据
    			var tableContent="";
    			var pageContent="";
    			//用户信息集合
    			var userPage=result.data;
    			//用户信息对象
    			var users=userPage.datas;       			         			
    			$.each(users,function(i,user){
    		tableContent+='		<tr>';
            tableContent+='       <td>'+(i+1)+'</td>';
  			tableContent+='	  	  <td><input type="checkbox" name="userid" value="'+user.id+'"></td>';
            tableContent+='       <td>'+user.loginacct+'</td>';
            tableContent+='       <td>'+user.username+'</td>';
            tableContent+='       <td>'+user.email+'</td>';
            tableContent+='       <td>';
  			tableContent+='	      <button type="button" onclick="goAssignPage('+user.id+')" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>';
  			tableContent+='	      <button type="button" onclick="goUpdatePage('+user.id+')" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>';
  			tableContent+='		  <button type="button" onclick="deleteUser('+user.id+',\''+user.loginacct+'\')" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button>';
  			tableContent+='	  	</td>';
            tableContent+='     </tr>';
    			});
    			
    			if(pageno>1){
    				pageContent+='<li><a href="#" onclick="pageQuery('+(pageno-1)+')">上一页</a></li>'
    			}
				for(var i=1;i<=userPage.totalno;i++){
					if(i==pageno){
						pageContent+='<li class="active"><a href="#">'+i+'</a></li>';
					}else{
						pageContent+='<li><a href="#" onclick="pageQuery('+i+')">'+i+'</a></li>';
					}			
				}
				
    			if(pageno<userPage.totalno){
    				pageContent+='<li><a href="#"  onclick="pageQuery('+(pageno+1)+')">下一页</a></li>'
    			}
    			
    			$("#userData").html(tableContent);
    			$(".pagination").html(pageContent);
    		}else{
    			layer.msg("分页信息查询错误", {time:2000, icon:5, shift:6}, function(){
    			});
    		}
    	}
	})
}  

bean:

public class Page<T> {
	private List<T> datas;
	private Integer pageno;
	private Integer totalno;
	private Integer totalsize;

java:

// 遍历查询
@ResponseBody
@RequestMapping("/pageQuery")
public Object pageQuery(String queryText, Integer pageno, Integer pagesize) {
	AJAXResult result = new AJAXResult();
	try {
		// 分页查询
		Map<String, Object> map = new HashMap<>();
		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;
}

service impl...

dao:

public List<User> pageQueryDate(Map<String, Object> map);

public int pageQueryCount(Map<String, Object> map);

查询遵循以时间的降序排列,mapper-user.xml :

<select id="pageQueryDate" resultType="cn.itcast.ssmIntegration.bean.User">
	select * from t_user 		
	<where>
		<if test="queryText!=null">
			and loginacct like concat('%',#{queryText},'%')
		</if>
	</where>
	order by createtime desc
	limit #{start},#{size}
</select>

<!-- concat(str1,str2)将多个字符串连接成一个字符串 -->
<select id="pageQueryCount" resultType="int">
	select count(*) from t_user
	<where>
		<if test="queryText!=null">
			and loginacct like concat('%',#{queryText},'%')
		</if>
	</where>
</select>

6. 获取项目名

资源路径不对导致引入资源失败

添加监听器ServerStartupListener.java:

public class ServerStartupListener implements ServletContextListener {
	public void contextInitialized(ServletContextEvent sce){
		//将web应用名称(路径)保存到application范围中
		ServletContext application=sce.getServletContext();
		String path=application.getContextPath();
		application.setAttribute("APP_PATH", path);
	}
}

web.xml新增:

<!-- 路径监听器 -->
<listener>
	<listener-class>cn.itcast.ssmIntegration.web.ServerStartupListener</listener-class>
</listener>

用法如下: 

<script src="${APP_PATH}/layer/layer.js"></script>

7. 新增用户

html:

<button onclick="window.location.href='${APP_PATH}/user/add'"><i class="glyphicon glyphicon-plus"></i> 新增</button>

java:

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

// 新增
@ResponseBody
@RequestMapping("/insert")
public Object insert(User user) {
	AJAXResult result = new AJAXResult();
	try {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		user.setCreatetime(sdf.format(new Date()));
		user.setUserpswd("123456");
		userService.insertUser(user);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}

	return result;
}

新增add.jsp

html:

<form role="form">
  <div class="form-group">
	<label for="exampleInputPassword1">登陆账号</label>
	<input type="text" class="form-control" id="loginacct" placeholder="请输入登陆账号">
  </div>
  <div class="form-group">
	<label for="exampleInputPassword1">用户名称</label>
	<input type="text" class="form-control" id="username" placeholder="请输入用户名称">
  </div>
  <div class="form-group">
	<label for="exampleInputEmail1">邮箱地址</label>
	<input type="email" class="form-control" id="email" placeholder="请输入邮箱地址">
	<p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p>
  </div>
  <button id="insertBtn" type="button" class="btn btn-success"><i class="glyphicon glyphicon-plus"></i> 新增</button>
  <button type="button" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
</form>

js:

$("#insertBtn").click(function(){		  
	var loginacct=$("#loginacct").val();
	if(loginacct==""){
		layer.msg("登陆账号不能为空", {time:2000, icon:5, shift:6}, function(){
		});
		return;
	}
	var loadingIndex=null;
	$.ajax({
		type:"post",
		url :"${APP_PATH}/user/insert",
		data:{
			"loginacct":loginacct,
			"username" :$("#username").val(),
			"email"    :$("#email").val()
		},
		beforeSend:function(){
			loadingIndex=layer.msg("处理中",{icon:16});
		},
		success:function(result){
			layer.close(loadingIndex);
			if(result.success){
				layer.msg("用户信息保存成功", {time:1200, icon:6}, function(){
					window.location.href="${APP_PATH}/user/index"
				});
			}
			else{
				layer.msg("用户信息保存失败,请重新操作", {time:2000, icon:5, shift:6}, function(){
				});
			}
		}
	})
})	

dao:

public void insertUser(User user);

mapper-user.xml:

<insert id="insertUser">
	INSERT INTO `ssm_atcrowdfunding`.`t_user` (
	`username`,
	`loginacct`,
	`userpswd`,
	`email`,
	`createtime`
	)
	VALUES
	(
	#{username},
	#{loginacct},
	#{userpswd},
	#{email},
	#{createtime}
	) ;
</insert>

8. 用户更新

js:

//获取编辑的id
function goUpdatePage(id){
     window.location.href="${APP_PATH}/user/edit?id="+id;
}

新建edit.jsp

html:

<form id="userForm" role="form">
  <div class="form-group">
	<label for="exampleInputPassword1">登陆账号</label>
	<input type="text" class="form-control" id="loginacct" value="${user.loginacct }" placeholder="请输入登陆账号">
  </div>
  <div class="form-group">
	<label for="exampleInputPassword1">用户名称</label>
	<input type="text" class="form-control" id="username" value="${user.username }" placeholder="请输入用户名称">
  </div>
  <div class="form-group">
	<label for="exampleInputEmail1">邮箱地址</label>
	<input type="email" class="form-control" id="email" value="${user.email }" placeholder="请输入邮箱地址">
	<p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p>
  </div>
  <button id="updateBtn" type="button" class="btn btn-success"><i class="glyphicon glyphicon-pencil"></i> 修改</button>
  <button type="resetBtn" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
</form>

 js:

//重置
$("#resetBtn").click(function(){
	//jq ==> dom(jq没有这个方法,所以做处理)
	//dom ==>jq $(dom)就可以转为jq对象
	$("userForm")[0].reset();
})

$("#updateBtn").click(function(){		  
	var loginacct=$("#loginacct").val();
	if(loginacct==""){
		layer.msg("登陆账号不能为空", {time:2000, icon:5, shift:6}, function(){
		});
		return;
	}
	var loadingIndex=null;
	$.ajax({
		type:"post",
		url :"${APP_PATH}/user/update",
		data:{
			"loginacct":loginacct,
			"username" :$("#username").val(),
			"email"    :$("#email").val(),
			"id"	   :"${user.id}"
		},
		beforeSend:function(){
			loadingIndex=layer.msg("处理中",{icon:16});
		},
		success:function(result){
			layer.close(loadingIndex);
			if(result.success){
				layer.msg("用户信息修改成功", {time:2000, icon:6}, function(){
					window.location.href="${APP_PATH}/user/index"
				});
			}
			else{
				layer.msg("用户信息修改失败,请重新操作", {time:2000, icon:5, shift:6}, function(){
				});
			}
		}
	})
})	

 java:

@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;
}

dao:

public void updateUser(User user);

mapper-user.xml:

<update id="updateUser">
	update t_user
	set loginacct=#{loginacct},username=#{username},email=#{email}
	where id=#{id}
</update>

9. 删除用户

9.1 单个删除

js:

function deleteUser(id,loginacct){
	layer.confirm("删除用户信息【"+loginacct+"】,是否继续",  {icon: 3, title:'提示'}, function(cindex){
	    //删除用户信息
	    $.ajax({
	    	type:"post",
	    	url :"${APP_PATH}/user/delete",
	    	data:{id:id},
	    	success:function(result){
	    		if(result.success){
	    			pageQuery(1);
	    		}else{
	    			layer.msg("用户信息删除失败", {time:2000, icon:5, shift:6}, function(){
        			});
	    		}
	    	}
	    })
		layer.close(cindex);
	}, function(cindex){
	    layer.close(cindex);
	});
}

java:

// 删除单个
@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;
}

dao:

public void deleteUserById(Integer id);

mapper-user.xml:

<delete id="deleteUserById">
	delete from t_user where id=#{id}
</delete>

9.2 批量删除

全选的html:

<th width="30"><input type="checkbox" id="allSelBox"></th>

原来的index.jsp的启动js新增代码,选定所有用户: 

$(function () {
    $("#allSelBox").click(function(){
	    var flg=this.checked;
	    $("#userData :checkbox").each(function(){
		    this.checked=flg;			    			
	    })
    })

js:

//批量删除
function deleteUsers(){
	var boxes=$("#userData :checkbox");
	if (boxes.length==0) {
		layer.msg("请选择需要删除的信息", {time:2000, icon:5, shift:6}, function(){});
	}else{
		layer.confirm("删除所选的用户信息,是否继续",  {icon: 3, title:'提示'}, function(cindex){
	    //删除用户信息
	    $.ajax({
	    	type:"post",
	    	url :"${APP_PATH}/user/deletes",
	    	data:$("#userForm").serialize(),
	    	success:function(result){
	    		if(result.success){
	    			pageQuery(1);
	    		}else{
	    			layer.msg("用户信息删除失败", {time:2000, icon:5, shift:6}, function(){
        			});
	    		}
	    	}
	    })
		layer.close(cindex);
	}, function(cindex){
	    layer.close(cindex);
	});
	}
}

java:

// 批量删除
@ResponseBody
@RequestMapping("/deletes")
public Object deletes(Integer[] userid) {
	AJAXResult result = new AJAXResult();
	try {
		Map<String, Object> map = new HashMap<>();
		map.put("userids", userid);
		userService.deleteUsers(map);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}

dao:

public void deleteUsers(Map<String, Object> map);

mapper-user.xml:

<delete id="deleteUsers">
	delete from t_user where id in
	<foreach collection="userids" item="userid" open="(" close=")" separator=",">
	#{userid}
	</foreach>
</delete>

10. 角色分配功能

仿造user建立role

bean:

public class Role {

	private Integer id;
	private String name;

实现index.jsp的最后一个按钮功能

js:

//分配角色
function goAssignPage(id){
	window.location.href="${APP_PATH}/user/assign?id="+id;
}

java:

// 分配页面
@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<>();
	List<Role> unassingRoles=new ArrayList<>();
	//获取关系表数据
	List<Integer> roleids=userService.queryRoleidsByUserid(id);
	for(Role role:roles){
		if(roleids.contains(role.getId())){
			assingedRoles.add(role);
		}else{
			unassingRoles.add(role);
		}
	}
	
	model.addAttribute("assingedRoles",assingedRoles);
	model.addAttribute("unassingRoles",unassingRoles);
	return "user/assign";
}

dao:

@Select("select roleid from t_user_role where userid=#{userid}")
public List<Integer> queryRoleidsByUserid(Integer id);

user新建assgin.jsp

html:

<form id="roleForm" role="form" class="form-inline">
  <input type="hidden" name="userid" value="${user.id}">
  <div class="form-group">
	<label for="exampleInputPassword1">未分配角色列表</label><br>
	<select id="leftList" name="unassignroleids" class="form-control" multiple size="10" style="width:200px;overflow-y:auto;">                      
        <c:forEach items="${unassingRoles}" var="role">
        	<option value="${role.id}">${role.name}</option>
        </c:forEach>
       
    </select>
  </div>
  <div class="form-group">
        <ul>
            <li id="left2RightBtn" class="btn btn-default glyphicon glyphicon-chevron-right"></li>
            <br>
            <li id="right2LeftBtn" class="btn btn-default glyphicon glyphicon-chevron-left" style="margin-top:20px;"></li>
        </ul>
  </div>
  <div class="form-group" style="margin-left:40px;">
	<label for="exampleInputPassword1">已分配角色列表</label><br>
	<select id="rightList" name="assignroleids" class="form-control" multiple size="10" style="width:200px;overflow-y:auto;">
      	<c:forEach items="${assingedRoles}" var="role">
        	<option value="${role.id}">${role.name}</option>
        </c:forEach>
    </select>
  </div>
</form>

js:

$(function () {
$(".list-group-item").click(function(){
    if ( $(this).find("ul") ) {
		$(this).toggleClass("tree-closed");
		if ( $(this).hasClass("tree-closed") ) {
			$("ul", this).hide("fast");
		} else {
			$("ul", this).show("fast");
		}
	}
});
$("#left2RightBtn").click(function(){
	var opts=$("#leftList :selected");
	if(opts.length==0){
		layer.msg("请选择需要分配的角色数据", {time:1000, icon:5, shift:6}, function(){
		});			    		
	}else{
		$.ajax({
			type:"post",
			url :"${APP_PATH}/user/doAssign",
			data:$("#roleForm").serialize(),
			success:function(result){
				if(result.success){
					 $("#rightList").append(opts);
					layer.msg("分配角色数据成功", {time:1000, icon:6}, function(){
					});
				}else{
					layer.msg("分配角色数据失败", {time:1000, icon:5, shift:6}, function(){
					});
				}
			}
		});		    		
	}
})
$("#right2LeftBtn").click(function(){
	var opts=$("#rightList :selected");
	if(opts.length==0){
		layer.msg("请选择需要分配的角色数据", {time:1200, icon:5, shift:6}, function(){
		});
	}else{
		$.ajax({
			type:"post",
			url :"${APP_PATH}/user/dounAssign",
			data:$("#roleForm").serialize(),
			success:function(result){
				if(result.success){
					 $("#leftList").append(opts);
					layer.msg("取消分配角色数据成功", {time:1000, icon:6}, function(){
					});
				}else{
					layer.msg("取消分配角色数据失败", {time:1000, icon:5, shift:6}, function(){
					});
				}
			}
		});		    		
	}
})
});

java:

//增加关系表的数据
@ResponseBody
@RequestMapping("/doAssign")
public Object doAssign(Integer userid,Integer[] unassignroleids) {
	AJAXResult result = new AJAXResult();
	try {
		Map<String, Object> map = new HashMap<>();
		map.put("userid", userid);
		map.put("roleids", unassignroleids);
		userService.insertUserRoles(map);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}
//删除关系表的数据
@ResponseBody
@RequestMapping("/dounAssign")
public Object dounAssign(Integer userid,Integer[] assignroleids) {
	AJAXResult result = new AJAXResult();
	try {
		Map<String, Object> map = new HashMap<>();
		map.put("userid", userid);
		map.put("roleids", assignroleids);
		userService.deleteUserRoles(map);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}	

dao:

public void deleteUserRoles(Map<String, Object> map);

public void insertUserRoles(Map<String, Object> map);

mapper-user.xml:

<insert id="insertUserRoles">
	insert into t_user_role (userid,roleid) values 
	<foreach collection="roleids" item="roleid" separator=",">
	(#{userid}, #{roleid})
	</foreach>
</insert>

<delete id="deleteUserRoles">
	delete from t_user_role where userid=#{userid} and roleid in
	<foreach collection="roleids" item="roleid" open="(" close=")" separator=",">
	#{roleid}
	</foreach>
</delete>

t_user_role:

  1. id 自身id
  2. userid 用户(t_user)id
  3. roleid 分配的t_role的id,数值表示可执行对应id的功能

userid对roleid表现为1对n

11. 树形菜单

bean:

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>();

对应的html添加按钮点击链接...

java:

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

仿造user新建permission

html:

<link rel="stylesheet" href="${APP_PATH}/ztree/zTreeStyle.css">
<script src="${APP_PATH}/ztree/jquery.ztree.all-3.5.min.js"></script>
<ul id="permissionTree" class="ztree"></ul>
<!-- 节点数据 -->

js:

$(function () {
    $(".list-group-item").click(function(){
	    if ( $(this).find("ul") ) {
			$(this).toggleClass("tree-closed");
			if ( $(this).hasClass("tree-closed") ) {
				$("ul", this).hide("fast");
			} else {
				$("ul", this).show("fast");
			}
		}
	});
    var setting={
    	//使用ajax
    	async:{
    		//设为true,开启异步加载
    		enable:true,
    		url   :"${APP_PATH}/permission/loadData",
    		autoParam:["id","name=n","level=lv"]
    	},
    	view: {
    		//不支持 同时选中多个节点
			selectedMulti: false,
			addDiyDom: function(treeId, treeNode){
				//icoObj表示取得icon的id
				var icoObj = $("#" + treeNode.tId + "_ico"); // tId = permissionTree_1, $("#permissionTree_1_ico")
				//用数据库设置的图标
				if ( treeNode.icon ) {
					//替换节点图标,css(str1,str2),以str2代替str1
					icoObj.removeClass("button ico_docu ico_open").addClass(treeNode.icon).css("background","");
				}
                
			},
			//增加节点菜单以及后面的按钮
			addHoverDom: function(treeId, treeNode){  
				var aObj = $("#" + treeNode.tId + "_a"); // tId = permissionTree_1, ==> $("#permissionTree_1_a")
				aObj.attr("href", "javascript:;");
				//editNameFlag记录节点是否处于编辑名称状态
				if (treeNode.editNameFlag || $("#btnGroup"+treeNode.tId).length>0) return;
				//tId为ztree内置id,ztree自动设置,一般是不同模块从1开始的数字
				var s = '<span id="btnGroup'+treeNode.tId+'">';
				//level记录节点的层级,根节点 level = 0,依次递增
				if ( treeNode.level == 0 ) {
					s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="addNode('+treeNode.id+')" href="#" >&nbsp;&nbsp;<i class="fa fa-fw fa-plus rbg "></i></a>';
				} else if ( treeNode.level == 1 ) {
					s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="editNode('+treeNode.id+')" href="#" title="修改权限信息">&nbsp;&nbsp;<i class="fa fa-fw fa-edit rbg "></i></a>';
					if (treeNode.children.length == 0) {
						s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="deleteNode('+treeNode.id+')" href="#" >&nbsp;&nbsp;<i class="fa fa-fw fa-times rbg "></i></a>';
					}
					s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="addNode('+treeNode.id+')" href="#" >&nbsp;&nbsp;<i class="fa fa-fw fa-plus rbg "></i></a>';
				} else if ( treeNode.level == 2 ) {
					s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="editNode('+treeNode.id+')" href="#" title="修改权限信息">&nbsp;&nbsp;<i class="fa fa-fw fa-edit rbg "></i></a>';
					s += '<a class="btn btn-info dropdown-toggle btn-xs" style="margin-left:10px;padding-top:0px;" onclick="deleteNode('+treeNode.id+')" href="#">&nbsp;&nbsp;<i class="fa fa-fw fa-times rbg "></i></a>';
				}

				s += '</span>';
				//将不同的按钮根据判定显示在不同节点菜单后面
				aObj.after(s);
			},
			//当鼠标移出节点时,隐藏用户自定义控件
			removeHoverDom: function(treeId, treeNode){
				$("#btnGroup"+treeNode.tId).remove();
			}
		},
    };
  
	//异步获取数据,zTree的初始化调用方法
    $.fn.zTree.init($("#permissionTree"),setting);
});

java:

@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){	
	//对数据库的存储顺序有要求
	List<Permission> permissions=new ArrayList<>();
	//查询所有数据
	List<Permission> ps=permissionService.queryAll();
	//根据索引查询
	Map<Integer, Permission> permissionMap=new HashMap<>();
	//装入map,为了用索引查询提高效率
	for(Permission p:ps){
		permissionMap.put(p.getId(), p);
	}
	for ( Permission p : ps ) {
		if ( p.getPid() == 0 ) {
			permissions.add(p);
		} else {
			//根据子节点的pid查出父节点
			Permission parent=permissionMap.get(p.getPid());
			//父节点添加子节点
			parent.getChildren().add((p));
		}
	}
	return permissions;		
}

sql:

 dao:

@Select("select * from t_permission")
public List<Permission> queryAll();

12. 菜单功能

js:

function addNode(id){
	window.location.href="${APP_PATH}/permission/add?id="+id;
}    
function editNode(id){
	window.location.href="${APP_PATH}/permission/edit?id="+id;
}  
function deleteNode(id){
	layer.confirm("删除所选的许可信息,是否继续",  {icon: 3, title:'提示'}, function(cindex){
	    //删除用户信息
	    $.ajax({
	    	type:"post",
	    	url :"${APP_PATH}/permission/delete",
	    	data:{
	    		id:id
	    	},
	    	success:function(result){
	    		if(result.success){
	    			//刷新数据
	    			var treeObj=$.fn.zTree.getZTreeObj("permissionTree");
	    			treeObj.reAsyncChildNodes(null,"refresh");
	    		}else{
	    			layer.msg("许可信息删除失败", {time:2000, icon:5, shift:6}, function(){
        			});
	    		}
	    	}
	    })
		layer.close(cindex);
	}, function(cindex){
	    layer.close(cindex);
	});
}     

java:

@ResponseBody
@RequestMapping("/delete")
public Object delete(Permission permission){
	AJAXResult result=new AJAXResult();
	try {
		permissionService.deletePermission(permission);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}

@ResponseBody
@RequestMapping("/update")
public Object update(Permission permission){
	AJAXResult result=new AJAXResult();
	try {
		permissionService.updatePermission(permission);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}

@RequestMapping("/edit")
public String edit(Integer id,Model model){
	Permission permission=permissionService.queryById(id);
	model.addAttribute("permission",permission);
	return "permission/edit";
}

@ResponseBody
@RequestMapping("/insert")
public Object insert(Permission permission){
	AJAXResult result=new AJAXResult();
	try {
		permissionService.insertPermission(permission);
		result.setSuccess(true);
	} catch (Exception e) {
		e.printStackTrace();
		result.setSuccess(false);
	}
	return result;
}

其他代码略...

13. 角色分配功能

13.1 分配角色

role下新建assgin.jsp(拷贝permission下的index.jsp修改)

html:

<div class="panel-body">
	<button class="btn btn-success" onclick="doAssign()">分配许可</button>
	<ul id="permissionTree" class="ztree"></ul>
</div>

js:

function doAssign(){
	var treeObj=$.fn.zTree.getZTreeObj("permissionTree");
	var nodes=treeObj.getCheckedNodes(true);
	if(nodes.length==0){
		layer.msg("请选择要分配的许可信息", {time:2000, icon:5, shift:6}, function(){
		});
	}else{
		var d="roleid=${param.id}";
		$.each(nodes,function(i,node){
			d+="&permissionids="+node.id
		});
		$.ajax({
			type:"post",
			url :"${APP_PATH}/role/doAssign",
			data:d,
			success:function(result){
				if(result){
					layer.msg("许可信息分配成功", {time:1000, icon:6}, function(){
        			});
				}else{
					layer.msg("许可信息分配失败", {time:1200, icon:5, shift:6}, function(){
        			});
				}						
			}						
		})
	}
}

java:

@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){	
	//对数据库的存储顺序有要求
	List<Permission> permissions=new ArrayList<>();
	//查询所有数据
	List<Permission> ps=permissionService.queryAll();
	//根据索引查询
	Map<Integer, Permission> permissionMap=new HashMap<>();
	//装入map,为了用索引查询提高效率
	for(Permission p:ps){
		permissionMap.put(p.getId(), p);
	}
	for ( Permission p : ps ) {
		if ( p.getPid() == 0 ) {
			permissions.add(p);
		} else {
			//根据子节点的pid查出父节点
			Permission parent=permissionMap.get(p.getPid());
			//父节点添加子节点
			parent.getChildren().add((p));
		}
	}
	return permissions;		
}

dao:

@Select("select * from t_permission")
public List<Permission> queryAll();

13.2 显示已分配角色

回到role的index.jsp

js:

function goAssignPage(id){
	window.location.href="${APP_PATH}/role/assign?id="+id;
}

java:

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

js:

$(function () {
    $(".list-group-item").click(function(){
	    if ( $(this).find("ul") ) {
			$(this).toggleClass("tree-closed");
			if ( $(this).hasClass("tree-closed") ) {
				$("ul", this).hide("fast");
			} else {
				$("ul", this).show("fast");
			}
		}
	});
    var setting={
    		//启用复选框
    		check:{
    			enable:true
    		},
    	async:{
    		enable:true,
    		url   :"${APP_PATH}/permission/loadAssignData?roleid=${param.id}",
    		autoParam:["id","name=n","level=lv"]
    	},
    	view: {
			selectedMulti: false,
			addDiyDom: function(treeId, treeNode){
				var icoObj = $("#" + treeNode.tId + "_ico"); // tId = permissionTree_1, $("#permissionTree_1_ico")
				if ( treeNode.icon ) {
					icoObj.removeClass("button ico_docu ico_open").addClass(treeNode.icon).css("background","");
				}
                
			},
			
		},
    };
	//异步获取数据
    $.fn.zTree.init($("#permissionTree"),setting);
});

java:

@ResponseBody
@RequestMapping("/loadAssignData")
public Object loadAssignData(Integer roleid){	
	List<Permission> permissions = new ArrayList<>();
	List<Permission> ps = permissionService.queryAll();
	//获取当前角色已经分配的许可信息
	List<Integer> permissionids=permissionService.queryPermissionidsByRoleid(roleid);
	for(Permission p:ps){
		if(permissionids.contains(p.getId())){
			p.setChecked(true);
		}else{
			p.setChecked(false);
		}
	}
	Map<Integer, Permission> permissionMap = new HashMap<>();
	for (Permission p : ps) {
		permissionMap.put(p.getId(), p);
	}
	for (Permission p : ps) {
		if (p.getPid() == 0) {
			permissions.add(p);
		} else {
			Permission parent = permissionMap.get(p.getPid());
			parent.getChildren().add((p));
		}
	}
	return permissions;	
}

dao:

@Select("select permissionid from t_role_permission where roleid=#{roleid}")
public List<Integer> queryPermissionidsByRoleid(Integer roleid);

14. 用户权限

DispatherController.java进行更改

java:

@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;

@ResponseBody
@RequestMapping("/doAJAXLogin")
public Object doAJAXLogin(User user,HttpSession session) {
	AJAXResult result=new AJAXResult();
	User dbUser=userService.query4Login(user);
	if (dbUser!=null) {
		session.setAttribute("loginUser",dbUser);
		//获取用户的权限信息
		List<Permission> permissions = permissionService.queryPermissionsByUser(dbUser);
		Map<Integer, Permission> permissionMap=new HashMap<>();
		Permission root=null;
		for (Permission permission:permissions) {
			Permission child=permission;
			if (child.getPid()==0) {
				root=permission;
			}else{
				Permission parent = permissionMap.get(child.getPid());
				parent.getChildren().add(child);
			}
		}
		session.setAttribute("rootPermission", root);
		result.setSuccess(true);		
	}else{
		result.setSuccess(false);
	}
	return result;
}

dao:

public List<Permission> queryPermissionsByUser(User dbUser);

mapper-permission.xml:

<!-- 根据用户的id查询用户角色表查出(根据)担任的所有角色id查询角色权限表查出(根据)所有权限id查询权限表查出权限的所有菜单信息 -->
<select id="queryPermissionsByUser" resultType="cn.itcast.ssmIntegration.bean.Permission">
	select * from t_permission where id 
	in(
	  select permissionid from t_role_permission where roleid 
	  in(
	  	select roleid from t_user_role where userid=#{id}
	  )
	)
</select>

抽象出菜单的html

html:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<ul style="padding-left: 0px;" class="list-group">
	<c:forEach items="${rootPermission.children}" var="permission">
	<c:if test="${empty permission.children}">
	<li class="list-group-item tree-closed"><a
		href="${APP_PATH}${permission.url}"><i
		class="${permission.icon }"></i>${permission.name}</a></li>
	</c:if>
	<c:if test="${not empty permission.children}">
	<li class="list-group-item tree-closed"><span><i
		class="${permission.icon}"></i> ${permission.name} <span
		class="badge" style="float: right">${permission.children.size()}</span></span>
		<ul style="margin-top: 10px; display: none;">				
			<c:forEach items="${permission.children}" var="child">
			<li style="height: 30px;"><a href="${APP_PATH}${child.url}"><i
				class="${child.icon}"></i> ${child.name}</a></li>
			</c:forEach>
		</ul>
	</li>
</c:if>
</c:forEach>
</ul>

15. 拦截器

15.1 登陆拦截器

LoginInterceptor.java:

public class LoginInterceptor implements HandlerInterceptor {

/**
 * 在控制器之前完成业务逻辑操作
 * 方法的返回值决定逻辑是否继续执行,true表示执行,false表示不执行
 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
	HttpSession session=request.getSession();
	User loginUser=(User) session.getAttribute("loginUser");
	
	if (loginUser==null) {
		String path=session.getServletContext().getContextPath();
		response.sendRedirect(path+"/login");
		return false;
	}else{
		return true;
	}
}

springmvc.xml:

<!-- 配置拦截器 -->
<mvc:interceptors>
	<!-- 配置多个拦截器 顺序执行 -->
	<mvc:interceptor>
		<!-- /** 是拦截所有的文件夹及里面的子文件夹 -->
		<mvc:mapping path="/**" />
		<!-- 不拦截静态资源 -->
		<mvc:exclude-mapping path="/login" />
		<mvc:exclude-mapping path="/doAJAXLogin" />
		<mvc:exclude-mapping path="/bootstrap/**" />
		<mvc:exclude-mapping path="/css/**" />
		<mvc:exclude-mapping path="/fonts/**" />
		<mvc:exclude-mapping path="/img/**" />
		<mvc:exclude-mapping path="/jquery/**" />
		<mvc:exclude-mapping path="/layer/**" />
		<mvc:exclude-mapping path="/script/**" />
		<mvc:exclude-mapping path="/ztree/**" />
		<bean class="cn.itcast.ssmIntegration.web.LoginInterceptor"></bean>
	</mvc:interceptor>
</mvc:interceptors>

15.2 权限拦截器

需要权限验证信息,在doAJAXLogin方法中新增

java:

for (Permission permission:permissions) {
	permissionMap.put(permission.getId(), permission);
	if (permission.getUrl()!=null&&!"".equals(permission.getUrl())) {
		//设置访问路径
		uriSet.add(session.getServletContext().getContextPath()+permission.getUrl());
	}
}
session.setAttribute("authUriSet", uriSet);

新建拦截器

java:

public class AuthInterceptor implements HandlerInterceptor {

@Autowired
private PermissionService permissionService;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
	//获取请求地址
	String uri=request.getRequestURI();
	String path=request.getSession().getServletContext().getContextPath();
	//判断当前路径是否需要权限验证
	//查询所有需要验证的路径集合
	List<Permission> permissions=permissionService.queryAll();
	Set<String> uriSet=new HashSet<>();
	for(Permission permission:permissions){
		if (permission.getUrl()!=null&&!"".equals(permission.getUrl())) {
			uriSet.add(path+permission.getUrl());
		}
	}
	if (uriSet.contains(uri)) {
		//权限验证
		//判断当前用户是由拥有对应的权限
		Set<String> authUriSet=(Set<String>) request.getSession().getAttribute("authUriSet");
		if (authUriSet.contains(uri)) {
			return true;
		}else{
			response.sendRedirect(path+"/error");
			return false;
		}
	}else{
		return true;
	}	
}

springmvc.xml:

<mvc:interceptor>
	<mvc:mapping path="/**" />
	<mvc:exclude-mapping path="/login" />
	<mvc:exclude-mapping path="/doAJAXLogin" />
	<mvc:exclude-mapping path="/bootstrap/**" />
	<mvc:exclude-mapping path="/css/**" />
	<mvc:exclude-mapping path="/fonts/**" />
	<mvc:exclude-mapping path="/img/**" />
	<mvc:exclude-mapping path="/jquery/**" />
	<mvc:exclude-mapping path="/layer/**" />
	<mvc:exclude-mapping path="/script/**" />
	<mvc:exclude-mapping path="/ztree/**" />
	<bean class="cn.itcast.ssmIntegration.web.AuthInterceptor"></bean>
</mvc:interceptor>

非法访问,设置跳转到错误页面

error.jsp

完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值