Day05_企业权限管理(SSM整合)
学于黑马程序员和传智播客联合做的教学项目 感谢
黑马程序员官网
传智播客官网
个人根据教程的每天的工作进度的代码和资料 密码:cti5
b站在线视频
微信搜索"艺术行者",关注并回复关键词"企业权限管理"获取视频和教程资料!
第五天
- 权限关联与控制
- AOP日志
实现用户—角色关联
实现查询用户-角色
将用户添加的功能提前实现
-
在user-list.jsp添加链接
-
<a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a>
-
-
导入user-role-add.jsp页面
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 用户管理 <small>添加角色表单</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li> <li class="active">添加角色表单</li> </ol> </section> <!-- 内容头部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文区域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名称</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--订单信息/--> <!--工具栏--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具栏/--> </section> <!-- 正文区域 /--> </form> </div> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">项目练习</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全选操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
编写Controller模块代码
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 用户管理 <small>添加角色表单</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li> <li class="active">添加角色表单</li> </ol> </section> <!-- 内容头部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文区域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名称</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--订单信息/--> <!--工具栏--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具栏/--> </section> <!-- 正文区域 /--> </form> </div> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">项目练习</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全选操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
编写sevice模块代码
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.security.core.userdetails.UserDetailsService; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ public interface IUserService extends UserDetailsService { List<UserInfo> findAll(); UserInfo findById(String userId); List<Role> findOtherRoles(String userId); void save(UserInfo userInfo); }
-
-
实现类
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IUserDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ @Service("userService") @Transactional public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = null; try { userInfo = userDao.findByUsername(username); } catch (Exception e) { e.printStackTrace(); } List<Role> roles = userInfo.getRoles(); //处理自己的用户对象封装成UserDetails User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(roles)); return user; } //作用就是返回一个List集合,集合中装入的是权限描述 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) { List<SimpleGrantedAuthority> list = new ArrayList<>(); for (Role role : roles) { list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName())); } return list; } @Override public List<UserInfo> findAll() { return userDao.findAll(); } //根据ID查询用户的信息 @Override public UserInfo findById(String userId) { return userDao.findById(userId); } //返回用户未添加的角色 @Override public List<Role> findOtherRoles(String userId) { return userDao.findOtherRoles(userId); } @Override public void save(UserInfo userInfo) { userDao.save(userInfo); } }
-
-
-
编写dao模块代码
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.stereotype.Service; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:41 */ public interface IUserDao { @Select("select * from users where username=#{username}") @Results({ @Result(property = "roles", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IRoleDao.findRoleByUserId")) }) public UserInfo findByUsername(String username) throws Exception; @Select("select * from users") List<UserInfo> findAll(); @Select("select * from users where id=#{userId}") UserInfo findById(String userId); @Select("select * from role where id is not in (select roleId from users_role where userId=#{userId})") List<Role> findOtherRoles(String userId); @Insert("insert into users(email,username,password,phoneNum,status) values(#{email},#{username},#{password},#{phoneNum},#{status})") void save(UserInfo userInfo); }
-
@RequestMapingParam 前端参数和方法参数对应
@Param 方法参数和注解参数对应
- 结果
给用户添加角色
-
导入user-role-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 用户管理 <small>添加角色表单</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li> <li class="active">添加角色表单</li> </ol> </section> <!-- 内容头部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文区域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名称</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--订单信息/--> <!--工具栏--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具栏/--> </section> <!-- 正文区域 /--> </form> </div> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">项目练习</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全选操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
UserContoler添加代码
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:55 */ @Service @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; //查询所有用户 @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<UserInfo> userList = userService.findAll(); mv.addObject("userList", userList); mv.setViewName("user-list"); return mv; } //查询用户以及用户可以添加的角色 @RequestMapping("/findUserByIdAndAllRole.do") public ModelAndView findUserByIdAndAllRole(@RequestParam(name = "id", required = true) String userId) { ModelAndView mv = new ModelAndView(); //根据用户id查询用户 UserInfo userInfo = userService.findById(userId); //根据用户id查询可以添加的角色 List<Role> otherRoles = userService.findOtherRoles(userId); mv.addObject("user", userInfo); mv.addObject("roleList", otherRoles); mv.setViewName("user-role-add"); return mv; } //用户添加 @RequestMapping("/save.do") public String save(UserInfo userInfo) throws Exception { userService.save(userInfo); return "redirect:findAll.do"; } //给用户添加角色 @RequestMapping("addRoleToUser.do") public String addRoleToUser(@RequestParam(name = "userId", required = true) String userId, @RequestParam(name = "ids", required = true) String[] roleIds) { userService.addRoleToUser(userId, roleIds); return "redirect:findAll.do"; } }
-
-
UserService模块添加代码
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.security.core.userdetails.UserDetailsService; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ public interface IUserService extends UserDetailsService { List<UserInfo> findAll(); UserInfo findById(String userId); List<Role> findOtherRoles(String userId); void save(UserInfo userInfo); void addRoleToUser(String userId, String[] roleIds); }
-
-
实现类
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IUserDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ @Service("userService") @Transactional public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = null; try { userInfo = userDao.findByUsername(username); } catch (Exception e) { e.printStackTrace(); } List<Role> roles = userInfo.getRoles(); //处理自己的用户对象封装成UserDetails User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(roles)); return user; } //作用就是返回一个List集合,集合中装入的是权限描述 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) { List<SimpleGrantedAuthority> list = new ArrayList<>(); for (Role role : roles) { list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName())); } return list; } @Override public List<UserInfo> findAll() { return userDao.findAll(); } //根据ID查询用户的信息 @Override public UserInfo findById(String userId) { return userDao.findById(userId); } //返回用户未添加的角色 @Override public List<Role> findOtherRoles(String userId) { return userDao.findOtherRoles(userId); } @Override public void save(UserInfo userInfo) { userDao.save(userInfo); } @Override public void addRoleToUser(String userId, String[] roleIds) { for (String roleId : roleIds) { userDao.addRoleToUser(userId, roleId); } } }
-
-
-
UserDao模块添加代码
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.stereotype.Service; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:41 */ public interface IUserDao { @Select("select * from users where username=#{username}") @Results({ @Result(property = "roles", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IRoleDao.findRoleByUserId")) }) public UserInfo findByUsername(String username) throws Exception; @Select("select * from users") List<UserInfo> findAll(); @Select("select * from users where id=#{userId}") UserInfo findById(String userId); @Select("select * from role where id not in (select roleId from users_role where userId=#{userId})") List<Role> findOtherRoles(String userId); @Insert("insert into users(email,username,password,phoneNum,status) values(#{email},#{username},#{password},#{phoneNum},#{status})") void save(UserInfo userInfo); @Insert("insert into users_role(userId, roleId) values (#{userId},#{roleId})") void addRoleToUser(@Param("userId") String userId, @Param("roleId") String roleId); }
-
注:此处需要到IRoleDao接口里添加findRoleById代码
@Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception;
- 结果
角色权限关联
和用户-角色关联差不多
展示权限
-
修改user-list页面成为role-list页面
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 用户管理 <small>全部用户</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li> <li class="active">全部用户</li> </ol> </section> <!-- 内容头部 /--> <!-- 正文区域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 数据表格 --> <div class="table-box"> <!--工具栏--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/user-add.jsp'"> <i class="fa fa-file-o"></i> 新建 </button> <button type="button" class="btn btn-default" title="刷新"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具栏/--> <!--数据列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"> </th> <th class="sorting_asc">ID</th> <th class="sorting_desc">用户名</th> <th class="sorting_asc sorting_asc_disabled">邮箱</th> <th class="sorting_desc sorting_desc_disabled">联系电话</th> <th class="sorting">状态</th> <th class="text-center">操作</th> </tr> </thead> <tbody> <c:forEach items="${userList}" var="user"> <tr> <td><input name="ids" type="checkbox"></td> <td>${user.id }</td> <td>${user.username }</td> <td>${user.email }</td> <td>${user.phoneNum }</td> <td>${user.statusStr }</td> <td class="text-center"> <a href="${pageContext.request.contextPath}/user/findById.do?id=${user.id}" class="btn bg-olive btn-xs">详情</a> <a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a> </td> </tr> </c:forEach> </tbody> <!-- <tfoot> <tr> <th>Rendering engine</th> <th>Browser</th> <th>Platform(s)</th> <th>Engine version</th> <th>CSS grade</th> </tr> </tfoot>--> </table> <!--数据列表/--> </div> <!-- 数据表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 总共2 页,共14 条数据。 每页 <select class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> 条 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首页</a></li> <li><a href="#">上一页</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一页</a></li> <li><a href="#" aria-label="Next">尾页</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文区域 /--> </div> <!-- @@close --> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="http://#">项目练习</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="../plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="../plugins/bootstrap/js/bootstrap.min.js"></script> <script src="../plugins/raphael/raphael-min.js"></script> <script src="../plugins/morris/morris.min.js"></script> <script src="../plugins/sparkline/jquery.sparkline.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="../plugins/knob/jquery.knob.js"></script> <script src="../plugins/daterangepicker/moment.min.js"></script> <script src="../plugins/daterangepicker/daterangepicker.js"></script> <script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="../plugins/datepicker/bootstrap-datepicker.js"></script> <script src="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="../plugins/fastclick/fastclick.js"></script> <script src="../plugins/iCheck/icheck.min.js"></script> <script src="../plugins/adminLTE/js/app.min.js"></script> <script src="../plugins/treeTable/jquery.treetable.js"></script> <script src="../plugins/select2/select2.full.min.js"></script> <script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="../plugins/bootstrap-markdown/js/markdown.js"></script> <script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="../plugins/ckeditor/ckeditor.js"></script> <script src="../plugins/input-mask/jquery.inputmask.js"></script> <script src="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="../plugins/datatables/jquery.dataTables.min.js"></script> <script src="../plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="../plugins/chartjs/Chart.min.js"></script> <script src="../plugins/flot/jquery.flot.min.js"></script> <script src="../plugins/flot/jquery.flot.resize.min.js"></script> <script src="../plugins/flot/jquery.flot.pie.min.js"></script> <script src="../plugins/flot/jquery.flot.categories.min.js"></script> <script src="../plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document) .ready( function() { // 激活导航位置 setSidebarActive("admin-datalist"); // 列表按钮 $("#dataList td input[type='checkbox']") .iCheck( { checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全选操作 $("#selall") .click( function() { var clicks = $(this).is( ':checked'); if (!clicks) { $( "#dataList td input[type='checkbox']") .iCheck( "uncheck"); } else { $( "#dataList td input[type='checkbox']") .iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
-
添加代码到RoleController模块
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:28 */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList", roleList); mv.setViewName("role-list"); return mv; } @RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; } @RequestMapping("/findRoleByIdAndAllPermission.do") public ModelAndView findRoleByIdAndAllPermission(@RequestParam(value = "id", required = true) String roleId) { ModelAndView mv = new ModelAndView(); //根据roleId查询role Role role = roleService.findById(roleId); //根据roleId查询可以添加的权限 List<Permission> permissionList = roleService.findOtherPermission(roleId); mv.addObject("role", role); mv.addObject("permissionList", permissionList); mv.setViewName("role-permission-add"); return mv; } }
-
-
添加代码到RoleService模块
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:32 */ public interface IRoleService { public List<Role> findAll(); void save(Role role); Role findById(String roleId); List<Permission> findOtherPermission(String roleId); }
-
-
实现类
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IRoleDao; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:33 */ @Service @Transactional public class RoleServiceImpl implements IRoleService { @Autowired private IRoleDao roleDao; @Override public List<Role> findAll() { return roleDao.findAll(); } @Override public void save(Role role) { roleDao.sava(role); } @Override public Role findById(String roleId) { return roleDao.findById(roleId); } @Override public List<Permission> findOtherPermission(String roleId) { return roleDao.findOtherPermission(roleId); } }
-
-
-
添加代码到RoleDao模块
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:43 */ public interface IRoleDao { //根据用户id查询出所有对应的权限 @Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception; @Select("select * from role") List<Role> findAll(); @Insert("insert into role(roleName, roleDesc) values (#{roleName},#{roleDesc})") void sava(Role role); @Select("select * from role where roleId = #{roleId}") @Results({ @Result(property = "permissions", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IPermissionDao.findPermissionByRoleId")) }) Role findById(String roleId); @Select("select * from permission where id not in (select permissionId from role_permission where roleId=#{roleId})") List<Permission> findOtherPermission(String roleId); }
-
-
结果
实现权限添加功能
-
修改user-role-add.jsp页面成为role-permission-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 角色管理 <small>添加权限表单</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li> <li class="active">添加权限表单</li> </ol> </section> <!-- 内容头部 /--> <form action="${pageContext.request.contextPath}/role/addPermissionToRole.do" method="post"> <!-- 正文区域 --> <section class="content"> <input type="hidden" name="roleId" value="${role.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">权限名称</th> <th class="sorting">权限描述</th> </tr> </thead> <tbody> <c:forEach items="${permissionList}" var="permission"> <tr> <td> <input name="ids" type="checkbox" value="${permission.id}"> </td> <td>${permission.id}</td> <td>${permission.permissionName }</td> <td>${permission.url}</td> </tr> </c:forEach> </tbody> </table> <!--订单信息/--> <!--工具栏--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具栏/--> </section> <!-- 正文区域 /--> </form> </div> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">项目练习</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全选操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
给RoleController模块添加代码
-
@RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; }
-
-
给RoleService模块添加代码
-
接口
-
void save(Role role);
-
-
实现类
-
@Override public void save(Role role) { roleDao.sava(role); }
-
-
-
给RoleDao模块添加代码
-
@Insert("insert into role(roleName, roleDesc) values (#{roleName},#{roleDesc})") void sava(Role role);
-
-
结果
方法权限控制
-
在服务器端我们可以通过Spring security提供的注解来对方法来进行权限控制。
-
Spring Security在方法的权限控制上支持三种类型的注解
-
JSR-250注解
JSR-250需要导入依赖进行使用
-
@Secured注解
@Secured注解是Spring security框架自带的功能
-
支持表达式的注解
表达式注解常常配合页面端标签控制权限进行使用,这里还要花费一些时间学习表达式的方法
Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应 的权限,反之则无。Spring Security可用表达式对象的基类是SecurityExpressionRoot,其为我们提供了如下在使用Spring EL表达式对URL或方法进行权限控制时通用的内置表达式。
表达式 描述
hasRole([role]) 当前用户是否拥有指定角色。
hasAnyRole([role1,role2]) 多个角色是一个以逗号进行分隔的字符串。如果当前用户拥有指定角色中的任意一个则返回true。
hasAuthority([auth]) 等同于hasRole
hasAnyAuthority([auth1,auth2]) 等同于hasAnyRole
Principle 代表当前用户的principle对象
authentication 直接从SecurityContext获取的当前Authentication对象
permitAll 总是返回true,表示允许所有的
denyAll 总是返回false,表示拒绝所有的
isAnonymous() 当前用户是否是一个匿名用户
isRememberMe() 表示当前用户是否是通过Remember-Me自动登录的
isAuthenticated() 表示当前用户是否已经登录认证成功了。
isFullyAuthenticated() 如果当前用户既不是一个匿名用户,同时又不是通过Remember-Me自动登录的,则返回true。 -
这三种注解默认都是没有启用的,需要单独通过global-method-security元素的对应属性进行启用。
使用@Secured注解
-
在spring-security.xml配置文件中配置一个标签
-
<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>
-
-
在指定方法上添加注解@Secured
-
//分页 @RequestMapping("/findAll.do") @Secured("ROLE_ADMIN") public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page, @RequestParam(name = "pageSize", required = true, defaultValue = "4") Integer size) { ModelAndView mv = new ModelAndView(); List<Orders> ordersList = ordersService.findAll(page, size); PageInfo pageInfo = new PageInfo(ordersList); mv.setViewName("orders-list"); mv.addObject("pageInfo", pageInfo); return mv; }
-
-
结果(创建simth用户,只给他分配了USER权限,没有给他分配ADMIN权限)
配置403错误页面
- 在web.xml中配置错误页面标签
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
- 新建403.jsp页面
<%--
Created by IntelliJ IDEA.
User: XinxingWang
Date: 2020/4/29
Time: 11:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>权限不足</title>
</head>
<body>
权限不足!
</body>
</html>
- 结果
页面端标签控制权限
页面端标签控制权限常常配合表达式控制权限进行使用,这里还要花费一些时间学习表达式的方法
使用页面端标签控制权限注解
-
在总工程的pom.xml配置文件中添加依赖
-
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring.security.version}</version> </dependency>
-
-
在aside.jsp页面和main.jsp页面导入标签
-
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
-
-
在用户名那里导入读取当前用户的标签
- 结果
AOP日志
记录用户的访问的操作信息
数据库准备
-
在Oracle数据库中添加创建sysLog数据库
-
CREATE TABLE sysLog ( id VARCHAR2(32) default SYS_GUID() PRIMARY KEY, visitTime timestamp, username VARCHAR2(50), ip VARCHAR2(30), url VARCHAR2(50), executionTime int, method VARCHAR2(200) )
-
-
创建实体类
-
package org.hacker.ssm.domain; import java.util.Date; /** * @author HackerStar * @create 2020-04-29 16:19 */ public class SysLog { private String id; private Date visitTime; private String visitTimeStr; private String username; private String ip; private String url; private Long executionTime; private String method; public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getVisitTime() { return visitTime; } public void setVisitTime(Date visitTime) { this.visitTime = visitTime; } public String getVisitTimeStr() { return visitTimeStr; } public void setVisitTimeStr(String visitTimeStr) { this.visitTimeStr = visitTimeStr; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Long getExecutionTime() { return executionTime; } public void setExecutionTime(Long executionTime) { this.executionTime = executionTime; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }
-
-
导入syslog-list.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>数据 - 项目练习</title> <meta name="description" content="项目练习"> <meta name="keywords" content="项目练习"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 页面头部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 页面头部 /--> <!-- 导航侧栏 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 导航侧栏 /--> <!-- 内容区域 --> <div class="content-wrapper"> <!-- 内容头部 --> <section class="content-header"> <h1> 日志管理 <small>全部日志</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首页</a></li> <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do">日志管理</a></li> <li class="active">全部日志</li> </ol> </section> <!-- 内容头部 /--> <!-- 正文区域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 数据表格 --> <div class="table-box"> <!--工具栏--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具栏/--> <!--数据列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">访问时间</th> <th class="sorting">访问用户</th> <th class="sorting">访问IP</th> <th class="sorting">资源URL</th> <th class="sorting">执行时间</th> <th class="sorting">访问方法</th> </tr> </thead> <tbody> <c:forEach items="${sysLogs}" var="syslog"> <tr> <td><input name="ids" type="checkbox"></td> <td>${syslog.id}</td> <td>${syslog.visitTimeStr }</td> <td>${syslog.username }</td> <td>${syslog.ip }</td> <td>${syslog.url}</td> <td>${syslog.executionTime}毫秒</td> <td>${syslog.method}</td> </tr> </c:forEach> </tbody> </table> <!--数据列表/--> <!--工具栏--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具栏/--> </div> <!-- 数据表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 总共2 页,共14 条数据。 每页 <select class="form-control"> <option>10</option> <option>15</option> <option>20</option> <option>50</option> <option>80</option> </select> 条 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首页</a></li> <li><a href="#">上一页</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一页</a></li> <li><a href="#" aria-label="Next">尾页</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文区域 /--> </div> <!-- 内容区域 /--> <!-- 底部导航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">研究院研发部</a>. </strong> All rights reserved. </footer> <!-- 底部导航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 选择框 $(".select2").select2(); // WYSIHTML5编辑器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 设置激活菜单 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document).ready(function() { // 激活导航位置 setSidebarActive("order-manage"); // 列表按钮 $("#dataList td input[type='checkbox']").iCheck({ checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全选操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
-
在controller模块下创建编写切面类处理日志类,用来获取访问的信息
-
package org.hacker.ssm.controller; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Date; /** * @author HackerStar * @create 2020-04-29 16:26 */ @Component @Aspect public class LogAop { private Date startTime;//访问时间 private Class executionClass;//访问的类 private Method executionMethod;//访问的方法 @Autowired private HttpServletRequest request; @Autowired private ISysLogService sysLogService; @Before("execution(* org.hacker.ssm.controller.*.*(..))") public void doBefore(JoinPoint jp) throws NoSuchMethodException { startTime = new Date();//访问的初始时间 executionClass = jp.getTarget().getClass();//获取访问的类 String methodName = jp.getSignature().getName();//获取访问的方法的名字 Object[] args = jp.getArgs();//获取访问的方法的参数 if (args == null || args.length == 0) {//方法没有参数 executionMethod = executionClass.getMethod(methodName);//获取访问的方法 } else {//方法有参数,将args元素遍历,获取对应的Class,装到Class数组中 Class[] classArgs = new Class[args.length]; for (int i = 0; i < args.length; i++) { classArgs[i] = args[i].getClass();//获取访问的方法 } executionMethod = executionClass.getMethod(methodName, classArgs); } } @After("execution(* org.hacker.ssm.controller.*.*(..))") public void doAfter(JoinPoint jp) { //获取类上的@RequestMapping对象 if (executionClass != SysLogController.class) { RequestMapping classAnnotation = (RequestMapping) executionClass.getAnnotation(RequestMapping.class); if (classAnnotation != null) { //获取方法上的@RequestMapping对象 RequestMapping methodAnnotation = executionMethod.getAnnotation(RequestMapping.class); if (methodAnnotation != null) { SysLog sysLog = new SysLog();//封装的实体类 String url = ""; //它的值应该是类上的@RequestMapping的value+方法上的@RequestMapping的value url = classAnnotation.value()[0] + methodAnnotation.value()[0]; //获取访问时长 Long exectiontime = new Date().getTime() - startTime.getTime(); //获取ip String ip = request.getRemoteAddr(); //获取用户名 SecurityContext context = SecurityContextHolder.getContext(); User principal = (User) context.getAuthentication().getPrincipal(); String username = principal.getUsername(); //将sysLog对象属性封装 sysLog.setVisitTime(startTime); sysLog.setExecutionTime(exectiontime); sysLog.setUsername(username); sysLog.setMethod("[类名]" + executionClass.getName() + "[方法名]" + executionMethod.getName()); sysLog.setIp(ip); sysLog.setUrl(url); //将访问记录实体类保存到数据库 sysLogService.save(sysLog); } } } } }
-
编写SysLogController模块用来和前端页面交互
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:37 */ @RequestMapping("/sysLog") @Controller public class SysLogController { @Autowired private ISysLogService sysLogService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<SysLog> sysLogs = sysLogService.findAll(); mv.addObject("sysLogs", sysLogs); mv.setViewName("sysLog-list"); return mv; } }
-
-
-
编写SysLogService模块
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.SysLog; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:41 */ public interface ISysLogService { public List<SysLog> findAll(); void save(SysLog sysLog); }
-
-
实现类
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.ISysLogDao; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:43 */ @Service @Transactional public class SysLogServiceImpl implements ISysLogService { @Autowired private ISysLogDao sysLogDao; @Override public List<SysLog> findAll() { return sysLogDao.findAll(); } @Override public void save(SysLog sysLog) { sysLogDao.save(sysLog); } }
-
-
-
编写SysLogDao模块
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.SysLog; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:43 */ public interface ISysLogDao { @Select("select * from sysLog") List<SysLog> findAll(); @Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})") void save(SysLog sysLog); }
-
-
结果
第五天工作完毕