springboot---整合shiro

Shiro是一個非常不錯的權限框架,它提供了登錄和權限驗證功能
1.創建數據庫腳本

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for module
-- ----------------------------
DROP TABLE IF EXISTS `module`;
CREATE TABLE `module`  (`mid` int(11) NOT NULL AUTO_INCREMENT,`mname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`mid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of module
-- ----------------------------
INSERT INTO `module` VALUES (1, 'add');
INSERT INTO `module` VALUES (2, 'delete');
INSERT INTO `module` VALUES (3, 'query');
INSERT INTO `module` VALUES (4, 'update');-- ----------------------------
-- Table structure for module_role
-- ----------------------------
DROP TABLE IF EXISTS `module_role`;
CREATE TABLE `module_role`  (`rid` int(11) NULL DEFAULT NULL,`mid` int(11) NULL DEFAULT NULL,INDEX `rid`(`rid`) USING BTREE,INDEX `mid`(`mid`) USING BTREE,CONSTRAINT `mid` FOREIGN KEY (`mid`) REFERENCES `module` (`mid`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `rid` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of module_role
-- ----------------------------
INSERT INTO `module_role` VALUES (1, 1);
INSERT INTO `module_role` VALUES (1, 2);
INSERT INTO `module_role` VALUES (1, 3);
INSERT INTO `module_role` VALUES (1, 4);
INSERT INTO `module_role` VALUES (2, 1);
INSERT INTO `module_role` VALUES (2, 3);-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (`rid` int(11) NOT NULL AUTO_INCREMENT,`rname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`rid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, 'admin');
INSERT INTO `role` VALUES (2, 'customer');
INSERT INTO `role` VALUES (3, NULL);-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`uid` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'hlhdidi', '123');
INSERT INTO `user` VALUES (2, 'xyycici', '1992');
INSERT INTO `user` VALUES (3, 'sujin', '123');-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role`  (`uid` int(11) NULL DEFAULT NULL,`rid` int(11) NULL DEFAULT NULL,INDEX `u_fk`(`uid`) USING BTREE,INDEX `r_fk`(`rid`) USING BTREE,CONSTRAINT `r_fk` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `u_fk` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES (1, 1);
INSERT INTO `user_role` VALUES (2, 2);
INSERT INTO `user_role` VALUES (3, 3);SET FOREIGN_KEY_CHECKS = 1;

當新添加一個用戶時,只需要配置權限即可,module_role表中已經配置了什么權限擁有什么樣的功能

SELECT u.*,r.*,m.* FROM user u inner join user_role ur on ur.uid=u.uidinner join role r on r.rid=ur.ridinner join module_role mr on mr.rid=r.ridinner join module m on mr.mid=m.midWHERE username='hlhdidi'; -- xyycici用戶已分配只要兩個權限 add和query

2.pom.xml中添加Springboot集成shiro的相關依賴

<!-- shiro整合springboot所需相關依賴--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.2.5</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.5</version></dependency><dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>1.2.1</version></dependency>
<!--end.......-->

3.創建實體類
僅列出關鍵實體類,其他實體類無需改動

用戶

package com.king.s5.model;import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
//用戶
public class User implements Serializable{private Integer uid;private String username;private String password;private Set<Role> roles = new HashSet<>();public User(Integer uid, String username, String password) {this.uid = uid;this.username = username;this.password = password;}public User() {super();}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Set<Role> getRoles() {return roles;}public void setRoles(Set<Role> roles) {this.roles = roles;}
}

功能

package com.king.s5.model;import java.util.HashSet;
import java.util.Set;
//功能
public class Module {private Integer mid;private String mname;private Set<Role> roles;public Module(Integer mid, String mname) {this.mid = mid;this.mname = mname;}public Module() {super();}public Integer getMid() {return mid;}public void setMid(Integer mid) {this.mid = mid;}public String getMname() {return mname;}public void setMname(String mname) {this.mname = mname;}public Set<Role> getRoles() {return roles;}public void setRoles(Set<Role> roles) {this.roles = roles;}
}

權限

public class Role {private Integer rid;private String rname;private Set<User> users = new HashSet<>();private Set<Module> Modules = new HashSet<>();public Role(Integer rid, String rname) {this.rid = rid;this.rname = rname;}public Role() {super();}public Integer getRid() {return rid;}public void setRid(Integer rid) {this.rid = rid;}public String getRname() {return rname;}public void setRname(String rname) {this.rname = rname;}public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}public Set<Module> getModules() {return Modules;}public void setModules(Set<Module> modules) {Modules = modules;}
}

4.編寫持久層mapper.xml
userMapper.xml,本次只寫到mapper層,不做service層(僅列出關鍵mapper.xml),其他xml無需改變

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.king.s5.mapper.UserMapper" ><resultMap id="BaseResultMap" type="com.king.s5.model.User" ><constructor ><idArg column="uid" jdbcType="INTEGER" javaType="java.lang.Integer" /><arg column="username" jdbcType="VARCHAR" javaType="java.lang.String" /><arg column="password" jdbcType="VARCHAR" javaType="java.lang.String" /></constructor></resultMap><resultMap type="com.king.s5.model.User" id="userMap"><id property="uid" column="uid"/><result property="username" column="username"/><result property="password" column="password"/><collection property="roles" ofType="com.king.s5.model.Role"><id property="rid" column="rid"/><result property="rname" column="rname"/><collection property="modules" ofType="com.king.s5.model.Module"><id property="mid" column="mid"/><result property="mname" column="mname"/></collection></collection></resultMap><sql id="Base_Column_List" >uid, username, password</sql><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select <include refid="Base_Column_List" />from userwhere uid = #{uid,jdbcType=INTEGER}</select><select id="queryUserName" parameterType="string" resultMap="userMap">SELECT u.*,r.*,m.* FROM user u inner join user_role ur on ur.uid=u.uidinner join role r on r.rid=ur.ridinner join module_role mr on mr.rid=r.ridinner join module m on mr.mid=m.midWHERE username=#{username};</select><delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >delete from userwhere uid = #{uid,jdbcType=INTEGER}</delete><insert id="insert" parameterType="com.king.s5.model.User" >insert into user (uid, username, password)values (#{uid,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR})</insert><insert id="insertSelective" parameterType="com.king.s5.model.User" >insert into user<trim prefix="(" suffix=")" suffixOverrides="," ><if test="uid != null" >uid,</if><if test="username != null" >username,</if><if test="password != null" >password,</if></trim><trim prefix="values (" suffix=")" suffixOverrides="," ><if test="uid != null" >#{uid,jdbcType=INTEGER},</if><if test="username != null" >#{username,jdbcType=VARCHAR},</if><if test="password != null" >#{password,jdbcType=VARCHAR},</if></trim></insert><update id="updateByPrimaryKeySelective" parameterType="com.king.s5.model.User" >update user<set ><if test="username != null" >username = #{username,jdbcType=VARCHAR},</if><if test="password != null" >password = #{password,jdbcType=VARCHAR},</if></set>where uid = #{uid,jdbcType=INTEGER}</update><update id="updateByPrimaryKey" parameterType="com.king.s5.model.User" >update userset username = #{username,jdbcType=VARCHAR},password = #{password,jdbcType=VARCHAR}where uid = #{uid,jdbcType=INTEGER}</update>
</mapper>

moduleMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.king.s5.mapper.ModuleMapper" ><resultMap id="BaseResultMap" type="com.king.s5.model.Module" ><constructor ><idArg column="mid" jdbcType="INTEGER" javaType="java.lang.Integer" /><arg column="mname" jdbcType="VARCHAR" javaType="java.lang.String" /></constructor></resultMap><sql id="Base_Column_List" >mid, mname</sql><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select <include refid="Base_Column_List" />from modulewhere mid = #{mid,jdbcType=INTEGER}</select><delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >delete from modulewhere mid = #{mid,jdbcType=INTEGER}</delete><insert id="insert" parameterType="com.king.s5.model.Module" >insert into module (mid, mname)values (#{mid,jdbcType=INTEGER}, #{mname,jdbcType=VARCHAR})</insert><insert id="insertSelective" parameterType="com.king.s5.model.Module" >insert into module<trim prefix="(" suffix=")" suffixOverrides="," ><if test="mid != null" >mid,</if><if test="mname != null" >mname,</if></trim><trim prefix="values (" suffix=")" suffixOverrides="," ><if test="mid != null" >#{mid,jdbcType=INTEGER},</if><if test="mname != null" >#{mname,jdbcType=VARCHAR},</if></trim></insert><update id="updateByPrimaryKeySelective" parameterType="com.king.s5.model.Module" >update module<set ><if test="mname != null" >mname = #{mname,jdbcType=VARCHAR},</if></set>where mid = #{mid,jdbcType=INTEGER}</update><update id="updateByPrimaryKey" parameterType="com.king.s5.model.Module" >update moduleset mname = #{mname,jdbcType=VARCHAR}where mid = #{mid,jdbcType=INTEGER}</update>
</mapper>

5.添加shiro的工具類
認證授權工具類

package com.king.s5.shiro;import com.king.s5.biz.IUserBiz;
import com.king.s5.mapper.UserMapper;
import com.king.s5.model.Module;
import com.king.s5.model.Role;
import com.king.s5.model.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;import java.util.ArrayList;
import java.util.List;
import java.util.Set;public class AuthRealm extends AuthorizingRealm {@Autowiredprivate UserMapper userMapper;//認證.登錄@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken utoken=(UsernamePasswordToken) token;//獲取用戶輸入的tokenString username = utoken.getUsername();User user = userMapper.queryUserName(username);//放入shiro.調用CredentialsMatcher檢驗密碼return new SimpleAuthenticationInfo(user, user.getPassword(),this.getClass().getName());}//授權@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {//獲取session中的用戶User user=(User) principal.fromRealm(this.getClass().getName()).iterator().next();List<String> permissions=new ArrayList<>();Set<Role> roles = user.getRoles();if(roles.size()>0) {for(Role role : roles) {Set<Module> modules = role.getModules();if(modules.size()>0) {for(Module module : modules) {permissions.add(module.getMname());}}}}SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();//將權限放入shiro中.info.addStringPermissions(permissions);return info;}
}

權限用戶密碼校驗類

package com.king.s5.shiro;import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;public class CredentialsMatcher extends SimpleCredentialsMatcher {//校驗@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {UsernamePasswordToken utoken=(UsernamePasswordToken) token;//獲得用戶輸入的密碼:(可以采用加鹽(salt)的方式去檢驗)String inPassword = new String(utoken.getPassword());//獲得數據庫中的密碼String dbPassword=(String) info.getCredentials();//進行密碼的比對return this.equals(inPassword, dbPassword);}
}

shiro配置類

package com.king.s5.shiro;import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;/*** shiro的配置類* @author sujin**/
@Configuration
public class ShiroConfiguration {@Bean(name="shiroFilter")public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();bean.setSecurityManager(manager);//配置登錄的url和登錄成功的urlbean.setLoginUrl("/login");bean.setSuccessUrl("/home");//配置訪問權限LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();filterChainDefinitionMap.put("/login*", "anon"); //表示可以匿名訪問filterChainDefinitionMap.put("/loginUser", "anon");filterChainDefinitionMap.put("/client/test", "anon");filterChainDefinitionMap.put("/assert/test", "anon");//添加白名單filterChainDefinitionMap.put("/assert/get", "anon");//添加白名單filterChainDefinitionMap.put("/assert/assertQuery", "anon");//添加白名單filterChainDefinitionMap.put("/a", "anon");filterChainDefinitionMap.put("/book/list", "anon");filterChainDefinitionMap.put("/logout*","anon");filterChainDefinitionMap.put("/jsp/error.jsp*","anon");filterChainDefinitionMap.put("/jsp/login.jsp*","authc");filterChainDefinitionMap.put("/*", "authc");//表示需要認證才可以訪問filterChainDefinitionMap.put("/**", "authc");//表示需要認證才可以訪問filterChainDefinitionMap.put("/*.*", "authc");bean.setFilterChainDefinitionMap(filterChainDefinitionMap);return bean;}//配置核心安全事務管理器@Bean(name="securityManager")public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {System.err.println("--------------shiro已經加載----------------");DefaultWebSecurityManager manager=new DefaultWebSecurityManager();manager.setRealm(authRealm);return manager;}//配置自定義的權限登錄器@Bean(name="authRealm")public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {AuthRealm authRealm=new AuthRealm();authRealm.setCredentialsMatcher(matcher);return authRealm;}//配置自定義的密碼比較器@Bean(name="credentialsMatcher")public CredentialsMatcher credentialsMatcher() {return new CredentialsMatcher();}@Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){return new LifecycleBeanPostProcessor();}@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();creator.setProxyTargetClass(true);return creator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();advisor.setSecurityManager(manager);return advisor;}
}

6.控制層controller

package com.king.s5.controller;import com.king.s5.model.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpSession;@Controller
public class LoginController {@RequestMapping("/login")public String login() {return "login";}@RequestMapping("/a")public String a() {return "a";}@RequestMapping("/loginUser")public String loginUser(String username,String password,HttpSession session) {//授權認證UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);Subject subject = SecurityUtils.getSubject();try {//完成登錄subject.login(usernamePasswordToken);//獲得用戶對象User user=(User) subject.getPrincipal();//存入sessionsession.setAttribute("user", user);return "index";} catch(Exception e) {return "login";//返回登錄頁面}}@RequestMapping("/logOut")public String logOut(HttpSession session) {Subject subject = SecurityUtils.getSubject();subject.logout();
//        session.removeAttribute("user");return "login";}
}

7.視圖層jsp
login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head><title>登錄</title>
</head><h1>歡迎登錄!${user.username }</h1>
<form action="${pageContext.request.contextPath }/loginUser" method="post"><input type="text" name="username"><br><input type="password" name="password"><br><input type="submit" value="提交">
</form>
</body>
</html>

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html>
<html lang="en">
<head><title>登錄</title>
</head><h1>歡迎${user.username }光臨!請選擇你的操作:</h1><br>
<ul><shiro:hasPermission name="add"><li>增加</li></shiro:hasPermission><shiro:hasPermission name="delete"><li>刪除</li></shiro:hasPermission><shiro:hasPermission name="update"><li>修改</li></shiro:hasPermission><shiro:hasPermission name="query"><li>查詢</li></shiro:hasPermission></ul>
<a href="${pageContext.request.contextPath }/logOut">點我注銷</a>
</body>
</html>

8.shiro標簽的使用

guest標簽驗證當前用戶是否為“訪客”,即未認證(包含未記住)的用戶
user標簽認證通過或已記住的用戶
authenticated標簽已認證通過的用戶。不包含已記住的用戶,這是與user標簽的區別所在未認證通過用戶,與authenticated標簽相對應。與guest標簽的區別是,該標簽包含已記住用戶
notAuthenticated標簽
principal 標簽輸出當前用戶信息,通常為登錄帳號信息
hasRole標簽驗證當前用戶是否屬于該角色
lacksRole標簽與hasRole標簽邏輯相反,當用戶不屬于該角色時驗證通過
hasAnyRole標簽驗證當前用戶是否屬于以下任意一個角色
hasPermission標簽驗證當前用戶是否擁有指定權限
lacksPermission標簽與hasPermission標簽邏輯相反,當前用戶沒有制定權限時,驗證通過

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250083.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250083.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250083.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Head First Java] - 線程共享數據問題

參考 - P507 1. 說明 兩個線程共享同一份數據,每次使用數據時,需要先判斷其是否在合理范圍每次使用數據完畢使用Thread.sleep函數讓線程阻塞 2.代碼 class BankAccount {private int balance 100;public int getBalance() {return balance;}public void withdraw(int amou…

asp.net中提交表單數據時提示從客戶端(。。。)中檢測到有潛在危險的 Request.Form 值...

看到這個圖是不是很親切熟悉哈&#xff0c;做過。net的肯定都見過哈 已經 將近4年沒碰。net了&#xff0c;今天正好朋友的程序有幾個bug,讓我幫忙修復下&#xff0c;于是我就抱著試試看的心情改了改&#xff0c;改到最后一個問題的時候也就是上面的這個問題&#xff0c;我一看&…

Openresty編寫Lua代碼一例

1.前段時間糾結了很久&#xff0c;一直弄不清lua和tomcat的聯系。一直認為是lua調用tomcat的接口才可使用&#xff0c;后面才明白過來&#xff0c;進入了一個誤區&#xff0c;lua本身就是一門獨立的腳本語言。在openresty里面配置好&#xff0c;即可編寫映射和響應。 下面是自己…

Shiro表結構設計

表設計 開發用戶-角色-權限管理系統&#xff0c;首先我們需要知道用戶-角色-權限管理系統的表結構設計。 在用戶-角色-權限管理系統找那個一般會涉及5張表&#xff0c;分別為&#xff1a; 1.sys_users用戶表 2.sys_roles角色表 3.sys_permissions權限表&#xff08;或資源表&…

[Java核心技術(卷I)] - 簡易的日歷

參考 - P102~P103 1. 目標 生成一個日歷,格式如下圖所示。 ps: 當前的天數需要標記為* 2. 核心 對日歷的變量 import java.time.*; public class CalendarTest{public static void main(String[] args) {LocalDate date LocalDate.now(); // 獲取當前日期int month date…

個人作業——福大微信公眾號使用評測

案例分析&#xff1a;在福州大學公眾號上&#xff0c;我們可以即時使用手機關注福大新聞&#xff0c;查看自身課表、成績等。公眾號可能存在一些小bug影響同學們的用戶體驗。本次作業中&#xff0c;作為一個用戶——福大的學生&#xff0c;將切身體驗該公眾號的功能&#xff0c…

在winform中使用wpf窗體

在winform項目&#xff0c;通過引用dll可以添加WPF窗體&#xff0c;如下 但是如果直接在winform的項目中添加wpf窗體還是有部分問題&#xff0c;圖片的顯示。 直接在XAML界面中用Source屬性設置圖片會出現錯誤。必須通過后臺代碼的方式來實現。 image1.Source GetImageIcon(gl…

shiro---注解

RequiresAuthentication 驗證用戶是否登錄&#xff0c;等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶是否被記憶&#xff0c;user有兩種含義&#xff1a; 一種是成功登錄的&#xff08;subject.isAuthenticated() 結果為true&#xff09;&…

[Java核心技術(卷I)] - Java中的參數能做什么和不能做什么

1. 參考 - P123 ~ P126 2. 你將學到 Java中對方法參數能做什么和不能做什么 方法不能修改基本數據類型的參數(數值型或布爾型)方法可以改變對象參數的狀態方法不能讓一個對象參數引用一個新的對象 3. 代碼證明 public class ParamTest {public static void main(String[] ar…

軟件構造 第五章第一節 可復用性的度量、形態和外部觀察

第五章第一節 可復用性的度量、形態和外部觀察 面向復用編程(programming for reuse)&#xff1a;開發出可復用的軟件 基于復用編程(programming with reuse)&#xff1a;利用已有的可復用軟件搭建應用系統 代碼復用的類型&#xff1a; 白盒復用&#xff1a;源代碼可見&#x…

洛谷團隊月賽題:題解

10pts10pts10pts 暴力算不解釋&#xff0c;時間復雜度O(knk2)O(knk^2)O(knk2)。 30pts30pts30pts 我們觀察到nnn很大&#xff0c;楊輝三角會T&#xff0c;直接算會上溢&#xff0c;所以需要預處理出111~kkk逆元再算&#xff0c;時間復雜度O(knnlogkn2)O(knnlogkn^2)O(knnlogkn2…

Angular Forms - 自定義 ngModel 綁定值的方式

在 Angular 應用中&#xff0c;我們有兩種方式來實現表單綁定——“模板驅動表單”與“響應式表單”。這兩種方式通常能夠很好的處理大部分的情況&#xff0c;但是對于一些特殊的表單控件&#xff0c;例如input[typedatetime]、input[typefile]&#xff0c;我們需要重寫默認的表…

[web性能優化] - 使用在線工具對html、js、css進行壓縮

參考 1. 學習點 使用 在線工具對html、css、js進行壓縮學會分析壓縮前后的效率提高點 2. 解決方案: 2.1 HTML壓縮 在線壓縮nodejs提供了 html-minifier工具(在構建層對代碼進行壓縮)后端模板引擎渲染壓縮 2.2 CSS壓縮 使用html-minifier對html中的css進行壓縮使用clean-cs…

【LOJ】 #2540. 「PKUWC2018」隨機算法

題解 感覺極其神奇的狀壓dp \(dp[i][S]\)表示答案為i&#xff0c;然后不可選的點集為S 我們每次往答案里加一個點&#xff0c;然后方案數是&#xff0c;設原來可以選的點數是y&#xff0c;新加入一個點后導致了除了新加的點之外x個點不能選&#xff0c;那么方案就是把x個數在y …

Shiro的authc過濾器的執行流程

1.先執行isAccessAllowed()&#xff0c;通過subject.isAuthenticated()判斷當前session中的subject是否已經登陸過。如果在當前session即會話中已經登陸過&#xff0c;返回true&#xff0c;authc過濾器放行請求到loginUrl。 問題? 這里會有一個問題&#xff0c;如果我登陸成功…

SpringBoot之基礎

簡介 背景 J2EE笨重的開發 / 繁多的配置 / 低下的開發效率 / 復雜的部署流程 / 第三方技術集成難度大 特點 ① 快速創建獨立運行的spring項目以及主流框架集成 ② 使用嵌入式的Servlet容器, 應用無需達成war包 ③ starters自動依賴和版本控制 ④ 大量自動配置, 簡化開發, 也可修…

[Java核心技術(卷I)] - vscode手動編譯運行繼承類

參考 - P160~P161 主要有3個類: 一個測試類(ManagerTest)、一個子類(Manager)、一個父類(Employee) 注意點: -1. 使用 javac -d . *.java進行預編譯 目錄結構入下: 此時會生成目錄結構如下: 之后運行 java com.inheritance.ManagerTest 附上幾個類的代碼 // com.inhe…

mysql常用語句和函數

mysql語句如果長期不寫&#xff0c;就會忘掉&#xff0c;所以要時常復習&#xff0c;溫故而知新。 1.select length("中國人"),select char_length("中國人"); 2建立數據庫的語句 use new_schema;create table ta(id int primary key);這是小括號&#xff…

shiro框架@RequiresPermissions 解釋

RequiresAuthentication 驗證用戶是否登錄&#xff0c;等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶是否被記憶&#xff0c;user有兩種含義&#xff1a; 一種是成功登錄的&#xff08;subject.isAuthenticated() 結果為true&#xff09;&…

【Social Listening實戰】當數據分析遭遇心理動力學:用戶深層次的情感需求浮出水面...

本文轉自知乎 作者&#xff1a;蘇格蘭折耳喵 ————————————————————————————————————————————————————— 本文篇幅較長&#xff0c;分為五部分&#xff0c;在中間部分有關于心理分析工具的介紹&#xff0c;案例分散在第二部…