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:
- id 自身id
- userid 使用者(t_user)id
- 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="#" > <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="修改許可權資訊"> <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="#" > <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="#" > <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="修改許可權資訊"> <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="#"> <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代碼和參數的手工設置以及結果集的... 摘要: