springBoot整合shiro如何解決讀取不到@value值問題
springBoot整合shiro讀取不到@value值
1、通過@value將值注入shiroconfigure靜態(tài)屬性
private static String dropmenu_post; @Value("${dropmenu.post}") public void setDropmenu_post(String dropmenu_post) { ShiroConfig.dropmenu_post = dropmenu_post; }
2、將LifecycleBeanPostProcessor獲取該對象的方法設(shè)為靜態(tài)
@Bean public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); }
3、使用
@Bean(name = "shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean( @Qualifier("securityManager") SecurityManager securityManager) { ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean(); sfb.setSecurityManager(securityManager); sfb.setLoginUrl(ShiroConfig.dropmenu_post + "/login"); sfb.setSuccessUrl("/report/list"); sfb.setUnauthorizedUrl("/goLogin"); Map<String, Filter> filters = new HashMap<>(); filters.put("per", getPermissionFilter()); // filters.put("verCode",getVerfityCodeFilter()); sfb.setFilters(filters); Map<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/resources/**", "anon"); filterMap.put("/fx/**", "anon"); filterMap.put("/fx2/**", "anon"); filterMap.put("/process/**", "anon"); filterMap.put("/repeat/**", "anon"); filterMap.put("/repeat2/**", "anon"); filterMap.put("/ipad/**", "anon"); filterMap.put("/student/**", "anon"); filterMap.put("/excel/**", "anon"); filterMap.put("/exam/**", "anon"); filterMap.put("/progress/**", "anon"); filterMap.put("/param/**", "anon"); filterMap.put("/statics/**", "anon"); filterMap.put("/download/**", "anon"); filterMap.put("/knowledge/**", "anon"); filterMap.put("/login", "anon"); filterMap.put("/actuator/**", "anon"); filterMap.put("/hystrix", "anon"); filterMap.put("/hystrix.stream", "anon"); filterMap.put("/logout", "logout"); filterMap.put("/js/**", "anon"); filterMap.put("/css/**", "anon"); filterMap.put("/user/**", "per"); filterMap.put("/**", "authc"); sfb.setFilterChainDefinitionMap(filterMap); return sfb; }
整個類的代碼如下
package com.whty.hxx.config; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.Filter; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.mgt.SecurityManager; 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.web.servlet.Cookie; import org.apache.shiro.web.servlet.ShiroHttpSession; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.DelegatingFilterProxy; import com.whty.hxx.common.filter.PermissionFilter; import com.whty.hxx.common.shiro.LoginRealm; import com.whty.hxx.common.shiro.MyWebSessionManager; import com.whty.hxx.common.shiro.ShiroUtil; import com.whty.hxx.common.shiro.redis.RedisSessionDAO; import com.whty.hxx.common.shiro.redis.ShiroRedisCacheManager; import lombok.extern.slf4j.Slf4j; /** * @author yym * @date 2018/5/31. spring shiro 配置 */ @Configuration @Slf4j public class ShiroConfig { private static String dropmenu_post; @Value("${dropmenu.post}") public void setDropmenu_post(String dropmenu_post) { ShiroConfig.dropmenu_post = dropmenu_post; } @Bean(value = "ehCacheManager") public EhCacheManager ehCacheManager() { EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManagerConfigFile("classpath:ehcache/ehcache.xml"); return ehCacheManager; } // @Bean(name="credentialsMatcher") // public RetryLimitCredentialsMatcher // getRetryLimitCredentialsMatcher(@Qualifier("redisCacheManager") // ShiroSpringCacheManager redisCacheManager){ RetryLimitCredentialsMatcher rm = new // RetryLimitCredentialsMatcher(getCacheManager(),2); // RetryLimitCredentialsMatcher rm = new // RetryLimitCredentialsMatcher(redisCacheManager); // rm.setHashAlgorithmName("md5"); // rm.setHashIterations(4); // return rm; // // } // @Bean(name = "redisCacheManager") // public ShiroRedisCacheManager redisCacheManager() { // log.debug("ShiroConfiguration.redisCacheManager()"); // return new ShiroRedisCacheManager(); // } @Bean(name = "redisSessionDAO") public RedisSessionDAO redisSessionDAO() { log.debug("ShiroConfiguration.redisSessionDAO()"); return new RedisSessionDAO(); } @Bean(name = "loginRealm") public LoginRealm getLoginRealm(@Qualifier("redisCacheManager") ShiroRedisCacheManager redisCacheManager) { LoginRealm realm = new LoginRealm(); // 密碼匹配校驗?? HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("md5"); credentialsMatcher.setHashIterations(4); realm.setCredentialsMatcher(credentialsMatcher); realm.setCacheManager(redisCacheManager); // realm.setCachingEnabled(true); return realm; } @Bean public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } // /** // * // * enterCacheSessionDAO:(EnterpriseCacheSessionDAO shiro sessionDao層的實現(xiàn)??). // <br/> // * 提供了緩存功能的會話維護,默認情況下使用MapCache實現(xiàn),內(nèi)部使用ConcurrentHashMap保存緩存的會話???.<br/> // * // * @author verywell // * @return // * @since JDK 1.8 // */ // @Bean(name="redisCacheSessionDAO") // public RedisSessionDao // getEnterCacheSessionDAO(@Qualifier("redisCacheManager") // ShiroSpringCacheManager redisCacheManager) { // RedisSessionDao enterCacheSessionDAO = new RedisSessionDao(); // //添加緩存管理?? // enterCacheSessionDAO.setCacheManager(redisCacheManager); 添加ehcache活躍緩存名稱(必須和ehcache緩存名稱??致) enterCacheSessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache"); // return enterCacheSessionDAO; // } // @Bean(name="sessionValidationScheduler") // public MyQuartzSessionValidationScheduler // getQuartzSessionValidationScheduler(@Qualifier("redisSessionDAO")RedisSessionDAO // sessionDAO // ,@Qualifier("redisCacheManager") ShiroRedisCacheManager redisCacheManager) { // MyQuartzSessionValidationScheduler sessionValidationScheduler = new // MyQuartzSessionValidationScheduler(); // sessionValidationScheduler.setSessionValidationInterval(10000); // DefaultWebSessionManager sessionManager=new DefaultWebSessionManager(); // sessionManager.setCacheManager(redisCacheManager); // sessionManager.setSessionDAO(sessionDAO); // sessionValidationScheduler.setSessionManager(sessionManager); // return sessionValidationScheduler; // } @Bean(name = "sessionManager") public DefaultWebSessionManager getSessionManager(@Qualifier("redisSessionDAO") RedisSessionDAO sessionDAO, @Qualifier("redisCacheManager") ShiroRedisCacheManager cacheManager) { MyWebSessionManager sessionManager = new MyWebSessionManager(); sessionManager.setSessionIdUrlRewritingEnabled(false);// sessionId不顯示在url?? sessionManager.setCacheManager(cacheManager); sessionManager.setSessionDAO(sessionDAO); // sessionManager.setGlobalSessionTimeout(2000); // sessionManager.setSessionValidationScheduler(sessionValidationScheduler); // sessionManager.setSessionValidationInterval(3000); // 創(chuàng)建會話Cookie Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME); cookie.setName(ShiroUtil.name_serssionId); cookie.setHttpOnly(true); sessionManager.setSessionIdCookie(cookie); return sessionManager; } @Bean(name = "securityManager") public SecurityManager getSecurityManager(@Qualifier("loginRealm") LoginRealm loginRealm, @Qualifier("sessionManager") DefaultWebSessionManager sessionManager, @Qualifier("redisCacheManager") ShiroRedisCacheManager cacheManager) { DefaultWebSecurityManager dwm = new DefaultWebSecurityManager(); dwm.setRealm(loginRealm); // dwm.setCacheManager(cacheManager); dwm.setSessionManager(sessionManager); return dwm; } @Bean public PermissionFilter getPermissionFilter() { PermissionFilter pf = new PermissionFilter(); return pf; } // @Bean // public VerfityCodeFilter getVerfityCodeFilter(){ // VerfityCodeFilter vf= new VerfityCodeFilter(); // vf.setFailureKeyAttribute("shiroLoginFailure"); // vf.setJcaptchaParam("code"); // vf.setVerfitiCode(true); // return vf; // } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean( @Qualifier("securityManager") SecurityManager securityManager) { ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean(); sfb.setSecurityManager(securityManager); sfb.setLoginUrl(ShiroConfig.dropmenu_post + "/login"); sfb.setSuccessUrl("/report/list"); sfb.setUnauthorizedUrl("/goLogin"); Map<String, Filter> filters = new HashMap<>(); filters.put("per", getPermissionFilter()); // filters.put("verCode",getVerfityCodeFilter()); sfb.setFilters(filters); Map<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/resources/**", "anon"); filterMap.put("/fx/**", "anon"); filterMap.put("/fx2/**", "anon"); filterMap.put("/process/**", "anon"); filterMap.put("/repeat/**", "anon"); filterMap.put("/repeat2/**", "anon"); filterMap.put("/ipad/**", "anon"); filterMap.put("/student/**", "anon"); filterMap.put("/excel/**", "anon"); filterMap.put("/exam/**", "anon"); filterMap.put("/progress/**", "anon"); filterMap.put("/param/**", "anon"); filterMap.put("/statics/**", "anon"); filterMap.put("/download/**", "anon"); filterMap.put("/knowledge/**", "anon"); // //===== 測試 // filterMap.put("/test/**","anon"); // filterMap.put("/report/**","anon"); // filterMap.put("/upload/**","anon"); // filterMap.put("/city/**","anon"); // filterMap.put("/county/**","anon"); // filterMap.put("/unitSchool/**","anon"); // filterMap.put("/regionSchool/**","anon"); // filterMap.put("/school/**","anon"); // filterMap.put("/clazz/**","anon"); // filterMap.put("/clazzEvaluation/**","anon"); // filterMap.put("/schoolEvaluation/**","anon"); // filterMap.put("/canvas/**","anon"); // //===== end filterMap.put("/login", "anon"); filterMap.put("/actuator/**", "anon"); filterMap.put("/hystrix", "anon"); filterMap.put("/hystrix.stream", "anon"); filterMap.put("/logout", "logout"); filterMap.put("/js/**", "anon"); filterMap.put("/css/**", "anon"); filterMap.put("/user/**", "per"); filterMap.put("/**", "authc"); sfb.setFilterChainDefinitionMap(filterMap); return sfb; } @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor( @Qualifier("securityManager") SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor as = new AuthorizationAttributeSourceAdvisor(); as.setSecurityManager(securityManager); return as; } @Bean public FilterRegistrationBean delegatingFilterProxy() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); DelegatingFilterProxy proxy = new DelegatingFilterProxy(); proxy.setTargetFilterLifecycle(true); proxy.setTargetBeanName("shiroFilter"); filterRegistrationBean.setFilter(proxy); return filterRegistrationBean; } }
springboot單元測試使用@value讀取不到值, yml的兩個坑
yml兩個坑
yml 和 properties都可以作為配置文件在springboot項目中使用
縮進問題
yml使用空格縮進代表包之間的層級問題,有時候差一個空格就可能導(dǎo)致配置不生效。另外,在同級配置之間使用 # 注釋
也會導(dǎo)致該問題,因為程序是按層級讀取配置的,加上注釋隔斷上下兩行之后,程序會不清楚下一條配置是上一個的下級還是同級(大致是這意思。。。)
springboot 2.X版本在單元測試中讀取不到y(tǒng)ml配置文件的值
這是個大坑,在項目中寫單元測試的時候需要讀取一個yml配置文件的值,發(fā)現(xiàn)無論如何都讀取不到,后來發(fā)現(xiàn)了這個坑。改成properties就行了。
總結(jié)
建議用properties!
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java基本數(shù)據(jù)類型存儲在JVM中的存儲位置介紹
這篇文章主要介紹了Java基本數(shù)據(jù)類型存儲在JVM中的存儲位置,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07springboot集成flyway自動創(chuàng)表的詳細配置
Flayway是一款數(shù)據(jù)庫版本控制管理工具,支持數(shù)據(jù)庫版本自動升級,Migrations可以寫成sql腳本,也可以寫在java代碼里;本文通過實例代碼給大家介紹springboot集成flyway自動創(chuàng)表的詳細過程,感興趣的朋友一起看看吧2021-06-06SpringBoot實現(xiàn)數(shù)據(jù)庫讀寫分離的3種方法小結(jié)
為了提高系統(tǒng)的讀寫性能和可用性,讀寫分離是一種經(jīng)典的數(shù)據(jù)庫架構(gòu)模式,在SpringBoot應(yīng)用中,有多種方式可以實現(xiàn)數(shù)據(jù)庫讀寫分離,本文將介紹三種主實現(xiàn)方案,大家可以根據(jù)需要自行選擇2025-04-04Spring AI與DeepSeek實戰(zhàn)一之快速打造智能對話應(yīng)用
本文詳細介紹了如何通過SpringAI框架集成DeepSeek大模型,實現(xiàn)普通對話和流式對話功能,步驟包括申請API-KEY、項目搭建、配置API-KEY、創(chuàng)建ChatClient對象、創(chuàng)建對話接口、切換模型、使用prompt模板、流式對話等,感興趣的朋友一起看看吧2025-03-03Java?spring注解@PostConstruct實戰(zhàn)案例講解
我們在Spring項目中經(jīng)常會遇到@PostConstruct注解,可能有的伙伴對這個注解很陌生,下面這篇文章主要給大家介紹了關(guān)于Java?spring注解@PostConstruct實戰(zhàn)案例講解的相關(guān)資料,需要的朋友可以參考下2023-12-12