IntelliJ IDEA Spring Boot(6) 集成Hibernate+Shiro+Ehcache
2017-10-28 22:04
716 查看
说真的用spring boot 集成集成Hibernate+Shiro+Ehcache。费了我老大的功夫啊。
但这一切都是值得。
1. 首先第一点,以前用xml配置shiro的,将失效。错误的说法,可以使用xml。
2. 以前xml中配置的bean,请在加@Configuration注解的类中定义方法并加上注解
@Bean,最好写上name属性,不然以方法名命名bean的名字
下面开始配置吧。
第一: 集成hibernate。这一步骤,http://blog.csdn.net/u011998835/article/details/78369721已经介绍了。但是我稍微做一下修改。
这里不再定义SessionFactory的注入了。改成下面的方式
还有就是我一直忽略的问题,这里补充一下,就是Druid数据源监控页面并没有配置。
这里新增一下。
这里@Bean我没有给name属性赋值,那么它的值就是 方法名字
其实上述代码就是以前web.xml中配置的如下代码的转换
上面的集成完毕之后,解析来集成shiro。
以前shiro是配置在 xml中,类似这样
但是用springboot 就不能这样写了。应慢慢修改成对应下面的java代码,我也是很辛苦的一一对应的写上的。
基本上一一对应。但这里有两个个巨坑。
就是url的拦截,请细致小心的配置,不要直接/**什么的,会导致最基本的登陆请求都完成不了,我就在这吃了大亏。因为在xml中那样配置没有问题,但是写成java代码,差点没坑死我。
第二个坑,我找了好长好长时间。 因为上一篇只集成hibernate的时候,并没有报异常。Could not obtain transaction-synchronized Session for current thread
可是加上ShiroConfig,怎么都报这个异常。刚开始使用配置openSessionInViewFilter,起点作用,但是在单元测试的时候,还是抱上述异常。我就非常纳闷,我尝试先关闭shiroConfig,然后发现单元测试就不报异常了。所以我觉得就是这个的配置,所以我基本一点点注释,才发现,一旦配置LifecycleBeanPostProcessor,一定报上述异常。
所以这个坑,哎~~~ 伤不起啊。
忘了没有修改ehcache.xml中shiro的缓存设置了。
加上,然后我们运行起来。
log日志我也粘上来吧。
好了,下面把整个项目重要代码都粘上
好了。应没有遗漏。
但这一切都是值得。
1. 首先第一点,以前用xml配置shiro的,将失效。错误的说法,可以使用xml。
2. 以前xml中配置的bean,请在加@Configuration注解的类中定义方法并加上注解
@Bean,最好写上name属性,不然以方法名命名bean的名字
下面开始配置吧。
第一: 集成hibernate。这一步骤,http://blog.csdn.net/u011998835/article/details/78369721已经介绍了。但是我稍微做一下修改。
@EnableTransactionManagement @EnableCaching @SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
这里不再定义SessionFactory的注入了。改成下面的方式
package com.dashuai.springboot.config; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManagerFactory; @Configuration public class SessionFactoryConfig { @Autowired private EntityManagerFactory entityManagerFactory; @Bean(name="SessionFactory") public SessionFactory getSessionFactory() { if (entityManagerFactory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } return entityManagerFactory.unwrap(SessionFactory.class); } }
还有就是我一直忽略的问题,这里补充一下,就是Druid数据源监控页面并没有配置。
这里新增一下。
package com.dashuai.springboot.config; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DruidConfig { @Bean public ServletRegistrationBean druidStatView() { ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet()); registration.addUrlMappings("/druid/*"); return registration; } @Bean public FilterRegistrationBean druidWebStatFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(new WebStatFilter()); registration.addInitParameter("exclusions","/css/*,/style/*,/js/*,*.js,*.css,/druid*,/attached/*,*.jsp"); registration.addInitParameter("principalSessionName","sessionUser"); registration.addInitParameter("profileEnable","true"); registration.addUrlPatterns("/*"); registration.setOrder(1); return registration; } }
这里@Bean我没有给name属性赋值,那么它的值就是 方法名字
其实上述代码就是以前web.xml中配置的如下代码的转换
<!-- //////////////阿里巴巴数据连接池 Druid的监控/////////////////// --> <filter> <filter-name>druidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value> /css/*,/style/*,/js/*,*.js,*.css,/druid*,/attached/*,*.jsp </param-value> </init-param> <init-param> <param-name>principalSessionName</param-name> <param-value>sessionUser</param-value> </init-param> <init-param> <param-name>profileEnable</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>druidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- //////////druid监控页面,使用${pageContext.request.contextPath}/druid/index.html访问///////// --> <servlet> <servlet-name>druidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>druidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping>
上面的集成完毕之后,解析来集成shiro。
以前shiro是配置在 xml中,类似这样
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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-4.0.xsd"> <!-- Realm 域 授权和认证的判断 --> <bean id="systemUserRealm" class="com.dashuai.shiro.SystemUserRealm" /> <bean id="normalUserRealm" class="com.dashuai.shiro.NormalUserRealm" /> <!-- FormAuthenticationFilter --> <bean id="systemAuthFilter" class="com.dashuai.shiro.SystemFormAuthFilter" > <property name="loginUrl" value="/admin/login.html" /> <property name="successUrl" value="/admin/index.html" /> </bean> <bean id="normalAuthFilter" class="com.dashuai.shiro.NormalFormAuthFilter" > <property name="loginUrl" value="/login.html" /> <property name="successUrl" value="/index.html" /> </bean> <bean id="defineModularRealmAuthenticator" class="com.dashuai.shiro.DefautModularRealm"> <property name="definedRealms"> <map> <entry key="systemAuthorizingRealm" value-ref="systemUserRealm" /> <entry key="normalAuthorizingRealm" value-ref="normalUserRealm" /> </map> </property> <property name="authenticationStrategy"> <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean> </property> </bean> <!-- 安全认证过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="filters"> <map> <entry key="authsys" value-ref="systemAuthFilter"></entry> <entry key="authnor" value-ref="normalAuthFilter"></entry> </map> </property> <property name="filterChainDefinitions"> <value> /res_admin/**=anon /res_front/**=anon /plugins/**=anon /login.html=anon /admin/login.*=anon /admin/**=authsys /user/**=authnor /**=anon </value> </property> </bean> <!-- 定义Shiro安全管理配置 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="memoryConstrainedCacheManager" /> <property name="authenticator" ref="defineModularRealmAuthenticator" /> <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 --> <!-- <property name="realm" ref="loginRealm"/> --> <property name="realms" > <list> <ref bean="systemUserRealm" /> <ref bean="normalUserRealm"/> </list> </property> <property name="sessionManager" ref="sessionManager" /> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> <!-- 定义授权缓存管理器 --> <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" /> </bean> <bean id="memoryConstrainedCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /> <!-- 自定义会话管理配置 --> <!-- 指定本系统SESSIONID, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID, 当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="sessionDAO" /> <!-- 会话超时时间,单位:毫秒 --> <property name="globalSessionTimeout" value="1800000" /> <!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 --> <property name="sessionValidationInterval" value="1800000" /> <property name="sessionValidationSchedulerEnabled" value="true" /> <property name="sessionIdCookie" ref="simpleCookie" /> <property name="sessionIdCookieEnabled" value="true" /> </bean> <!-- 会话Cookie模板 --> <bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg name="name" value="shiro.sesssion"/> <property name="path" value="/"/> </bean> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="rememberMe"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="604800"/><!-- 7天 --> </bean> <!-- rememberMe管理器 --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/> <property name="cookie" ref="rememberMeCookie"/> </bean> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="cacheManager" ref="shiroCacheManager" /> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> </beans>
但是用springboot 就不能这样写了。应慢慢修改成对应下面的java代码,我也是很辛苦的一一对应的写上的。
package com.dashuai.springboot.config; import com.dashuai.springboot.shiro.*; import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy; import org.apache.shiro.cache.MemoryConstrainedCacheManager; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 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 javax.servlet.Filter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean(name = "systemAuthFilter") public SystemFormAuthFilter getSystemFormAuthFilter() { SystemFormAuthFilter formAuthFilter = new SystemFormAuthFilter(); formAuthFilter.setSuccessUrl("/admin/index.html"); formAuthFilter.setLoginUrl("/admin/login.html"); return formAuthFilter; } @Bean(name = "normalAuthFilter") public NormalFormAuthFilter getNormalFormAuthFilter() { NormalFormAuthFilter formAuthFilter = new NormalFormAuthFilter(); formAuthFilter.setSuccessUrl("/index.html"); formAuthFilter.setLoginUrl("/login.html"); return formAuthFilter; } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager()); Map<String, Filter> filters = new LinkedHashMap<>(); filters.put("authsys", getSystemFormAuthFilter()); filters.put("authnor", getNormalFormAuthFilter()); shiroFilterFactoryBean.setFilters(filters); LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>(); filterChainDefinitionMap.put("/login.html", "anon"); filterChainDefinitionMap.put("/admin/login.*", "anon"); filterChainDefinitionMap.put("/admin", "authsys"); filterChainDefinitionMap.put("/admin/", "authsys"); filterChainDefinitionMap.put("/admin/**.html", "authsys");// 也就是说 这个配置请细致配置 // filterChainDefinitionMap.put("/admin/**", "authsys");// 不可以加这个,否则/admin/login.*失效 filterChainDefinitionMap.put("/user/**", "authnor"); filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setCacheManager(getMemoryConstrainedCacheManager()); securityManager.setAuthenticator(getDefautModularRealm()); ArrayList<Realm> list = new ArrayList<>(); list.add(getSystemUserRealm()); list.add(getNormalUserRealm()); securityManager.setRealms(list); securityManager.setSessionManager(getDefaultWebSessionManager()); securityManager.setRememberMeManager(getCookieRememberMeManager()); return securityManager; } @Bean(name = "memoryConstrainedCacheManager") public MemoryConstrainedCacheManager getMemoryConstrainedCacheManager() { MemoryConstrainedCacheManager manager = new MemoryConstrainedCacheManager(); return manager; } @Bean(name = "defineModularRealmAuthenticator") public DefautModularRealm getDefautModularRealm() { DefautModularRealm realm = new DefautModularRealm(); Map<String, Object> definedRealms = new HashMap<>(); definedRealms.put("systemAuthorizingRealm", getSystemUserRealm()); definedRealms.put("normalAuthorizingRealm", getNormalUserRealm()); realm.setDefinedRealms(definedRealms); realm.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); return realm; } @Bean(name = "systemUserRealm") public SystemUserRealm getSystemUserRealm() { SystemUserRealm realm = new SystemUserRealm(); return realm; } @Bean(name = "normalUserRealm") public NormalUserRealm getNormalUserRealm() { NormalUserRealm realm = new NormalUserRealm(); return realm; } @Bean(name = "sessionManager") public DefaultWebSessionManager getDefaultWebSessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionDAO(getEnterpriseCacheSessionDAO()); sessionManager.setGlobalSessionTimeout(1800000); sessionManager.setSessionValidationInterval(1800000); sessionManager.setSessionIdCookieEnabled(true); sessionManager.setSessionValidationSchedulerEnabled(true); sessionManager.setSessionIdCookie(getSimpleCookie()); return sessionManager; } @Bean(name = "sessionDAO") public EnterpriseCacheSessionDAO getEnterpriseCacheSessionDAO() { EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO(); sessionDAO.setCacheManager(getEhCacheManager()); return sessionDAO; } @Bean(name = "shiroCacheManager") public EhCacheManager getEhCacheManager() { EhCacheManager em = new EhCacheManager(); em.setCacheManagerConfigFile("classpath:ehcache.xml"); return em; } @Bean(name = "simpleCookie") public SimpleCookie getSimpleCookie() { SimpleCookie simpleCookie = new SimpleCookie("shiro.sesssion"); simpleCookie.setPath("/"); return simpleCookie; } @Bean(name = "rememberMeManager") public CookieRememberMeManager getCookieRememberMeManager() { CookieRememberMeManager meManager = new CookieRememberMeManager(); meManager.setCipherKey(org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); meManager.setCookie(getRememberMeCookie()); return meManager; } @Bean(name = "rememberMeCookie") public SimpleCookie getRememberMeCookie() { SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setHttpOnly(true); simpleCookie.setMaxAge(604800); // 7天 return simpleCookie; }
// 千万不要配置这个,这是导致Could not obtain transaction-synchronized Session for current thread产生的原因 // 至于为什么,弄不清楚 // @Bean(name = "lifecycleBeanPostProcessor") // public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { // return new LifecycleBeanPostProcessor(); // }@Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter")); filterRegistration.addInitParameter("targetFilterLifecycle", "true"); filterRegistration.addUrlPatterns("/*"); return filterRegistration; }}
基本上一一对应。但这里有两个个巨坑。
LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>(); filterChainDefinitionMap.put("/login.html", "anon"); filterChainDefinitionMap.put("/admin/login.*", "anon"); filterChainDefinitionMap.put("/admin", "authsys"); filterChainDefinitionMap.put("/admin/", "authsys"); filterChainDefinitionMap.put("/admin/**.html", "authsys");// 也就是说 这个配置请细致配置 // filterChainDefinitionMap.put("/admin/**", "authsys");// 不可以加这个,否则/admin/login.*失效 filterChainDefinitionMap.put("/user/**", "authnor"); filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
就是url的拦截,请细致小心的配置,不要直接/**什么的,会导致最基本的登陆请求都完成不了,我就在这吃了大亏。因为在xml中那样配置没有问题,但是写成java代码,差点没坑死我。
第二个坑,我找了好长好长时间。 因为上一篇只集成hibernate的时候,并没有报异常。Could not obtain transaction-synchronized Session for current thread
Could not obtain transaction-synchronized Session for current thread
可是加上ShiroConfig,怎么都报这个异常。刚开始使用配置openSessionInViewFilter,起点作用,但是在单元测试的时候,还是抱上述异常。我就非常纳闷,我尝试先关闭shiroConfig,然后发现单元测试就不报异常了。所以我觉得就是这个的配置,所以我基本一点点注释,才发现,一旦配置LifecycleBeanPostProcessor,一定报上述异常。
所以这个坑,哎~~~ 伤不起啊。
忘了没有修改ehcache.xml中shiro的缓存设置了。
<!-- shiro ehcache--> <!-- 登录记录缓存 锁定10分钟 --> <cache name="passwordRetryCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authorizationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authenticationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="shiro-activeSessionCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="shiro_cache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="0" timeToLiveSeconds="0" maxElementsOnDisk="0" overflowToDisk="true" memoryStoreEvictionPolicy="FIFO" statistics="true"> </cache>
加上,然后我们运行起来。
log日志我也粘上来吧。
22:16:10.124 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : [] 22:16:10.125 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter/target/classes/, /spring-boot-autoconfigure/target/classes/, /spring-boot-starter-[\w-]+/, /spring-boot/target/classes/, /spring-boot-actuator/target/classes/, /spring-boot-devtools/target/classes/] 22:16:10.126 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/E:/WorkSpace/springboot/target/classes/] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.8.RELEASE) 2017-10-28 22:16:10.323 INFO 5840 --- [ restartedMain] c.d.springboot.SpringbootApplication : Starting SpringbootApplication on DESKTOP-I8M03ML with PID 5840 (E:\WorkSpace\springboot\target\classes started by yaoshuangshuai in E:\WorkSpace\springboot) 2017-10-28 22:16:10.324 INFO 5840 --- [ restartedMain] c.d.springboot.SpringbootApplication : No active profile set, falling back to default profiles: default 2017-10-28 22:16:10.542 INFO 5840 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7245da69: startup date [Sat Oct 28 22:16:10 CST 2017]; root of context hierarchy 2017-10-28 22:16:11.496 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'shiroConfig' of type [com.dashuai.springboot.config.ShiroConfig$$EnhancerBySpringCGLIB$$9b51ca65] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.658 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'memoryConstrainedCacheManager' of type [org.apache.shiro.cache.MemoryConstrainedCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.692 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration' of type [org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration$$EnhancerBySpringCGLIB$$e5568eb1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.694 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.777 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.810 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [com.alibaba.druid.pool.DruidDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.814 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'inMemoryDatabaseShutdownExecutor' of type [org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration$NonEmbeddedInMemoryDatabaseShutdownExecutor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.828 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.jpa-org.springframework.boot.autoconfigure.orm.jpa.JpaProperties' of type [org.springframework.boot.autoconfigure.orm.jpa.JpaProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.834 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration' of type [org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration$$EnhancerBySpringCGLIB$$9f067a84] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.841 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.transaction-org.springframework.boot.autoconfigure.transaction.TransactionProperties' of type [org.springframework.boot.autoconfigure.transaction.TransactionProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.844 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'platformTransactionManagerCustomizers' of type [org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.850 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration' of type [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$7418e39a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.864 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jpaVendorAdapter' of type [org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.867 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactoryBuilder' of type [org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:11.903 INFO 5840 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default' 2017-10-28 22:16:12.012 DEBUG 5840 --- [ restartedMain] o.h.c.internal.RegionFactoryInitiator : Cache region factory : org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory 2017-10-28 22:16:12.119 INFO 5840 --- [ restartedMain] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited 2017-10-28 22:16:12.362 WARN 5840 --- [ restartedMain] org.hibernate.id.UUIDHexGenerator : HHH000409: Using org.hibernate.id.UUIDHexGenerator which does not generate IETF RFC 4122 compliant UUID values; consider using org.hibernate.id.UUIDGenerator instead 2017-10-28 22:16:12.527 INFO 5840 --- [ restartedMain] o.h.cache.spi.UpdateTimestampsCache : HHH000250: Starting update timestamps cache at region: org.hibernate.cache.spi.UpdateTimestampsCache 2017-10-28 22:16:12.531 INFO 5840 --- [ restartedMain] o.h.cache.internal.StandardQueryCache : HHH000248: Starting query cache at region: org.hibernate.cache.internal.StandardQueryCache 2017-10-28 22:16:12.594 WARN 5840 --- [ restartedMain] o.h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [com.dashuai.springboot.entity.SystemUser]; using defaults. 2017-10-28 22:16:12.595 DEBUG 5840 --- [ restartedMain] o.h.c.e.AbstractEhcacheRegionFactory : started EHCache region: com.dashuai.springboot.entity.SystemUser 2017-10-28 22:16:12.596 WARN 5840 --- [ restartedMain] c.e.i.s.EhcacheAccessStrategyFactoryImpl : HHH020007: read-only cache configured for mutable entity [com.dashuai.springboot.entity.SystemUser] 2017-10-28 22:16:12.638 WARN 5840 --- [ restartedMain] o.h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [com.dashuai.springboot.entity.SystemRole]; using defaults. 2017-10-28 22:16:12.639 DEBUG 5840 --- [ restartedMain] o.h.c.e.AbstractEhcacheRegionFactory : started EHCache region: com.dashuai.springboot.entity.SystemRole 2017-10-28 22:16:12.640 WARN 5840 --- [ restartedMain] c.e.i.s.EhcacheAccessStrategyFactoryImpl : HHH020007: read-only cache configured for mutable entity [com.dashuai.springboot.entity.SystemRole] 2017-10-28 22:16:12.917 INFO 5840 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2017-10-28 22:16:12.919 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactory' of type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.920 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactory' of type [com.sun.proxy.$Proxy66] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.921 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'sessionFactoryConfig' of type [com.dashuai.springboot.config.SessionFactoryConfig$$EnhancerBySpringCGLIB$$e5b8db62] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.928 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'SessionFactory' of type [org.hibernate.internal.SessionFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.929 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'systemUserDao' of type [com.dashuai.springboot.dao.impl.SystemUserDaoImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.930 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'systemUserService' of type [com.dashuai.springboot.service.impl.SystemUserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.930 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'systemUserRealm' of type [com.dashuai.springboot.shiro.SystemUserRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.937 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'normalUserRealm' of type [com.dashuai.springboot.shiro.NormalUserRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.940 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'defineModularRealmAuthenticator' of type [com.dashuai.springboot.shiro.DefautModularRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.952 WARN 5840 --- [ restartedMain] net.sf.ehcache.CacheManager : Creating a new instance of CacheManager using the diskStorePath "../springBoot_Ehcache" which is already used by an existing CacheManager. The source of the configuration was net.sf.ehcache.config.generator.ConfigurationSource$InputStreamConfigurationSource@76292dc5. The diskStore path for this CacheManager will be set to ../springBoot_Ehcache\ehcache_auto_created_1509200172951. To avoid this warning consider using the CacheManager factory methods to create a singleton CacheManager or specifying a separate ehcache configuration (ehcache.xml) for each CacheManager instance. 2017-10-28 22:16:12.954 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'shiroCacheManager' of type [org.apache.shiro.cache.ehcache.EhCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.958 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'sessionDAO' of type [org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.961 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'simpleCookie' of type [org.apache.shiro.web.servlet.SimpleCookie] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.968 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'sessionManager' of type [org.apache.shiro.web.session.mgt.DefaultWebSessionManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.970 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'rememberMeCookie' of type [org.apache.shiro.web.servlet.SimpleCookie] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.973 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'rememberMeManager' of type [org.apache.shiro.web.mgt.CookieRememberMeManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.978 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'securityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.986 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'systemAuthFilter' of type [com.dashuai.springboot.shiro.SystemFormAuthFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:12.992 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'normalAuthFilter' of type [com.dashuai.springboot.shiro.NormalFormAuthFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.027 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cache.annotation.ProxyCachingConfiguration' of type [org.springframework.cache.annotation.ProxyCachingConfiguration$$EnhancerBySpringCGLIB$$53a4b598] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.037 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration' of type [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration$$EnhancerBySpringCGLIB$$48187a3c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.046 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.cache-org.springframework.boot.autoconfigure.cache.CacheProperties' of type [org.springframework.boot.autoconfigure.cache.CacheProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.053 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'cacheManagerCustomizers' of type [org.springframework.boot.autoconfigure.cache.CacheManagerCustomizers] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.054 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration' of type [org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration$$EnhancerBySpringCGLIB$$e9b3ed1d] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.059 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'cacheManager' of type [org.springframework.cache.concurrent.ConcurrentMapCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.059 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'cacheAutoConfigurationValidator' of type [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration$CacheManagerValidator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.073 INFO 5840 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a927f7a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-10-28 22:16:13.322 INFO 5840 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2017-10-28 22:16:13.329 INFO 5840 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2017-10-28 22:16:13.330 INFO 5840 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.23 2017-10-28 22:16:13.401 INFO 5840 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2017-10-28 22:16:13.402 INFO 5840 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2863 ms 2017-10-28 22:16:13.549 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'webStatFilter' to urls: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'openSessionInViewFilter' to urls: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'delegatingFilterProxy' to urls: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'systemAuthFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'normalAuthFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'shiroFilter' to: [/*] 2017-10-28 22:16:13.550 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'statViewServlet' to [/druid/*] 2017-10-28 22:16:13.551 INFO 5840 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2017-10-28 22:16:13.880 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7245da69: startup date [Sat Oct 28 22:16:10 CST 2017]; root of context hierarchy 2017-10-28 22:16:13.926 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/ || /admin/index.html]}" onto public java.lang.String com.dashuai.springboot.controller.AdminController.index() 2017-10-28 22:16:13.926 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin]}" onto public java.lang.String com.dashuai.springboot.controller.AdminController.index2() 2017-10-28 22:16:13.927 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/login.html]}" onto public java.lang.String com.dashuai.springboot.controller.AdminController.loginIndex() 2017-10-28 22:16:13.928 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/login.do]}" onto public java.lang.String com.dashuai.springboot.controller.AdminController.doLogin(java.lang.String,java.lang.String,javax.servlet.http.HttpServletRequest) 2017-10-28 22:16:13.928 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/logout.html]}" onto public java.lang.String com.dashuai.springboot.controller.AdminController.logout() 2017-10-28 22:16:13.930 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2017-10-28 22:16:13.930 INFO 5840 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2017-10-28 22:16:13.961 INFO 5840 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-28 22:16:13.961 INFO 5840 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-28 22:16:13.990 INFO 5840 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-28 22:16:14.393 INFO 5840 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2017-10-28 22:16:14.451 INFO 5840 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-10-28 22:16:14.453 INFO 5840 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure 2017-10-28 22:16:14.457 INFO 5840 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.alibaba.druid.pool:name=dataSource,type=DruidDataSource] 2017-10-28 22:16:14.493 INFO 5840 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2017-10-28 22:16:14.497 INFO 5840 --- [ restartedMain] c.d.springboot.SpringbootApplication : Started SpringbootApplication in 4.362 seconds (JVM running for 4.875)
好了,下面把整个项目重要代码都粘上
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dashuai</groupId> <artifactId>springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>true</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.31</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- 集成ehcache需要的依赖--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <!--工具包,加密算法 --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins> </build> </project>
package com.dashuai.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement @EnableCaching @SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
#log logging.file=mylog.log logging.level.root=info logging.level.org.springframework=info logging.level.org.hibernate=warn #logging.level.org.hibernate.engine.QueryParameters=DEBUG #logging.level.org.hibernate.engine.query.HQLQueryPlan=DEBUG #logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE #logging.level.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE #控制是否显示缓存相关日志 logging.level.org.hibernate.cache=DEBUG #thymeleaf spring.thymeleaf.cache=false #mysql spring.datasource.driver-class-name= com.mysql.jdbc.Driver spring.datasource.url=jdbc\:mysql\://localhost\:3306/dadmin?useUnicode\=true&characterEncoding\=UTF-8 spring.datasource.username=root spring.datasource.password=123456 #druid spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.filters=stat spring.datasource.maxActive= 20 spring.datasource.initialSize= 1 spring.datasource.maxWait= 60000 spring.datasource.minIdle =1 spring.datasource.timeBetweenEvictionRunsMillis= 60000 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery= select 'x' spring.datasource.testWhileIdle= true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn= false spring.datasource.poolPreparedStatements=true spring.datasource.maxOpenPreparedStatements= 20 #hibernate spring.jpa.database = MYSQL spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect spring.jpa.properties.hibernate.format_sql = true spring.jpa.properties.hibernate.show_sql = true spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext # 打开hibernate统计信息 spring.jpa.properties.hibernate.generate_statistics=true # 打开二级缓存 spring.jpa.properties.hibernate.cache.use_second_level_cache=true # 打开查询缓存 spring.jpa.properties.hibernate.cache.use_query_cache=true # 指定缓存provider spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory # 配置shared-cache-mode spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE spring.jpa.properties.hibernate.cache.provider_configuration_file_resource_path=classpath:ehcache.xml spring.cache.ehcache.config=ehcache.xml
package com.dashuai.springboot.config; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DruidConfig { @Bean public ServletRegistrationBean druidStatView() { ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet()); registration.addUrlMappings("/druid/*"); return registration; } @Bean public FilterRegistrationBean druidWebStatFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(new WebStatFilter()); registration.addInitParameter("exclusions","/css/*,/style/*,/js/*,*.js,*.css,/druid*,/attached/*,*.jsp"); registration.addInitParameter("principalSessionName","sessionUser"); registration.addInitParameter("profileEnable","true"); registration.addUrlPatterns("/*"); registration.setOrder(1); return registration; } }
package com.dashuai.springboot.config; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManagerFactory; @Configuration public class SessionFactoryConfig { @Autowired private EntityManagerFactory entityManagerFactory; @Bean(name="SessionFactory") public SessionFactory getSessionFactory() { if (entityManagerFactory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } return entityManagerFactory.unwrap(SessionFactory.class); } /** * 解决异常 org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread * @return */ @Bean(name="openSessionInViewFilter") public FilterRegistrationBean openSessionInViewFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(new org.springframework.orm.hibernate4.support.OpenSessionInViewFilter()); filterRegistration.addInitParameter("singleSession","true"); filterRegistration.addInitParameter("sessionFactoryBeanName","SessionFactory"); filterRegistration.addUrlPatterns("/*"); return filterRegistration; } }
package com.dashuai.springboot.config; import com.dashuai.springboot.shiro.*; import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy; import org.apache.shiro.cache.MemoryConstrainedCacheManager; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 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 javax.servlet.Filter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean(name = "systemAuthFilter") public SystemFormAuthFilter getSystemFormAuthFilter() { SystemFormAuthFilter formAuthFilter = new SystemFormAuthFilter(); formAuthFilter.setSuccessUrl("/admin/index.html"); formAuthFilter.setLoginUrl("/admin/login.html"); return formAuthFilter; } @Bean(name = "normalAuthFilter") public NormalFormAuthFilter getNormalFormAuthFilter() { NormalFormAuthFilter formAuthFilter = new NormalFormAuthFilter(); formAuthFilter.setSuccessUrl("/index.html"); formAuthFilter.setLoginUrl("/login.html"); return formAuthFilter; } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager()); Map<String, Filter> filters = new LinkedHashMap<>(); filters.put("authsys", getSystemFormAuthFilter()); filters.put("authnor", getNormalFormAuthFilter()); shiroFilterFactoryBean.setFilters(filters); LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>(); filterChainDefinitionMap.put("/login.html", "anon"); filterChainDefinitionMap.put("/admin/login.*", "anon"); filterChainDefinitionMap.put("/admin", "authsys"); filterChainDefinitionMap.put("/admin/", "authsys"); filterChainDefinitionMap.put("/admin/**.html", "authsys");// 也就是说 这个配置请细致配置 // filterChainDefinitionMap.put("/admin/**", "authsys");// 不可以加这个,否则/admin/login.*失效 filterChainDefinitionMap.put("/user/**", "authnor"); filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setCacheManager(getMemoryConstrainedCacheManager()); securityManager.setAuthenticator(getDefautModularRealm()); ArrayList<Realm> list = new ArrayList<>(); list.add(getSystemUserRealm()); list.add(getNormalUserRealm()); securityManager.setRealms(list); securityManager.setSessionManager(getDefaultWebSessionManager()); securityManager.setRememberMeManager(getCookieRememberMeManager()); return securityManager; } @Bean(name = "memoryConstrainedCacheManager") public MemoryConstrainedCacheManager getMemoryConstrainedCacheManager() { MemoryConstrainedCacheManager manager = new MemoryConstrainedCacheManager(); return manager; } @Bean(name = "defineModularRealmAuthenticator") public DefautModularRealm getDefautModularRealm() { DefautModularRealm realm = new DefautModularRealm(); Map<String, Object> definedRealms = new HashMap<>(); definedRealms.put("systemAuthorizingRealm", getSystemUserRealm()); definedRealms.put("normalAuthorizingRealm", getNormalUserRealm()); realm.setDefinedRealms(definedRealms); realm.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); return realm; } @Bean(name = "systemUserRealm") public SystemUserRealm getSystemUserRealm() { SystemUserRealm realm = new SystemUserRealm(); return realm; } @Bean(name = "normalUserRealm") public NormalUserRealm getNormalUserRealm() { NormalUserRealm realm = new NormalUserRealm(); return realm; } @Bean(name = "sessionManager") public DefaultWebSessionManager getDefaultWebSessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionDAO(getEnterpriseCacheSessionDAO()); sessionManager.setGlobalSessionTimeout(1800000); sessionManager.setSessionValidationInterval(1800000); sessionManager.setSessionIdCookieEnabled(true); sessionManager.setSessionValidationSchedulerEnabled(true); sessionManager.setSessionIdCookie(getSimpleCookie()); return sessionManager; } @Bean(name = "sessionDAO") public EnterpriseCacheSessionDAO getEnterpriseCacheSessionDAO() { EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO(); sessionDAO.setCacheManager(getEhCacheManager()); return sessionDAO; } @Bean(name = "shiroCacheManager") public EhCacheManager getEhCacheManager() { EhCacheManager em = new EhCacheManager(); em.setCacheManagerConfigFile("classpath:ehcache.xml"); return em; } @Bean(name = "simpleCookie") public SimpleCookie getSimpleCookie() { SimpleCookie simpleCookie = new SimpleCookie("shiro.sesssion"); simpleCookie.setPath("/"); return simpleCookie; } @Bean(name = "rememberMeManager") public CookieRememberMeManager getCookieRememberMeManager() { CookieRememberMeManager meManager = new CookieRememberMeManager(); meManager.setCipherKey(org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); meManager.setCookie(getRememberMeCookie()); return meManager; } @Bean(name = "rememberMeCookie") public SimpleCookie getRememberMeCookie() { SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setHttpOnly(true); simpleCookie.setMaxAge(604800); // 7天 return simpleCookie; }@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
filterRegistration.addUrlPatterns("/*");
return filterRegistration;
}
}
package com.dashuai.springboot.controller; import com.dashuai.springboot.entity.SystemUser; import com.dashuai.springboot.shiro.CustomUsernamePasswordToken; import org.apache.commons.codec.digest.DigestUtils; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AccountException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/admin") public class AdminController { private final Logger logger = Logger.getLogger(AdminController.class); @RequestMapping public String index2(){ return "admin/index"; } @RequestMapping(value = {"/","/index.html"}) public String index(){ return "admin/index"; } @RequestMapping("/login.html") public String loginIndex(){ // 防止重复登陆 Subject subject = SecurityUtils.getSubject(); if(null==subject||null==subject.getPrincipal()||!subject.isAuthenticated()){ return "admin/login"; } return "redirect:/admin"; } @RequestMapping("/login.do") public String doLogin(String username, String password, HttpServletRequest request){ logger.info("进入到 doLogin方法中 "); if(null==username||username.equals("")){ return "redirect:/admin/login.html"; } logger.info("登陆请求 username:"+username+",password:"+password); try { SecurityUtils.getSubject().login(new CustomUsernamePasswordToken(username, DigestUtils.md5Hex(password),false, CustomUsernamePasswordToken.LOGIN_ADMIN_TYPE)); System.err.println("登陆成功,"+SecurityUtils.getSubject().getPrincipal()); logger.info("登陆成功,"+SecurityUtils.getSubject().getPrincipal()); SystemUser systemUser = (SystemUser) SecurityUtils.getSubject().getPrincipal(); request.getSession().setAttribute("SystemUser",systemUser); logger.info("Session 中存入 登陆信息 key: SystemUser value: "+systemUser); return "redirect:/admin/index.html"; } catch (IncorrectCredentialsException e) { logger.info(e.getMessage()); request.setAttribute("msg", "登陆失败,密码错误"); return "admin/login"; } catch (UnknownAccountException e) { request.setAttribute("msg", "登陆失败,用户名不存在"); logger.info(e.getMessage()); return "admin/login"; }catch (AccountException e) { request.setAttribute("msg", "您的账号被禁用了!"); logger.info(e.getMessage()); return "admin/login"; } } @RequestMapping("/logout.html") public String logout(){ Subject subject = SecurityUtils.getSubject(); if (null!=subject) { subject.logout(); } return "redirect:/admin/login.html"; } }
package com.dashuai.springboot.dao; import org.hibernate.Session; import java.io.Serializable; import java.util.List; import java.util.Map; public interface BaseDao<T> { public Session getCurrentSession(); public Serializable save(T o); public void delete(T o); public void saveOrUpdate(T o); public void update(T o); public List<T> getByHQL(boolean withCache, String hql, Map<String, Object> params); public List<T> getByHQL(boolean withCache, String hql, Map<String, Object> params, int page, int rows); public long countByHQL(boolean withCache, String hql, Map<String, Object> params); public long countBySQL(boolean withCache, String sql, Map<String, Object> params); public List<Map<String,Object>> getResultMapBySql(String sql, Map<String, Object> params); public List<Map<String,Object>> getResultMapBySql(String sql, Map<String, Object> params, int page, int rows); public int executeHQL(String hql, Map<String, Object> params); public int executeSQL(String sql, Map<String, Object> params); }
package com.dashuai.springboot.dao.impl; import java.io.Serializable; import java.util.List; import java.util.Map; import com.dashuai.springboot.dao.BaseDao; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.transform.Transformers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository("baseDao") public class BaseDaoImpl<T> implements BaseDao<T> { @Autowired private SessionFactory sessionFactory; public Session getCurrentSession() { return sessionFactory.getCurrentSession(); } public Serializable save(T o) { return getCurrentSession().save(o); } public void delete(T o) { getCurrentSession().delete(o); } public void saveOrUpdate(T o) { getCurrentSession().saveOrUpdate(getCurrentSession().merge(o)); } public void update(T o) { getCurrentSession().update(o); } public List<T> getByHQL(boolean withCache, String hql, Map<String, Object> params) { Query q = getCurrentSession().createQuery(hql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.setCacheable(withCache).list(); } public List<T> getByHQL(boolean withCache, String hql, Map<String, Object> params, int page, int rows) { Query q = getCurrentSession().createQuery(hql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.setCacheable(withCache).setFirstResult((page - 1) * rows)// .setMaxResults(rows)// .list(); } public long countByHQL(boolean withCache, String hql, Map<String, Object> params) { Query q = getCurrentSession().createQuery(hql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return (Long) q.setCacheable(withCache).uniqueResult(); } public long countBySQL(boolean withCache, String sql, Map<String, Object> params) { SQLQuery q = getCurrentSession().createSQLQuery(sql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return (Long) q.setCacheable(withCache).uniqueResult(); } public List<Map<String, Object>> getResultMapBySql(String sql, Map<String, Object> params) { SQLQuery q = getCurrentSession().createSQLQuery(sql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); } public List<Map<String, Object>> getResultMapBySql(String sql, Map<String, Object> params, int page, int rows) { SQLQuery q = getCurrentSession().createSQLQuery(sql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.setFirstResult((page - 1) * rows)// .setMaxResults(rows)// .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)// .list(); } public int executeHQL(String hql,Map<String,Object> params) { Query q = getCurrentSession().createQuery(hql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.executeUpdate(); } public int executeSQL(String sql,Map<String,Object> params) { SQLQuery q = getCurrentSession().createSQLQuery(sql); if (params != null && !params.isEmpty()) { for (String key : params.keySet()) { q.setParameter(key, params.get(key)); } } return q.executeUpdate(); } }
package com.dashuai.springboot.dao; import com.dashuai.springboot.entity.SystemUser; import java.io.Serializable; public interface SystemUserDao { Serializable saveSystemUser(SystemUser user); SystemUser findUserByUsername(String username); }
package com.dashuai.springboot.dao.impl; import com.dashuai.springboot.dao.SystemUserDao; import com.dashuai.springboot.entity.SystemUser; import org.springframework.stereotype.Repository; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; @Repository("systemUserDao") public class SystemUserDaoImpl extends BaseDaoImpl<SystemUser> implements SystemUserDao { public Serializable saveSystemUser(SystemUser user) { return save(user); } public SystemUser findUserByUsername(String username) { String hql = "from SystemUser where username=:username"; Map<String,Object> params = new HashMap<>(); params.put("username",username); List<SystemUser> list = getByHQL(true,hql,params); if(null!=list&&list.isEmpty()){ return null; } return list.get(0); } }
package com.dashuai.springboot.entity; import com.fasterxml.jackson.annotation.JsonFormat; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Cache; import javax.persistence.*; import java.io.Serializable; import java.util.Date; /** * 用户表。(通用用户,能否访问后台,看是否有后台角色) */ @Entity @Table(name="system_user") @Cacheable @Cache(usage = CacheConcurrencyStrategy.READ_ONLY) public class SystemUser implements Serializable { @Id @GenericGenerator(name = "systemUUID", strategy = "uuid") @GeneratedValue(generator = "systemUUID") @Column(name = "uuid",updatable = false, nullable = false) private String uuid; // 表主键 @Column private String username; // 登录用户名 @Column private String password; // 登录密码 @Column private String isRoot; // 最高权限管理员; "1":root "0": notRoot @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Column private Date registerDate; @Column private Integer status; // 账号状态: 0:正常;1:禁用 public Date getRegisterDate() { return registerDate; } public void setRegisterDate(Date registerDate) { this.registerDate = registerDate; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } 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 String getIsRoot() { return isRoot; } public void setIsRoot(String isRoot) { this.isRoot = isRoot; } @Override public String toString() { return "SystemUser{" + "uuid='" + uuid + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + ", isRoot='" + isRoot + '\'' + ", registerDate=" + registerDate + ", status=" + status + '}'; } }
package com.dashuai.springboot.service; import com.dashuai.springboot.entity.SystemUser; public interface SystemUserService { String saveSystemUser(SystemUser user); SystemUser findUserByUsername(String username); }
package com.dashuai.springboot.service.impl; import com.dashuai.springboot.dao.SystemUserDao; import com.dashuai.springboot.entity.SystemUser; import com.dashuai.springboot.service.SystemUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service("systemUserService") public class SystemUserServiceImpl implements SystemUserService { @Autowired SystemUserDao systemUserDao; @Transactional public String saveSystemUser(SystemUser user) { return (String)systemUserDao.saveSystemUser(user); } @Transactional(readOnly = true) public SystemUser findUserByUsername(String username) { return systemUserDao.findUserByUsername(username); } }
package com.dashuai.springboot.shiro; import org.apache.shiro.authc.UsernamePasswordToken; public class CustomUsernamePasswordToken extends UsernamePasswordToken { public static final int LOGIN_ADMIN_TYPE=1000; // 后台 public static final int LOGIN_FRONT_TYPE=999; // 前台 private int loginType; // 是否是系统后台用户还是前台用户 public int getLoginType() { return loginType; } public void setLoginType(int loginType) { this.loginType = loginType; } public CustomUsernamePasswordToken (String username, String password, boolean rememberMe, int loginType) { super(username, password, rememberMe); this.loginType = loginType; } }
package com.dashuai.springboot.shiro; import org.apache.log4j.Logger; import org.apache.shiro.ShiroException; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.pam.ModularRealmAuthenticator; import org.apache.shiro.realm.Realm; import org.apache.shiro.util.CollectionUtils; import java.util.Collection; import java.util.Map; /** * 管理多个Realms */ public class DefautModularRealm extends ModularRealmAuthenticator { private static final Logger log = Logger.getLogger(DefautModularRealm.class); private Map<String, Object> definedRealms; /** * 多个realm实现 */ @Override protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) { return super.doMultiRealmAuthentication(realms, token); } /** * 调用单个realm执行操作 */ @Override protected AuthenticationInfo doSingleRealmAuthentication(Realm realm,AuthenticationToken token) { log.info("DefautModularRealm doSingleRealmAuthentication Shiro 认证执行的第 3 步 " +token); // 如果该realms不支持(不能验证)当前token if (!realm.supports(token)) { throw new ShiroException("token错误!"); } AuthenticationInfo info = realm.getAuthenticationInfo(token); log.info("DefautModularRealm doSingleRealmAuthentication info " +info); return info; } /** * 判断登录类型执行操作 */ @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)throws AuthenticationException { log.info("DefautModularRealm doAuthenticate Shiro 认证执行的第二步 "); this.assertRealmsConfigured(); Realm realm = null; CustomUsernamePasswordToken token = (CustomUsernamePasswordToken) authenticationToken; //判断是否是后台用户 if (token.getLoginType()==CustomUsernamePasswordToken.LOGIN_ADMIN_TYPE) { realm = (Realm) this.definedRealms.get("systemAuthorizingRealm");// 查看shiro的配置 } else if (token.getLoginType()==CustomUsernamePasswordToken.LOGIN_FRONT_TYPE){ realm = (Realm) this.definedRealms.get("normalAuthorizingRealm"); } log.info("doAuthenticate ==> "+realm); return this.doSingleRealmAuthentication(realm, authenticationToken); } /** * 判断realm是否为空 */ @Override protected void assertRealmsConfigured() throws IllegalStateException { this.definedRealms = this.getDefinedRealms(); if (CollectionUtils.isEmpty(this.definedRealms)) { throw new ShiroException("值传递错误!"); } } public Map<String, Object> getDefinedRealms() { return this.definedRealms; } public void setDefinedRealms(Map<String, Object> definedRealms) { this.definedRealms = definedRealms; } }
package com.dashuai.springboot.shiro; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * 前台 用户登录的验证 */ public class NormalFormAuthFilter extends FormAuthenticationFilter { private static final Logger log = LoggerFactory .getLogger(SystemFormAuthFilter.class); @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { log.info("NormalFormAuthFilter onAccessDenied Shiro 前台 认证执行的第一步 "); return super.onAccessDenied(request, response); } }
package com.dashuai.springboot.shiro; import com.dashuai.springboot.entity.SystemUser; import com.dashuai.springboot.service.SystemUserService; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; 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.Arrays; /** * 这里验证多个 Realm,前后台 分开验证 */ public class NormalUserRealm extends AuthorizingRealm { private static final Logger log = Logger .getLogger(SystemUserRealm.class); @Autowired private SystemUserService systemUserService; /** * Shiro权限认证,即权限授权 * * 关于多个Realm授权的问题。对于本项目配置而言是这样的。 * 本项目配置了两个: SystemUserRealm;NormalUserRealm; * 它会按配置顺序执行。先SystemUserRealm; * 如果在先SystemUserRealm发现了想要的角色或者权限,那么不执行NormalUserRealm; * 如果在SystemUserRealm没有找到,那么继续执行NormalUserRealm中授权方法。 * */ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { log.info("前台用户 NormalUserRealm Shiro 请求授权"); return null; } /** * 用户认证,登录认证 */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { log.info("前台用户 NormalUserRealm 用户认证 Shiro 认证执行的第 4 步 " ); CustomUsernamePasswordToken token = (CustomUsernamePasswordToken) authenticationToken; String username = token.getUsername(); log.info("NormalUserRealm token username: "+username+", password: "+new String(token.getPassword())); SystemUser systemUser = systemUserService.findUserByUsername(username); log.info("NormalUserRealm systemUser: "+systemUser); if(null==systemUser){ throw new UnknownAccountException("NormalUserRealm tips: 用户名不存在"); }else if(!systemUser.getPassword().equals(new String(token.getPassword()))){ throw new IncorrectCredentialsException("NormalUserRealm tips: 密码错误,请重试"); }else if(systemUser.getStatus()==1){ throw new AccountException("NormalUserRealm tips: 账号被禁用"); }else{ return new SimpleAuthenticationInfo(systemUser,systemUser.getPassword(),getName()); } } }
package com.dashuai.springboot.shiro; import org.apache.log4j.Logger; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * 后台的用户登录认证 */ public class SystemFormAuthFilter extends FormAuthenticationFilter { private static final Logger log = Logger .getLogger(SystemFormAuthFilter.class); @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { log.info("SystemFormAuthFilter onAccessDenied Shiro 认证执行的第一步 "); return super.onAccessDenied(request, response); } /*@Override protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { log.info("SystemFormAuthFilter onLoginSuccess "); //我们登录成功之后要跳到一个固定的页面,通常是跳到首页, WebUtils.getAndClearSavedRequest(request); WebUtils.redirectToSavedRequest(request,response,"admin/index.html"); return super.onLoginSuccess(token, subject, request, response); }*/ }
package com.dashuai.springboot.shiro; import com.dashuai.springboot.entity.SystemUser; import com.dashuai.springboot.service.SystemUserService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; //import org.apache.log4j.Logger; /** * 系统用户领域(后台用户操作) * 在 shiro 中,用户需要提供principals(身份)和credentials(证明)给shiro,从而应用能验证用户身份: principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。 一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。 credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。 最常见的principals和credentials组合就是用户名/密码了。 */ public class SystemUserRealm extends AuthorizingRealm { private static final Logger log = LoggerFactory.getLogger(SystemUserRealm.class); @Autowired private SystemUserService systemUserService; /** * Shiro权限认证,即权限授权 * 会进入授权方法一共有三种情况! 1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”):自己去调用这个是否有什么角色或者是否有什么权限的时候; 2、@RequiresRoles("admin") :在方法上加注解的时候; 3、[@shiro.hasPermission name = "admin"][/@shiro.hasPermission]:在页面上加shiro标签的时候,即进这个页面的时候扫描到有这个标签的时候。 */ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { log.info("SystemUserRealm Shiro请求授权 "); // SystemUser systemUser = (SystemUser) SecurityUtils.getSubject().getPrincipal(); // SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // if(systemUser.getIsRoot().equals(ConstantUtil.IS_ROOT)){ // Collection<String> roles = new ArrayList<>(); // List<SystemRole> list = systemRoleService.getRootAllRoles(); // for(SystemRole systemRole:list){ // roles.add(systemRole.getRoleName()); // } // info.addRoles(roles); // log.info("SystemUserRealm Root 获取角色:{} ", Arrays.toString(info.getRoles().toArray())); // }else{ // // 非root用户 // info.addRoles(systemUserRoleService.getAllRolesNameByUserId(systemUser.getUuid())); // log.info("SystemUserRealm 后台 非ROOT 获取角色: {}", Arrays.toString(info.getRoles().toArray())); // } // return info; return null; } /** * 用户认证,登录认证 */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws UnknownAccountException,IncorrectCredentialsException { log.info("SystemUserRealm doGetAuthenticationInfo Shiro 认证执行的第 4 步 " ); CustomUsernamePasswordToken token = (CustomUsernamePasswordToken) authenticationToken; String username = token.getUsername(); log.info("SystemUserRealm token username: {}, password: {}",username,new String(token.getPassword())); SystemUser systemUser = systemUserService.findUserByUsername(username); log.info("SystemUserRealm systemUser: {}",systemUser); if(null==systemUser){ throw new UnknownAccountException("SystemUserRealm 提示: 用户名不存在"); }else if(!systemUser.getPassword().equals(new String(token.getPassword()))){ throw new IncorrectCredentialsException("SystemUserRealm 提示:密码错误"); }else if(systemUser.getStatus()==1){ throw new AccountException("SystemUserRealm 提示: 账号被禁用"); }else{ return new SimpleAuthenticationInfo(systemUser,systemUser.getPassword(),getName()); } } }
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Title</title> </head> <body> 登陆成功! <a href="login.html" th:href="@{/admin/logout.html}">退出</a> </body> </html>
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Title</title> </head> <body> <form action="index.html" th:action="@{/admin/login.do}" method="post" > 用户名: <input type="text" name="username" /><br/> 密码:<input type="password" name="password" /><br/> <input type="submit" value="登陆" /> </form> </body> </html>
2017-10-28 22:24:18.165 INFO 4224 --- [nio-8080-exec-1] c.d.s.controller.AdminController : 进入到 doLogin方法中 2017-10-28 22:24:18.184 INFO 4224 --- [nio-8080-exec-2] c.d.s.shiro.SystemFormAuthFilter : SystemFormAuthFilter onAccessDenied Shiro 认证执行的第一步 2017-10-28 22:24:21.570 INFO 4224 --- [nio-8080-exec-3] c.d.s.controller.AdminController : 进入到 doLogin方法中 2017-10-28 22:24:21.571 INFO 4224 --- [nio-8080-exec-3] c.d.s.controller.AdminController : 登陆请求 username:root,password:123456 2017-10-28 22:24:21.574 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.DefautModularRealm : DefautModularRealm doAuthenticate Shiro 认证执行的第二步 2017-10-28 22:24:21.575 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.DefautModularRealm : doAuthenticate ==> com.dashuai.springboot.shiro.SystemUserRealm@7cf211db 2017-10-28 22:24:21.575 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.DefautModularRealm : DefautModularRealm doSingleRealmAuthentication Shiro 认证执行的第 3 步 com.dashuai.springboot.shiro.CustomUsernamePasswordToken - root, rememberMe=false 2017-10-28 22:24:21.575 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.SystemUserRealm : SystemUserRealm doGetAuthenticationInfo Shiro 认证执行的第 4 步 2017-10-28 22:24:21.575 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.SystemUserRealm : SystemUserRealm token username: root, password: e10adc3949ba59abbe56e057f20f883e 2017-10-28 22:24:21.631 DEBUG 4224 --- [nio-8080-exec-3] o.h.cache.internal.StandardQueryCache : Checking cached query results in region: org.hibernate.cache.internal.StandardQueryCache 2017-10-28 22:24:21.631 DEBUG 4224 --- [nio-8080-exec-3] o.h.c.e.i.r.EhcacheGeneralDataRegion : key: sql: select systemuser0_.uuid as uuid1_1_, systemuser0_.is_root as is_root2_1_, systemuser0_.password as password3_1_, systemuser0_.register_date as register4_1_, systemuser0_.status as status5_1_, systemuser0_.username as username6_1_ from system_user systemuser0_ where systemuser0_.username=?; parameters: ; named parameters: {username=root}; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 2017-10-28 22:24:21.631 DEBUG 4224 --- [nio-8080-exec-3] o.h.c.e.i.r.EhcacheGeneralDataRegion : Element for key sql: select systemuser0_.uuid as uuid1_1_, systemuser0_.is_root as is_root2_1_, systemuser0_.password as password3_1_, systemuser0_.register_date as register4_1_, systemuser0_.status as status5_1_, systemuser0_.username as username6_1_ from system_user systemuser0_ where systemuser0_.username=?; parameters: ; named parameters: {username=root}; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 is null 2017-10-28 22:24:21.631 DEBUG 4224 --- [nio-8080-exec-3] o.h.cache.internal.StandardQueryCache : Query results were not found in cache Hibernate: select systemuser0_.uuid as uuid1_1_, systemuser0_.is_root as is_root2_1_, systemuser0_.password as password3_1_, systemuser0_.register_date as register4_1_, systemuser0_.status as status5_1_, systemuser0_.username as username6_1_ from system_user systemuser0_ where systemuser0_.username=? 2017-10-28 22:24:21.658 DEBUG 4224 --- [nio-8080-exec-3] o.h.cache.internal.StandardQueryCache : Caching query results in region: org.hibernate.cache.internal.StandardQueryCache; timestamp=6181685909749760 2017-10-28 22:24:21.659 DEBUG 4224 --- [nio-8080-exec-3] o.h.c.e.i.r.EhcacheGeneralDataRegion : key: sql: select systemuser0_.uuid as uuid1_1_, systemuser0_.is_root as is_root2_1_, systemuser0_.password as password3_1_, systemuser0_.register_date as register4_1_, systemuser0_.status as status5_1_, systemuser0_.username as username6_1_ from system_user systemuser0_ where systemuser0_.username=?; parameters: ; named parameters: {username=root}; transformer: org.hibernate.transform.CacheableResultTransformer@110f2 value: [6181685909749760, 402880eb5f48f14d015f48f159300000] 2017-10-28 22:24:21.659 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.SystemUserRealm : SystemUserRealm systemUser: SystemUser{uuid='402880eb5f48f14d015f48f159300000', username='root', password='e10adc3949ba59abbe56e057f20f883e', isRoot='null', registerDate=null, status=0} 2017-10-28 22:24:21.661 INFO 4224 --- [nio-8080-exec-3] c.d.springboot.shiro.DefautModularRealm : DefautModularRealm doSingleRealmAuthentication info SystemUser{uuid='402880eb5f48f14d015f48f159300000', username='root', password='e10adc3949ba59abbe56e057f20f883e', isRoot='null', registerDate=null, status=0} 登陆成功,SystemUser{uuid='402880eb5f48f14d015f48f159300000', username='root', password='e10adc3949ba59abbe56e057f20f883e', isRoot='null', registerDate=null, status=0} 2017-10-28 22:24:21.664 INFO 4224 --- [nio-8080-exec-3] c.d.s.controller.AdminController : 登陆成功,SystemUser{uuid='402880eb5f48f14d015f48f159300000', username='root', password='e10adc3949ba59abbe56e057f20f883e', isRoot='null', registerDate=null, status=0} 2017-10-28 22:24:21.666 INFO 4224 --- [nio-8080-exec-3] c.d.s.controller.AdminController : Session 中存入 登陆信息 key: SystemUser value: SystemUser{uuid='402880eb5f48f14d015f48f159300000', username='root', password='e10adc3949ba59abbe56e057f20f883e', isRoot='null', registerDate=null, status=0}
<ehcache name="springBoot_Ehcache" updateCheck="false">
<diskStore path="../springBoot_Ehcache"/>
<!-- hibernate ehcache-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="true"/>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToLiveSeconds="120"
overflowToDisk="true"/>
<!-- shiro ehcache--> <!-- 登录记录缓存 锁定10分钟 --> <cache name="passwordRetryCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authorizationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authenticationCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="shiro-activeSessionCache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="shiro_cache" maxElementsInMemory="2000" eternal="false" timeToIdleSeconds="0" timeToLiveSeconds="0" maxElementsOnDisk="0" overflowToDisk="true" memoryStoreEvictionPolicy="FIFO" statistics="true"> </cache>
</ehcache>
好了。应没有遗漏。
相关文章推荐
- IntelliJ IDEA Spring Boot(7) 集成Hibernate+Shiro+Ehcache(2)
- IntelliJ IDEA Spring Boot(5) 集成Hibernate
- Intellij IDEA Spring Boot (10) 集成mybatis以及分页
- spring boot集成ehcache 2.x 用于hibernate二级缓存
- IDEA springboot集成ehcache单节点和redis集群
- Spring Boot + Shiro 集成
- JAVA IIntelliJ IDEA(2)-----使用Spring-boot-devTools无效解决办法
- 在前后端分离的SpringBoot项目中集成Shiro权限框架
- Spring Boot学习总结(9)——SpringBoot集成Ehcache3.x
- Spring Boot配置外置Tomcat和JSP视图教程(IntelliJ IDEA + Maven)
- 【安装】IntelliJ IDEA+Maven+SpringMVC+Hibernate项目搭建运行
- IntelliJ IDEA+SpringBoot创建模拟接口小程序
- 37. Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】
- spring boot 集成shiro的配置
- Idea创建spring boot 项目(3)集成Lombok
- Intellij idea Springboot 热加载
- IntelliJ IDEA+SpringBoot中静态资源访问路径陷阱:静态资源访问404
- 使用IDEA在Spring Boot上集成JSP
- IntelliJ IDEA + Spring Boot + maven + (单)多数据源