一、關於停止使用外鍵。
原本集成shiro建立用戶、角色、權限表的時候使用了外鍵,系統自動創建其中兩個關聯表,用@JoinTable。看起來省事,但是實際上刪除以及取出數據轉成json都很麻煩,折騰的心累,真不如取消外鍵自己來搞定,比較靈活,業務邏輯掌握好就可以。
所以,最后3個entity變成了5個。
entity如下:
@Entity public class User { @Id @GenericGenerator(name="generator",strategy = "native") @GeneratedValue(generator = "generator") private Integer userId; @Column(nullable = false, unique = true) private String userName; //登錄用戶名,賬號 @Column(nullable = false) private String name;//名稱(昵稱或者真實姓名,根據實際情況定義) @Column(nullable = false) private String password; private String salt;//加密密碼的鹽 private byte state;//用戶狀態,0:創建未認證(比如沒有激活,沒有輸入驗證碼等等)--等待驗證的用戶 , 1:正常狀態,2:用戶被鎖定. // @ManyToMany(fetch= FetchType.EAGER)//立即從數據庫中進行加載數據; // @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns ={@JoinColumn(name = "roleId") }) @Transient private List<IUserRole> roleList;// 一個用戶具有多個角色 @Transient private List<ISysPermission> permissionList;//用戶的權限 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime createTime;//創建時間 @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate expiredDate;//過期日期 private String email; private String tel; public List<IUserRole> getRoleList() { return roleList; } public void setRoleList(List<IUserRole> roleList) { this.roleList = roleList; } public List<ISysPermission> getPermissionList() { return permissionList; } public void setPermissionList(List<ISysPermission> permissionList) { this.permissionList = permissionList; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public LocalDate getExpiredDate() { return expiredDate; } public void setExpiredDate(LocalDate expiredDate) { this.expiredDate = expiredDate; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } public byte getState() { return state; } public void setState(byte state) { this.state = state; } /** * 密碼鹽. * @return */ public String getCredentialsSalt(){ return this.userName+this.salt; } //重新對鹽重新進行了定義,用戶名+salt,這樣就更加不容易被破解 }
@Entity public class SysRole { @Id @GenericGenerator(name="generator",strategy = "native") @GeneratedValue(generator = "generator") private Integer roleId; // 編號 @Column(nullable = false, unique = true) @NotBlank(message ="名稱不能為空") private String role; // 角色標識程序中判斷使用,如"admin",這個是唯一的: private String description; // 角色描述,UI界面顯示使用 private Boolean available = Boolean.FALSE; // 是否可用,如果不可用將不會添加給用戶, // @JsonFormat(pattern="yyyy-MM-dd HH:mm",timezone="GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime createTime;//創建時間 // @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate expiredDate;//過期日期 //角色 -- 權限關系:多對多關系; // @JsonIgnore // @ManyToMany(fetch= FetchType.EAGER) // @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")}) @Transient private List<ISysRolePermission> permissions; // 用戶 - 角色關系定義; // @JsonIgnore // @ManyToMany // @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")}) // private List<User> users;// 一個角色對應多個用戶 public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public LocalDate getExpiredDate() { return expiredDate; } public void setExpiredDate(LocalDate expiredDate) { this.expiredDate = expiredDate; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Boolean getAvailable() { return available; } public void setAvailable(Boolean available) { this.available = available; } public List<ISysRolePermission> getPermissions() { return permissions; } public void setPermissions(List<ISysRolePermission> permissions) { this.permissions = permissions; } }
@Entity public class SysPermission { @Id @GenericGenerator(name="generator",strategy = "native") @GeneratedValue(generator = "generator") private Integer permissionId;//主鍵. @Column(nullable = false) private String permissionName;//名稱. private String description;//描述 @Column(columnDefinition="enum('menu','button')") private String resourceType;//資源類型,[menu|button] private String url;//資源路徑. private String permission; //權限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view private Long parentId; //父編號 private String parentIds; //父編號列表 private Integer level;//菜單層級,1(頂級),2,3 private Boolean available = Boolean.FALSE; //角色 -- 權限關系:多對多關系; // @ManyToMany // @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")}) @Transient private List<SysRole> roles; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getLevel() { return level; } public void setLevel(Integer level) { this.level = level; } public Integer getPermissionId() { return permissionId; } public void setPermissionId(Integer permissionId) { this.permissionId = permissionId; } public String getPermissionName() { return permissionName; } public void setPermissionName(String permissionName) { this.permissionName = permissionName; } public String getResourceType() { return resourceType; } public void setResourceType(String resourceType) { this.resourceType = resourceType; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getPermission() { return permission; } public void setPermission(String permission) { this.permission = permission; } public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public String getParentIds() { return parentIds; } public void setParentIds(String parentIds) { this.parentIds = parentIds; } public Boolean getAvailable() { return available; } public void setAvailable(Boolean available) { this.available = available; } public List<SysRole> getRoles() { return roles; } public void setRoles(List<SysRole> roles) { this.roles = roles; } }
新增的實體:
//用戶和角色關聯表
@Entity public class SysUserRole { @Id @GenericGenerator(name="generator",strategy = "native") @GeneratedValue(generator = "generator") private Integer id; // 編號 private Integer userId; private Integer roleId; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } }
//角色權限對照表
@Entity public class SysRolePermission { @Id @GenericGenerator(name="generator",strategy = "native") @GeneratedValue(generator = "generator") private Integer id; // 編號 private Integer roleId; // private Integer permissionId;// public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public Integer getPermissionId() { return permissionId; } public void setPermissionId(Integer permissionId) { this.permissionId = permissionId; } }
建立以上5個實體以后,實體之間的關聯就需要自己來實現和掌控,例如刪除角色的時候,角色和權限關聯表里的對應角色記錄就必須同步刪除;刪除用戶的時候,用戶和角色關聯表的記錄就必須同步刪除。
二、DAO層里需要自定義一些SQL,對於SQL比較熟悉的人來說非常簡單。
角色DAO
public interface RoleRepository extends JpaRepository<SysRole,Integer> { Page<SysRole> findAllByRoleContains(String role, Pageable pageable); SysRole findSysRoleByRole(String role); //排除現有角色的情況下,判斷新的角色是否存在 @Query(value="select * from SysRole where role <> ?1 and role = ?2",nativeQuery = true) SysRole findSysRoleExists2(String oldRole, String newRole); //根據roleid列表刪除所有的角色 @Modifying @Query(value = "delete from SysRole where roleId in (?1)",nativeQuery = true) void deleteAllByRoleIdList(List<Integer> roleIdList); //根據roleid列出所有權限,包括沒有的權限,如果沒有權限,則roleid和role兩個字段會是null值,可以根據此做業務判斷 @Query(value="select a.permissionId,a.permission,a.permissionName,a.parentId,c.roleId,c.role from syspermission a \n" + "left join sysrolepermission b on a.permissionId=b.permissionId and a.available=1 and b.roleId=?1\n" + "left join sysrole c on c.roleId=b.roleId", countQuery = "select count(*) from syspermission a \n" + "left join sysrolepermission b on a.permissionId=b.permissionId and a.available=1 and b.roleId=?1\n" + "left join sysrole c on c.roleId=b.roleId", nativeQuery = true) List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId); //根據roleid刪除角色權限關聯表里所有角色權限 @Modifying @Query(value = "delete from SysRolePermission where roleId=?1",nativeQuery = true) void deleteRolePermission(Integer roleId); //插入角色和權限 @Modifying @Query(value="insert into SysRolePermission(roleId,permissionId) VALUES(?1,?2) ",nativeQuery = true) void insertRolePermission(Integer roleId, Integer permissionId); }
用戶DAO
public interface UserRepository extends JpaRepository<User,Integer> { User findByUserName(String userName); Page<User> findAllByUserNameContains(String userName, Pageable pageable); //排除現有用戶的情況下,判斷新用戶是否存在 @Query(value="select * from user where userName<> ?1 and userName=?2",nativeQuery = true) User findUserExist2(String oldUserName, String newUserName); //根據userid列表刪除所有用戶 @Modifying @Query(value="delete from user where userId in (?1)",nativeQuery = true) void deleteAllUserByUserIdList(List<Integer> userIdList); //根據userid刪除用戶角色關聯表里的記錄 @Modifying @Query(value="delete from SysUserRole where userId in (?1)",nativeQuery = true) void deleteAllUserRoleByUserIdList(List<Integer> userIdList); //根據userid刪除用戶角色關聯表里的記錄 @Modifying @Query(value="delete from SysUserRole where userId = ?1",nativeQuery = true) void deleteAllUserRoleByUserId(Integer userId); //新增用戶和角色關聯記錄 @Modifying @Query(value="insert into SysUserRole(userId,roleId) VALUES(?1,?2)",nativeQuery = true) void insertUserRole(Integer userId, Integer roleId); //根據用戶名獲取用戶所具備的角色列表 @Query(value="select a.userId,a.userName,c.roleId,c.role,c.description from user a\n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrole c on b.roleId=c.roleId and c.available=1\n" + "where a.userName=?1", countQuery = "select count(*) from user a\n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrole c on b.roleId=c.roleId and c.available=1\n" + "where a.userName=?1", nativeQuery = true) List<IUserRole> findUserRoleByUserName(String userName); //根據用戶id,列出所有角色,包括該用戶不具備的角色,該用戶不具備角色的時候,userid和username為null,可以做業務判斷 @Query(value="select a.roleId,a.role,a.description,c.userId,c.userName from SysRole a\n" + "left join SysUserRole b on a.roleId=b.roleId and a.available=1 and b.userId=?1\n" + "left join user c on c.userId=b.userId;", countQuery = "select count(*) from SysRole a\n" + "left join SysUserRole b on a.roleId=b.roleId and a.available=1 and b.userId=?1\n" + "left join user c on c.userId=b.userId;", nativeQuery = true) List<IUserRole> findAllUserRoleByUserId(Integer userId); //根據用戶名,獲取用戶具備的權限。 @Query(value="select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a \n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrolepermission c on b.roleId = c.roleId\n" + "inner join syspermission d on c.permissionId=d.permissionId\n" + "where a.userName=?1", countQuery = "select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a \n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrolepermission c on b.roleId = c.roleId\n" + "inner join syspermission d on c.permissionId=d.permissionId\n" + "where a.userName=?1", nativeQuery = true) List<ISysPermission> findUserRolePermissionByUserName(String userName); }
JPA中自定義SQL返回結果需要自定義結果集接收,實際上最方便的是定義結果集接口,JPA自動會實現該接口,填充數據。
結果集接口:
//用於UserRepository自定義返回實體 用戶與角色對應表
public interface IUserRole { Integer getUserId(); String getUserName(); Integer getRoleId(); String getRole(); String getDescription(); }
//用於UserRepository自定義返回實體用戶與權限對應表
public interface ISysPermission { Integer getUserId(); String getUserName(); Integer getPermissionId(); String getPermission(); String getPermissionName(); }
//角色權限對照表,列出全部權限,沒有權限的role和roleId為null
public interface ISysRolePermission { Integer getRoleId(); String getRole(); Integer getPermissionId(); String getPermission(); String getPermissionName(); Integer getParentId(); }
三、service層和impl層實際上就沒多少變化了。
public interface UserService { User findByUserName(String userName); Optional<User> findUserById(Integer userId); User save(User user); boolean checkUserExists(String userName); boolean checkUserExists2(String oldUserName, String newUserName); List<IUserRole> findUserRoleByUserName(String userName); List<IUserRole> findAllUserRoleByUserId(Integer userId); List<ISysPermission> findUserRolePermissionByUserName(String userName); Page<User> findAllByUserNameContains(String userName, Pageable pageable); void deleteAllUserByUserIdList(List<Integer> userIdList); void deleteAllUserRoleByUserIdList(List<Integer> userIdList); void deleteAllUserRoleByUserId(Integer userId); void grantUserRole(Integer userId, List<Integer> roleIdList); }
public interface RoleService { Page<SysRole> findAll(Pageable pageable); Page<SysRole> findAllByRoleContains(String role, Pageable pageable); Optional<SysRole> findById(Integer roleId); SysRole save(SysRole sysRole); boolean checkRoleExists(String role); boolean checkRoleExists(String oldRole, String newRole); boolean deleteAllByRoleIdIn(List<Integer> roleIdList); List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId); void grantAuthorization(Integer roleId, List<Integer> permissionList); void clearAuthorization(Integer roleId); }
//這個登錄相關的service
public interface LoginService { LoginResult login(String userName, String password); String getCurrentUserName(); void logout(); }
impl層,因為自定義的SQL要用事務,一般放在impl里實現,不建議放在controller里。
比如授權,采用的方式是刪除原先的所有授權,把新的權限重新插入,兩步操作用事務。
@Service public class UserServiceImpl implements UserService { @Resource private UserRepository userRepository; @Override public User findByUserName(String userName) { return userRepository.findByUserName(userName); } @Override public List<IUserRole> findUserRoleByUserName(String userName) { return userRepository.findUserRoleByUserName(userName); } @Override public List<IUserRole> findAllUserRoleByUserId(Integer userId) { return userRepository.findAllUserRoleByUserId(userId); } @Override public List<ISysPermission> findUserRolePermissionByUserName(String userName) { return userRepository.findUserRolePermissionByUserName(userName); } @Override public Optional<User> findUserById(Integer userId) { return userRepository.findById(userId); } @Override public User save(User user) { return userRepository.save(user); } @Override public boolean checkUserExists(String userName) { User user = userRepository.findByUserName(userName); if(user!=null) return true; else return false; } @Override public boolean checkUserExists2(String oldUserName, String newUserName) { User user = userRepository.findUserExist2(oldUserName,newUserName); if(user!=null) return true; else return false; } @Override public Page<User> findAllByUserNameContains(String userName, Pageable pageable) { return userRepository.findAllByUserNameContains(userName,pageable); } @Transactional @Override public void deleteAllUserByUserIdList(List<Integer> userIdList) { userRepository.deleteAllUserRoleByUserIdList(userIdList); userRepository.deleteAllUserByUserIdList(userIdList); } @Transactional @Override public void deleteAllUserRoleByUserIdList(List<Integer> userIdList) { userRepository.deleteAllUserRoleByUserIdList(userIdList); } @Transactional @Override public void deleteAllUserRoleByUserId(Integer userId) { userRepository.deleteAllUserRoleByUserId(userId); } @Transactional @Override public void grantUserRole(Integer userId, List<Integer> roleIdList) { userRepository.deleteAllUserRoleByUserId(userId); for(Integer roleId:roleIdList) { userRepository.insertUserRole(userId,roleId); } } }
@Service public class RoleServiceImpl implements RoleService { @Resource RoleRepository roleRepository; @Override public Page<SysRole> findAll(Pageable pageable) { return roleRepository.findAll(pageable); } @Override public Optional<SysRole> findById(Integer roleId) { return roleRepository.findById(roleId); } @Override public Page<SysRole> findAllByRoleContains(String role, Pageable pageable) { return roleRepository.findAllByRoleContains(role,pageable); } @Override public SysRole save(SysRole sysRole) { return roleRepository.save(sysRole); } @Override public boolean checkRoleExists(String role) { SysRole sysRole = roleRepository.findSysRoleByRole(role); if(sysRole!=null) return true; else return false; } @Override public boolean checkRoleExists(String oldRole, String newRole) { SysRole sysRole = roleRepository.findSysRoleExists2(oldRole,newRole); if(sysRole!=null) return true; else return false; } //刪除角色權限和角色 @Transactional @Override public boolean deleteAllByRoleIdIn(List<Integer> roleIdList) { try { for(Integer roleId:roleIdList) { roleRepository.deleteRolePermission(roleId); } roleRepository.deleteAllByRoleIdList(roleIdList); return true; }catch (Exception e) { e.printStackTrace(); return false; } } @Override public List<ISysRolePermission> findSysRolePermissionByRoleId(Integer roleId) { return roleRepository.findSysRolePermissionByRoleId(roleId); } //授權前先清除原角色權限,然后重新新增授權 @Transactional @Override public void grantAuthorization(Integer roleId, List<Integer> permissionList) { roleRepository.deleteRolePermission(roleId); for(Integer permissionId:permissionList) { roleRepository.insertRolePermission(roleId,permissionId); } } @Transactional @Override public void clearAuthorization(Integer roleId) { roleRepository.deleteRolePermission(roleId); } }
LoginServiceImpl沒多少變化。
四、config,新增Kaptcha做圖片驗證碼
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
@Component public class KaptchaConfig { @Bean public DefaultKaptcha getDefaultKaptcha() { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); // 圖片邊框 properties.setProperty("kaptcha.border", "yes"); // 邊框顏色 properties.setProperty("kaptcha.border.color", "105,179,90"); // 字體顏色 properties.setProperty("kaptcha.textproducer.font.color", "blue"); // 圖片寬 properties.setProperty("kaptcha.image.width", "150"); // 圖片高 properties.setProperty("kaptcha.image.height", "40"); // 字體大小 properties.setProperty("kaptcha.textproducer.font.size", "30"); // session key properties.setProperty("kaptcha.session.key", "code"); // 驗證碼長度 properties.setProperty("kaptcha.textproducer.char.length", "4"); // 字體 // properties.setProperty("kaptcha.textproducer.font.names", "宋體,楷體,微軟雅黑"); properties.put("kaptcha.obscurificator.impl","com.google.code.kaptcha.impl.ShadowGimpy"); properties.put("kaptcha.textproducer.char.string","acdefhkmnprtwxy2345678"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } }
這里有個坑,需要為驗證碼鏈接配置匿名訪問,就是在ShiroConfig里,否則圖片出不來。
filterChainDefinitionMap.put("/getVerifyCode", "anon"); //給驗證碼使用
五、controller
HomeController用於登錄驗證
@Controller public class HomeController { @Resource private LoginService loginService; @Resource DefaultKaptcha defaultKaptcha; private long verifyTTL = 60;//驗證碼過期時間60秒 @RequestMapping({"/", "/index"}) public String index() { return "/index"; } /** * 2、生成驗證碼 * * @param request * @param response * @throws Exception */ @RequestMapping("/getVerifyCode") public void defaultKaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception { byte[] bytesCaptchaImg = null; ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { // 生產驗證碼字符串並保存到session中 String createText = defaultKaptcha.createText(); request.getSession().setAttribute("verifyCode", createText); request.getSession().setAttribute("verifyCodeTTL", System.currentTimeMillis()); // 使用生產的驗證碼字符串返回一個BufferedImage對象並轉為byte寫入到byte數組中 BufferedImage bufferedImage = defaultKaptcha.createImage(createText); ImageIO.write(bufferedImage, "jpg", jpegOutputStream); } catch (Exception e) { e.printStackTrace(); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // 定義response輸出類型為image/jpeg類型,使用response輸出流輸出圖片的byte數組 bytesCaptchaImg = jpegOutputStream.toByteArray(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = response.getOutputStream(); responseOutputStream.write(bytesCaptchaImg); responseOutputStream.flush(); responseOutputStream.close(); } @RequestMapping("/403") public String unauthorizedRole() { System.out.println("------沒有權限-------"); return "/user/403"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String toLogin(Map<String, Object> map, HttpServletRequest request) { loginService.logout(); return "/user/login"; } @RequestMapping(value = "/login", method = RequestMethod.POST) public String login(Map<String, Object> map, HttpServletRequest request) throws Exception { System.out.println("login()"); String userName = request.getParameter("userName"); String password = request.getParameter("password"); String verifyCode = request.getParameter("verifyCode"); String rightCode = (String) request.getSession().getAttribute("verifyCode"); Long verifyCodeTTL = (Long) request.getSession().getAttribute("verifyCodeTTL"); Long currentMillis = System.currentTimeMillis(); if (rightCode == null || verifyCodeTTL == null) { map.put("msg", "請刷新圖片,輸入驗證碼!"); map.put("userName", userName); map.put("password", password); return "/user/login"; } Long expiredTime = (currentMillis - verifyCodeTTL) / 1000; if (expiredTime > this.verifyTTL) { map.put("msg", "驗證碼過期,請刷新圖片重新輸入!"); map.put("userName", userName); map.put("password", password); return "/user/login"; } if (!verifyCode.equalsIgnoreCase(rightCode)) { map.put("msg", "驗證碼錯誤,請刷新圖片重新輸入!"); map.put("userName", userName); map.put("password", password); return "/user/login"; } LoginResult loginResult = loginService.login(userName, password); if (loginResult.isLogin()) { map.put("userName", userName); return "/index"; } else { map.put("msg", loginResult.getResult()); map.put("userName", userName); return "/user/login"; } } @RequestMapping("/logout") public String logOut(HttpSession session) { loginService.logout(); return "/user/login"; } }
密碼生成,前文沒說,實際是比較簡單的:
public class EncryptUtils { public static String encrypt(String str,String salt, String algorithmName, int hashIterations) { return new SimpleHash(algorithmName,str, ByteSource.Util.bytes(salt),hashIterations).toString(); } }
UserController
@Controller @RequestMapping("/user") public class UserController { private String algorithmName = "md5"; private int hashIterations = 2; private String salt = "8d78869f470951332959580424d4bf4f"; @Resource UserService userService; @Resource LoginService loginService; /** * 用戶查詢. * @return */ @RequestMapping("/ulist") public String userList(){ return "/user/userList"; } @RequestMapping(value="/getUserList") @RequiresPermissions("user:view")//權限管理; @ResponseBody public Object getUserList(HttpServletRequest request, HttpServletResponse response) { int pageSize = 10; try { pageSize = Integer.parseInt(request.getParameter("pageSize")); }catch (Exception e) { e.printStackTrace(); } int pageNumber=0 ; try { pageNumber = Integer.parseInt(request.getParameter("pageNumber"))-1; }catch (Exception e) { e.printStackTrace(); } Map<String, Object> map = new HashMap<>(); String strUserName=request.getParameter("searchText")==null ? "": request.getParameter("searchText"); String sortName=request.getParameter("sortName")==null ? "roleId": request.getParameter("sortName"); String sortOrder=request.getParameter("sortOrder")==null ? "asc": request.getParameter("sortOrder"); Sort sortLocal = new Sort(sortOrder.equalsIgnoreCase("asc") ? Sort.Direction.ASC: Sort.Direction.DESC,sortName); Pageable pageable = PageRequest.of(pageNumber,pageSize,sortLocal); Page<User> userPage = userService.findAllByUserNameContains(strUserName,pageable); map.put("total",userPage.getTotalElements()); map.put("rows",userPage.getContent()); //如果使用外鍵,這里會出問題,需要在實體里添加注解忽略實體之間的相互引用。 return map; } @RequestMapping(value = "/add",method = RequestMethod.GET) @RequiresPermissions("user:add")//權限管理; public String toUserAdd(User user){ return "/user/userAdd"; } /** * 用戶添加; * @return */ @RequestMapping(value = "/add",method = RequestMethod.POST) @RequiresPermissions("user:add")//權限管理; @ResponseBody public String save(@Valid User user, BindingResult bindingResult, String password2){ if(bindingResult.hasErrors()) { return "0"; } user.setSalt(this.salt); if(user.getUserId()==null) { user.setCreateTime(LocalDateTime.now()); String encryptPwd = EncryptUtils.encrypt(user.getPassword(),user.getCredentialsSalt(),this.algorithmName,this.hashIterations); user.setPassword(encryptPwd); } else { if(!user.getPassword().equals(password2)) { String encryptPwd = EncryptUtils.encrypt(user.getPassword(),user.getCredentialsSalt(),this.algorithmName,this.hashIterations); user.setPassword(encryptPwd); } } try { userService.save(user); return "/user/ulist"; }catch (Exception e) { e.printStackTrace(); return "0"; } } @RequestMapping("/checkUserExists") @ResponseBody public Object checkRoleExists(@RequestParam String newUserName, @RequestParam(required = false) Integer userId, @RequestParam(required = false) String oldUserName) { Map<String,Boolean> map = new HashMap<>(); if(userId==null) { boolean result = !userService.checkUserExists(newUserName); map.put("valid",result); } else { boolean result = !userService.checkUserExists2(oldUserName,newUserName); map.put("valid",result); } return map; } @RequestMapping(value = "/edit/{id}") @RequiresPermissions("user:edit") public String edit(@PathVariable("id")Integer id, Map<String,Object> map) { User user = userService.findUserById(id).orElse(new User()); map.put("user",user); return "/user/userAdd"; } /** * 用戶刪除; * @return */ @RequestMapping("/delete") @ResponseBody @RequiresPermissions("user:del")//權限管理; public Object userDel(@RequestParam String userIdList){ if(userIdList==null || userIdList.isEmpty()) { return "0"; } String[] sList = userIdList.split(","); List<Integer> idList = new ArrayList<>(); for (String s:sList ) { if(s.equalsIgnoreCase("1")) return "0"; idList.add(Integer.parseInt(s)); } Map<String,String> map = new HashMap<>(); try { userService.deleteAllUserByUserIdList(idList); map.put("success","true"); map.put("url","/user/ulist"); }catch (Exception e) { e.printStackTrace(); map.put("error","true"); } return map; } @RequestMapping(value="/toListUserRole/{userId}") @RequiresPermissions("user:roleGrant") public String listUserRole(@PathVariable("userId")Integer userId, Map<String, Object> map) { User user = userService.findUserById(userId).orElse(new User()); map.put("user",user); return "/user/userRole"; } @RequestMapping(value = "/toGetUserRole/{userId}") @RequiresPermissions("user:roleGrant") @ResponseBody public Object getUserRole(@PathVariable("userId")Integer userId) { if(userId==null) return null; List<IUserRole> list = userService.findAllUserRoleByUserId(userId); return list; } @RequestMapping(value="/toGrantUserRole") @ResponseBody @RequiresPermissions("user:roleGrant") public Object grantUserRole(Integer userId, String roleIdList) { if(userId==1) return 0; Map<String,String> map = new HashMap<>(); if(roleIdList==null || roleIdList.isEmpty()) { try { userService.deleteAllUserRoleByUserId(userId); map.put("success","true"); map.put("url","/user/ulist"); return map; }catch (Exception e) { e.printStackTrace(); map.put("sucess","false"); map.put("url","/user/ulist"); return map; } } String[] sList = roleIdList.split(","); List<Integer> idList = new ArrayList<>(); for (String s:sList ) { idList.add(Integer.parseInt(s)); } try { userService.grantUserRole(userId,idList); map.put("sucess","true"); map.put("url","/user/ulist"); return map; }catch (Exception e) { e.printStackTrace(); map.put("sucess","false"); map.put("url","/user/ulist"); return map; } } @RequestMapping(value="/toChangePassword") public String toChangePassword(String password,String newPassword,String newPassword2) { return "/user/changePwd"; } @RequestMapping(value="/changePassword",method = RequestMethod.POST) @ResponseBody public Object changePassword(HttpServletRequest request) { Map<String,String> map = new HashMap<>(); String password = request.getParameter("password"); String newPassword = request.getParameter("newPassword"); String newPassword2 = request.getParameter("newPassword2"); if(newPassword==null) { map.put("success","false"); map.put("result","密碼不能為空"); return map; } if(!newPassword.equals(newPassword2)) { map.put("success","false"); map.put("result","兩次密碼輸入不一樣"); return map; } if(newPassword.length()<6) { map.put("success","false"); map.put("result","密碼長度必須大於6位"); return map; } String userName = loginService.getCurrentUserName(); if(userName==null || userName.isEmpty()) { map.put("success","false"); map.put("result","用戶錯誤"); return map; } User user = userService.findByUserName(userName); if(user==null) { map.put("success","false"); map.put("result","用戶錯誤"); return map; } String encryptPwd = EncryptUtils.encrypt(password,user.getCredentialsSalt(),this.algorithmName,this.hashIterations); if(!encryptPwd.equals(user.getPassword())) { map.put("success","false"); map.put("result","當前用戶密碼不正確"); return map; } String encryptNewPwd = EncryptUtils.encrypt(newPassword,user.getCredentialsSalt(),this.algorithmName,this.hashIterations); user.setPassword(encryptNewPwd); userService.save(user); map.put("success","true"); map.put("result","密碼修改成功,請重新登錄"); map.put("url","/logout"); return map; } @RequestMapping(value="/toCheckPwd") @ResponseBody public Object checkCurrentPwd(@RequestParam String password) { Map<String,Boolean> map = new HashMap<>(); if(password==null) { map.put("valid",false); return map; } String userName = loginService.getCurrentUserName(); if(userName==null || userName.isEmpty()) { map.put("valid",false); return map; } User user = userService.findByUserName(userName); if(user==null) { map.put("valid",false); return map; } String encryptPwd = EncryptUtils.encrypt(password,user.getCredentialsSalt(),this.algorithmName,this.hashIterations); if(!encryptPwd.equals(user.getPassword())) { map.put("valid",false); return map; } map.put("valid",true); return map; } }
RoleController
@Controller @RequestMapping("/user") public class RoleController { @Resource RoleService roleService; @RequestMapping(value="/role") @ResponseBody @RequiresPermissions("role:view") public Object getRole(HttpServletRequest request, HttpServletResponse response) { int pageSize = 10; try { pageSize = Integer.parseInt(request.getParameter("pageSize")); }catch (Exception e) { e.printStackTrace(); } int pageNumber=0 ; try { pageNumber = Integer.parseInt(request.getParameter("pageNumber"))-1; }catch (Exception e) { e.printStackTrace(); } Map<String, Object> map = new HashMap<>(); String strRole=request.getParameter("searchText")==null ? "": request.getParameter("searchText"); String sortName=request.getParameter("sortName")==null ? "roleId": request.getParameter("sortName"); String sortOrder=request.getParameter("sortOrder")==null ? "asc": request.getParameter("sortOrder"); Sort sortLocal = new Sort(sortOrder.equalsIgnoreCase("asc") ? Sort.Direction.ASC: Sort.Direction.DESC,sortName); Pageable pageable = PageRequest.of(pageNumber,pageSize,sortLocal); Page<SysRole> sysRolePage = roleService.findAllByRoleContains(strRole, pageable); map.put("total",sysRolePage.getTotalElements()); map.put("rows",sysRolePage.getContent()); return map; } @RequestMapping("/rlist") // @RequiresPermissions("user:view") public String list() { return "/user/roleList"; } @RequestMapping(value="/roleAdd", method= RequestMethod.GET) @RequiresPermissions("role:add") public String toAdd(SysRole sysRole) { return "/user/roleAdd"; } @RequestMapping(value="/roleAdd",method = RequestMethod.POST) @ResponseBody @RequiresPermissions("role:add") public String save(@Valid SysRole sysRole, BindingResult bindingResult) { if(bindingResult.hasErrors()) { return "0"; } if(sysRole.getCreateTime()==null) sysRole.setCreateTime(LocalDateTime.now()); try { roleService.save(sysRole); return "/user/rlist"; }catch (Exception e) { e.printStackTrace(); return "0"; } } @RequestMapping("/checkRoleExists") @ResponseBody public Object checkRoleExists(@RequestParam String newRole, @RequestParam(required = false) Integer roleId, @RequestParam(required = false) String oldRole) { Map<String,Boolean> map = new HashMap<>(); if(roleId==null) { boolean result = !roleService.checkRoleExists(newRole); map.put("valid",result); } else { boolean result = !roleService.checkRoleExists(oldRole,newRole); map.put("valid",result); } return map; } @RequestMapping(value = "/roleEdit/{id}") @RequiresPermissions("role:edit") public String edit(@PathVariable("id")Integer id, Map<String,Object> map) { SysRole sysRole = roleService.findById(id).orElse(new SysRole()); map.put("sysRole",sysRole); return "/user/roleAdd"; } @RequestMapping(value = "/roleDelete") @ResponseBody @RequiresPermissions("role:del") public Object delete(@RequestParam String roleIdList) { if(roleIdList==null || roleIdList.isEmpty()) { return "0"; } String[] sList = roleIdList.split(","); List<Integer> idList = new ArrayList<>(); for (String s:sList ) { if(s.equalsIgnoreCase("1")) return "0"; idList.add(Integer.parseInt(s)); } boolean result = roleService.deleteAllByRoleIdIn(idList); Map<String,String> map = new HashMap<>(); if(result) { map.put("success","true"); map.put("url","/user/rlist"); } else { map.put("error","true"); } return map; } @RequestMapping(value = "/plist/{roleId}") @RequiresPermissions("role:authorize") public String permissionList(@PathVariable("roleId")Integer roleId, Map<String, Object> map) { SysRole sysRole = roleService.findById(roleId).orElse(new SysRole()); map.put("sysRole",sysRole); return "/user/sysPermission"; } @RequestMapping("/getPermission/{roleId}") @ResponseBody @RequiresPermissions("role:authorize") public Object getRolePermission(@PathVariable("roleId")Integer roleId) { if(roleId==null) return null; List<ISysRolePermission> list = roleService.findSysRolePermissionByRoleId(roleId); return list; } //根據roleid授權 @RequestMapping(value = "/toAuthorize") @ResponseBody @RequiresPermissions("role:authorize") public Object toAuthorize(Integer roleId,String permissionIdList) { if(roleId==1) return 0; Map<String,String> map = new HashMap<>(); if(permissionIdList==null || permissionIdList.isEmpty()) { try { roleService.clearAuthorization(roleId); map.put("success","true"); map.put("url","/user/rlist"); return map; }catch (Exception e) { e.printStackTrace(); map.put("sucess","false"); map.put("url","/user/rlist"); return map; } } String[] sList = permissionIdList.split(","); List<Integer> idList = new ArrayList<>(); for (String s:sList ) { idList.add(Integer.parseInt(s)); } try { roleService.grantAuthorization(roleId,idList); map.put("sucess","true"); map.put("url","/user/rlist"); return map; }catch (Exception e) { e.printStackTrace(); map.put("sucess","false"); map.put("url","/user/rlist"); return map; } } }
代碼可以參考這個地址:https://github.com/asker124143222/bus