05.SSM整合案例的基本介紹html
06.產品操做前端
07.訂單操做java
08.權限控制web
09.用戶和角色操做spring
10.權限關聯數據庫
11.AOP日誌express
3.3.1.用戶查詢頁面 user-list.jsp
請在資料中查看具體代碼
跨域
<!--數據列表--> <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" varStatus="s"> <tr> <td><input name="ids" type="checkbox" id="${s.index}" value="${user.id}"></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>
視圖層 UserController 數組
@Controller @RequestMapping(value = "/user") public class UsersController { @Autowired private IUserService userService; @RequestMapping("/findAll.do") public ModelAndView findAll() throws Exception{ ModelAndView mv = new ModelAndView("user-list2"); //獲取一個添加對象 List<UserInfo> userList = userService.findAll(); //attributeName取決於jsp頁面上的EL表達式{}裏面的字符串 mv.addObject("userList",userList); return mv; } }
UserServiceImpl
新添加的部分代碼:
// 查詢全部用戶 @Override public List<UserInfo> findAll() throws Exception { return userDao.findAll(); }
持久層 IUserDao
新添加的部分代碼:
/** * 查詢全部用戶 * @return * @throws Exception */ @Select("select * from USERS") public List<UserInfo> findAll() throws Exception;
user-list.jsp裏面的一個按鈕控件經過onclick 實現跳轉請求
<!--工具欄--> <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>
user-add.jsp裏面關鍵信息以下:
form表單的action屬性
<!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/user/save.do" method="post"> <!-- 正文區域 -->
DAO層
/** * 添加一個新用戶 * @param userInfo */ @Insert({"insert into USERS(username,email,password,phoneNum,status)", "values(#{username},#{email},#{password},#{phoneNum},#{status})"}) public void save(UserInfo userInfo) throws Exception;
Utils工具類
package cn.bjut.ssm.utils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class BCryptPasswordEncoderUtils { private static BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); //工具類的方法最好用static關鍵字修飾 //明文轉換成密文工具類 public static String encodePassword(String password){ return bCryptPasswordEncoder.encode(password); } }
Service層
//添加一個新用戶 @Override public void save(UserInfo userInfo) throws Exception { //對密碼進行加密處理 userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword())); userDao.save(userInfo); //返回void return ; }
Controller層
//添加用戶(後自動請求查詢全部用戶) @RequestMapping("/save.do") public String save(UserInfo userInfo)throws Exception{ userService.save(userInfo); //返回字符串爲當前控制類的註解@RequestMapping後面小括號裏的內容 return "redirect:findAll.do"; }
修改oracle數據庫中表的varchar2字段類型長度
package cn.bjut.ssm.utils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class BCryptPasswordEncoderUtils { private static BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); //工具類的方法最好用static關鍵字修飾 //明文轉換成密文工具類 public static String encodePassword(String password){ return bCryptPasswordEncoder.encode(password); } //構造一個主方法用於轉換以前明文密碼得到加密後的字符串 public static void main(String[] args) { //以前明文密碼:itheima //$2a$10$ylUiLsD7W.hqjGIsND9/CeuKRxz4.4oHsyZulKtfErHzL5WAkOqtW String code = BCryptPasswordEncoderUtils.encodePassword("itheima"); //打印到控制檯 System.out.println(code); } }
-- 查詢表users的數據 select * from users t; -- 插入以前的明文密碼的轉換字符串密文 update USERS set PASSWORD ='$2a$10$ylUiLsD7W.hqjGIsND9/CeuKRxz4.4oHsyZulKtfErHzL5WAkOqtW' where USERNAME = 'ssm08'; -- 提交事務 commit;
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!-- 配置不攔截的靜態資源和登陸相關頁面 --> <security:http pattern="/login.jsp" security="none"/> <security:http pattern="/failer.jsp" security="none"/> <security:http pattern="/css/**" security="none"/> <security:http pattern="/img/**" security="none"/> <security:http pattern="/images/**" security="none"/> <security:http pattern="/plugins/**" security="none"/> <!-- 配置具體的規則 auto-config="false" 選用本身編寫登陸的頁面,不用框架提供的默認登陸頁面 use-expressions="false" 是否使用SPEL表達式(還沒學習過) --> <security:http auto-config="false" use-expressions="true" > <!-- 配置具體的攔截的規則 pattern="請求路徑的規則" access="訪問系統的人,必須有ROLE_USER的角色" --> <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/> <!--<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>--> <!--若是沒有login-processing-url這一屬性,那麼登陸表單的action,必須爲j_spring_secutity_check--> <!-- 定義跳轉的具體的頁面 --> <security:form-login login-page="/login.jsp" login-processing-url="/login" username-parameter="username" password-parameter="password" default-target-url="/index.jsp" authentication-failure-url="/failer.jsp" authentication-success-forward-url="/index.jsp" /> <!-- 關閉跨域請求 --> <security:csrf disabled="true"/> <!-- 退出 --> <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" /> </security:http> <!-- 切換成數據庫中的用戶名和密碼 --> <security:authentication-manager> <security:authentication-provider user-service-ref="userService"> <!-- 配置加密的方式 --> <security:password-encoder ref="passwordEncoder"/> </security:authentication-provider> </security:authentication-manager> <!-- 配置加密類 --> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <!-- 提供了入門的方式,在內存中存入用戶名和密碼 <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/> </security:user-service> </security:authentication-provider> </security:authentication-manager> --> </beans>
Service層的 實現了接口UserDetailsService的實現類
cn.bjut.ssm.service.impl.UserServiceImpl
@Service(value = "userService") @Transactional //註解的方式使用spring事務管理 public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Autowired //注入加密類 private BCryptPasswordEncoder bCryptPasswordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //UserInfo是domain包下的實體類 UserInfo userInfo = null; try{ userInfo = userDao.findByUsername(username); } catch(Exception e){ e.printStackTrace(); } //把本身查詢到的實體類中的認證信息封裝成UserDetails //"{noop}"使用密碼明文的必要前綴 // User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles())); User user = new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus() ==0 ?false:true,true,true,true,getAuthority(userInfo.getRoles())); return user; } //這個成員方法做用就是返回一個List集合,集合中裝入的是角色描述。 //實際項目中應該是從數據庫中獲取role描述後封裝到這個方法體裏面。 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){ List<SimpleGrantedAuthority> list = new ArrayList<>(); //加強for循環 for (Role role :roles){ // new 匿名對象 list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName())); } return list; } // 查詢全部用戶 @Override public List<UserInfo> findAll() throws Exception { return userDao.findAll(); } //添加一個新用戶 @Override public void save(UserInfo userInfo) throws Exception { //對密碼進行加密處理 userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword())); userDao.save(userInfo); //返回void return ; } }
6.用戶操做-用戶詳情服務器端代碼實現
user-list.jsp
<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>
詳情 按鈕能夠向服務器提交一個GET方式的請求。
視圖層
@Controller @RequestMapping(value = "/user") public class UsersController { @Autowired private IUserService userService; @RequestMapping("/findById.do") public ModelAndView findById(String id)throws Exception{ ModelAndView mv = new ModelAndView(); //獲取一個Object UserInfo userInfo = userService.findById(id); mv.addObject("user",userInfo); mv.setViewName("user-show2"); return mv; }
Service層
@Service(value = "userService") @Transactional //註解的方式使用spring事務管理 public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Autowired //注入加密類 private BCryptPasswordEncoder bCryptPasswordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //UserInfo是domain包下的實體類 UserInfo userInfo = null; try{ userInfo = userDao.findByUsername(username); } catch(Exception e){ e.printStackTrace(); } //把本身查詢到的實體類中的認證信息封裝成UserDetails //"{noop}"使用密碼明文的必要前綴 // User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles())); User user = new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus() ==0 ?false:true,true,true,true,getAuthority(userInfo.getRoles())); return user; } //這個成員方法做用就是返回一個List集合,集合中裝入的是角色描述。 //實際項目中應該是從數據庫中獲取role描述後封裝到這個方法體裏面。 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){ List<SimpleGrantedAuthority> list = new ArrayList<>(); //加強for循環 for (Role role :roles){ // new 匿名對象 list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName())); } return list; } // 查詢全部用戶 @Override public List<UserInfo> findAll() throws Exception { return userDao.findAll(); } //添加一個新用戶 @Override public void save(UserInfo userInfo) throws Exception { //對密碼進行加密處理 userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword())); userDao.save(userInfo); //返回void return ; } //經過ID查詢用戶詳情 @Override public UserInfo findById(String id) throws Exception{ return userDao.findByUserId(id); } }
IUserDAO
//經過用戶ID查詢Role的詳情 @Select("select id,username,phoneNum,status from USERS where id = #{ UserId }") @Results({ @Result(property = "id",column = "id",id = true), @Result(property = "username",column = "username"), @Result(property = "phoneNum",column = "phoneNum"), @Result(property = "status",column = "status"), //經過中間表查詢多對多關係,返回一個其它實體類的List集合 @Result(property = "roles",column = "id",javaType =java.util.List.class,many = @Many(select = "cn.bjut.ssm.dao.IRoleDao.findRoleByUserId")) }) public UserInfo findByUserId(String UserId) throws Exception;
IRoleDao
public interface IRoleDao { //根據用戶ID查詢出全部對應的角色 @Select("select * from ROLE where id in( select ROLEID from USERS_ROLE where USERID = #{userId})") @Results({ @Result(id = true,property = "id",column = "id"), @Result(property = "roleName",column = "roleName"), @Result(property = "roleDesc",column = "roleDesc"), @Result(property = "permissions",column = "id",javaType = java.util.List.class,many = @Many(select = "cn.bjut.ssm.dao.IPermissionDao.findPermissionByRoleId")) }) public List<Role> findRoleByUserId(String userId) throws Exception; }
IPermissionDao
public interface IPermissionDao { //多對多表的查詢,先查詢中間表做爲結果集。 @Select("select * from PERMISSION where id in(select permissionId from role_permission where roleId = #{ roleId})") public List<Permission> findPermissionByRoleId(String roleId) throws Exception; }
user-show.jsp
<!--數據列表--> <div class="tab-pane" id="tab-treetable"> <table id="collapse-table" class="table table-bordered table-hover dataTable"> <thead> <tr> <th>名稱</th> <th>描述</th> </tr> </thead> <tr data-tt-id="0"> <td colspan="2">${user.username}</td> </tr> <tbody> <c:forEach items="${user.roles}" var="role" varStatus="s"> <tr data-tt-id="${s.index +1 }" data-tt-parent-id="0" > <td>${role.roleName }</td> <td>${role.roleDesc }</td> </tr> <c:forEach items="${role.permissions}" var="permission"> <tr data-tt-id="1-1" data-tt-parent-id="${s.index +1 }"> <td>${permission.permissionName}</td> <td>${permission.url}</td> </tr> </c:forEach> </c:forEach> </tbody> </table> </div> <!--數據列表/-->
在aside.jsp文件內有側邊欄導航的連接地址,這些就是Controller層的@RequestMapping註解後面的value值。
ssm_web子模塊新建一個RoleController實現。
DAO層 IRoleDao
@Select("select * from ROLE ") @Results({ @Result(id = true,property = "id",column = "id"), @Result(property = "roleName",column = "roleName"), @Result(property = "roleDesc",column = "roleDesc"), }) //查詢全部的Role信息返回一個List集合 public List<Role> findAll()throws Exception;
Service層 RoleServiceImpl
@Service @Transactional //註解的方式使用spring事務管理 public class RoleServiceImpl implements IRoleService { @Autowired private IRoleDao roleDao; //查詢全部Role的Service層實現 @Override public List<Role> findAll() throws Exception { return roleDao.findAll(); } }
視圖層 RoleController
/** * 角色管理Controller */ @Controller @RequestMapping(name ="/role") public class RoleController { @Autowired private IRoleService roleService; //查詢全部角色 @RequestMapping ("/findAll.do") public ModelAndView findAll() throws Exception{ ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList",roleList); mv.setViewName("role-list2"); return mv; } }
@RequestMapping (value="{
} ") 能夠支持通配符* 的請求路徑的數組。
Controller層
/** * 角色管理Controller */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; //新建保存一個Role @RequestMapping(value = { "/save.do" }) public String saveRole(Role role) throws Exception{ roleService.saveRole( role); return "redirect:findAll.do"; }
DAO層
public interface IRoleDao { //插入一條Role完整信息 @Insert({"insert into ROLE (roleName,roleDesc) ", "values(#{roleName},#{roleDesc})"}) public void saveRole(Role role)throws Exception;
PL/SQL Developer插入兩條PERMISSION表的數據以供後續測試使用。
-- 查詢PERMISSION表中全部數據 select * from permission t -- 添加兩條測試記錄到PERMISSION表 insert into permission ( permissionname, URL ) values('user findAll','/user/findAll.do'); insert into permission ( permissionname, URL ) values('user findByID','/user/findById.do'); commit;
在WEB-INF/pages/目錄下copy一份 permission-list.jsp做爲前端顯示的頁面。
@Controller @RequestMapping(value="/permission") public class PermissionController { @Autowired private IPermissionService permissionService; @RequestMapping("/findAll.do") public ModelAndView findAll() throws Exception{ ModelAndView mv = new ModelAndView(); List<Permission> permissionList = permissionService.findAll(); mv.addObject("permissionList",permissionList); mv.setViewName("permission-list2"); return mv; } }
DAO層的接口 IPermissionDao
public interface IPermissionDao { //查詢全部權限 @Select("select * from PERMISSION") public List<Permission> findAll() throws Exception;
====================
end