1. 程式人生 > >SSM框架的RBAC許可權實戰

SSM框架的RBAC許可權實戰

密碼:vpt2

實際內容大概如下:

目錄

1. 專案結構

parent設為pom,做管理層

common設為jar,做持久層

manager設為jar,做控制層

web設為war,做顯示層

2. 環境配置

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">請輸入合法的郵箱地址, 格式為: [email protected]</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">請輸入合法的郵箱地址, 格式為: [email protected]</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

完!

相關推薦

SSM框架RBAC許可權實戰

密碼:vpt2 實際內容大概如下: 目錄 1. 專案結構 parent設為pom,做管理層 common設為jar,做持久層 manager設為jar,

IDEA基於Spring Cloud Netflix(2.1.0RC3)的Spring Cloud Eureka來實現服務治理的微服務架構搭建以及和SSM框架的整合——實戰教程

這裡開始spring cloud微服務架構搭建,用的maven還是之前自己的本地安裝的,repository倉庫也是本地的。 在搭建專案框架之前先簡單學習一下spring cloud。 Spring Cloud 簡介        Spring

[20]Java實戰項目教程 Java購物項目 最新SSM框架 服務端教程[2.2G]

image aid bdc lan png SSM框架 font java blog 視頻試看鏈接:https://pan.baidu.com/s/1skRge4l 淘寶鏈接:https://item.taobao.com/item.htm?spm=0.7095261.0

基於SSM的POI導入導出Excel實戰第一篇-SSM框架的整合

lib 三層 下載 童鞋 框架 excel alt 第三方 新建 業務背景:在JavaWeb應用開發中,經常需要將應用系統中某些業務數據導出到Excel中,又或者需要將這些業務數據先收集到Excel然後一鍵導入到系統 業務需求:如何用Java實現導入導出Excel 需求分析

SSM框架整合Apache Shiro,實現安全登入驗證和許可權驗證功能

第一部分 Apache Shiro的簡介  1、什麼是 apache shiro : Apache Shiro是一個功能強大且易於使用的Java安全框架,提供了認證,授權,加密,和會話管理 如同 spring security 一樣都是是一個許可權安全框架,但是與Spri

MyBatis實戰之對映器 SSM框架之批量增加示例(同步請求jsp檢視解析) mybatis的批量更新例項 造成MySQL全表掃描的原因 SSM框架實戰之整合EhCache

對映器是MyBatis最強大的工具,也是我們使用MyBatis時用得最多的工具,因此熟練掌握它十分必要。MyBatis是針對對映器構造的SQL構建的輕量級框架,並且通過配置生成對應的JavaBean返回給呼叫者,而這些配置主要便是對映器,在MyBatis中你可以根據情況定義動態SQL來滿足不同場景的需要,它比

java實現動態許可權(選單管理)動態新增選單,動態新增角色SSM框架

首先是資料庫設計 Menu表(選單表) Role表(角色表) Role_Menu表(角色選單關係表) User表(使用者表) User_Role表(使用者角色關係表) 其他實體類就略過了 在Menu實體類中添加了一個List<Menu&

SSM框架實戰之整合EhCache

<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/PO

企業級許可權管理系統ssm框架

        最近做了一套Java開發企業級許可權管理系統,搭建起了框架,實現許可權管理,介紹如下,供參考。 手把手原生實現一套許可權管理系統          

RBAC許可權模型——專案實戰

一、前言     許可權一句話來理解就是對資源的控制,對web應用來說就是對url的控制,關於許可權可以毫不客氣的說幾乎每個系統都會包含,只不過不同系統關於許可權的應用複雜程式不一樣而已,現在我們在用的許可權模型基本上都是以RBAC為基礎進行擴充套件的,我們今天就將RBA

SSM框架搭建及專案實戰

(可通過圖片水印檢視部落格地址) 1、基本概念 1.1、Spring         Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著作Expert One

SSM框架整合ElasticSearch實現資料的增刪改查實戰案例

前言:      當資料量過大幾十萬或者上百萬條資料或者億萬條時,單純的mysql oracle 以及sql查詢已經無法滿足我們在效率上的需求,elasticSearch 是當下一款熱門的實時搜尋引擎基於lucense的搜尋伺服器,使用它可以完成近乎實時的資料查詢。 目錄

shiro許可權控制(一):shiro介紹以及整合SSM框架

 shiro安全框架是目前為止作為登入註冊最常用的框架,因為它十分的強大簡單,提供了認證、授權、加密和會話管理等功能 。  shiro能做什麼?       認證:驗證使用者的身份       授權:對使用者執行訪問控制:判斷使用者是否被允許做某事       會話管理:在任

基於SSM框架許可權系統的開發

有bug請在評論區留言 這是個十分簡單的許可權實現,後端採用SSM框架,前段展示層使用ztree(ztree官網),實現控制則使用jsp自定義的判斷標籤; 第一步:新建power資料庫。 使用者表user,權利表power,使用者-權利關係表userPower, /*

RBAC許可權框架_MVC許可權框架

RBAC許可權框架(Role-Based Access Control)基於角色的許可權訪問控制的框架,通過使用者-角色-許可權的關聯,非常方便的進行許可權管理,在這裡不再說明什麼是RBAC,請自行百度. 謝謝大家的捧場,如文章中有錯誤或者,請聯絡我或者給我發郵件[email protected],修正

java SSM 框架 多數據源 代碼生成器 websocket即時通訊 shiro redis 後臺框架源碼

sql編輯器 quartz 自定義表單 SSM springmvc 獲取【下載地址】 QQ: 313596790 官網 http://www.fhadmin.org/ A 調用攝像頭拍照,自定義裁剪編輯頭像,頭像圖片色度調節 B 集成代碼生成器 [正反雙向](單表、主表、明細

java SSM 框架 代碼生成器 websocket 即時通訊 shiro redis 多數據源 後臺框架源碼

idt 下載到本地 exp 綁定 鏈接 數據庫連接池 展示 地圖工具 重排序 A 調用攝像頭拍照,自定義裁剪編輯頭像,頭像圖片色度調節B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemaker模版技術 ,0個代碼不用寫,

java企業站源碼 響應式 兼容手機平板PC 主流SSM 框架 freemaker 靜態引擎

oom bsp dxf col 我們 前後臺 ext 欄目 family java 企業網站源碼 前後臺都有 靜態模版引擎, 代碼生成器大大提高開發效率 前臺: 支持三套模版, 可以在後臺切換 系統介紹: 1.網站後臺采用主流的 SSM 框架 jsp JSTL,網站後臺采

java SSM框架 多數據源 代碼生成器 websocket即時通訊 shiro redis 後臺框架源碼

sql編輯器 quartz 自定義表單 springmvc ssm 獲取【下載地址】 QQ: 313596790官網 http://www.fhadmin.org/A 調用攝像頭拍照,自定義裁剪編輯頭像,頭像圖片色度調節B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速

SSM框架Spring+SpringMVC+MyBatis——詳細整合教程

servle aps files framework l數據庫 建立 blank onf pin 摘要: 包括SQL Maps和Data Access Objects(DAO)MyBatis 消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的... 摘要: