以下是整个项目的目录结构:
1 package com.aaa.ssm.common; 2 3 import org.apache.shiro.crypto.hash.SimpleHash; 4 5 /** 6 * 加密工具类 7 */ 8 public class MD5 { 9 /** 10 * 11 * @param method 使用的加密方式 12 * @param password 加密的字符串 13 * @param code 可以添加的加密字符串 14 * @param count 加密的字数 15 * @return 返回加密后的字符串 16 */ 17 public static String getMd5(String method, String password,String code,Integer count){ 18 SimpleHash simpleHash=null; 19 if (code==null&count==null){ 20 simpleHash=new SimpleHash(method,password); 21 }else { 22 simpleHash=new SimpleHash(method,password,code,count); 23 } 24 25 String newMd5= simpleHash.toString(); 26 27 return newMd5; 28 } 29 30 31 32 }
package com.aaa.ssm.common; public class Const { //放置用户登录成功的session数据 public static final String SESSION_USER="SESSION_USER"; //放置用户的请求地址 public static final String SESSION_URLS="SESSION_URLS"; }
package com.aaa.ssm.controller; import com.aaa.ssm.entity.Module; import com.aaa.ssm.entity.Users; import com.aaa.ssm.service.UsersService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/user") public class UsersController { @Autowired private UsersService usersService; /** * 登录成功 * @param * @return */ //@RequiresPermissions("user") @RequestMapping("/login") public String login(Users users,String rememberMe,Model model) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(users.getUsername(), users.getPassword()); //处理空指针异常 if (rememberMe == null) { rememberMe = "0"; } //记住密码的操作 if (rememberMe.equals("1") && rememberMe != null) { token.setRememberMe(true); } try { subject.login(token); //获取对象信息 users = (Users) subject.getPrincipal(); //根据用户查询模块 List<Module> modules = usersService.queryModule(users); model.addAttribute("module", modules); return "index"; } catch (AuthenticationException e) { model.addAttribute("error", "账号或密码错误"); return "login"; } } @RequestMapping("/tologin") public String toLogin(){ return "login"; } /** * 查询所有用户信息 * @param model * @return */ @RequestMapping("/list") public String list(Model model){ List<Users> users = usersService.listAll(); model.addAttribute("users",users ); return "list"; } /** * 退出 * @return */ @RequestMapping("/logout") public String logout(){ return "redirect:/login.jsp"; } }
package com.aaa.ssm.dao; import com.aaa.ssm.entity.Module; import com.aaa.ssm.entity.Users; import org.apache.ibatis.annotations.Param; import org.apache.shiro.subject.PrincipalCollection; import java.util.List; /** * 用户管理dao接口 */ public interface UsersDao { /** * 用户登录 * @param users * @return */ Users login(Users users); /** * shiro框架验证 * @param username * @return */ Users findByUsername(String username); /** * 查询所有用户 * @return */ List<Users> listAll(); /** * 权限查询 一级菜单 * @return */ List<Module> listOneModule(Users users); /** * 权限查询 二级菜单 * @return */ List<Module> listTwoModule(@Param("users") Users users, @Param("parent") Module parent); }
用户实体类要想实现rememberMe 记住我的功能 需要实现序列化接口(Serializable)
package com.aaa.ssm.entity; import java.io.Serializable; /** * Serializable 为了实现存储Cookie 对象要实现实例化接口 */ public class Users implements Serializable { private Integer id; private String username; private String password; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } 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 getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Users{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", address='" + address + '\'' + '}'; } }
package com.aaa.ssm.service.impl; import com.aaa.ssm.dao.UsersDao; import com.aaa.ssm.entity.Module; import com.aaa.ssm.entity.Users; import com.aaa.ssm.service.UsersService; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; @Service @Transactional public class UsersServiceImpl implements UsersService { @Autowired private UsersDao usersDao; @Override public Users login(Users users) { return usersDao.login(users); } @Override public Users findByUsername(String username) { return usersDao.findByUsername(username); } @Override public List<Users> listAll() { return usersDao.listAll(); } @Override public List<Module> queryModule(Users users) { //先查询一级菜单 List<Module> oneModule = usersDao.listOneModule(users); for (Module module:oneModule){ //查询二级菜单 List<Module> modules = usersDao.listTwoModule(users,module); module.setChildern(modules); } return oneModule; } @Override public List<String> queryUrls(List<Module> modules) { List<String> str=new ArrayList<String>(); for (Module oneModule: modules){ List<Module> childern = oneModule.getChildern(); for (Module s:childern){ String url = s.getUrl(); //截取字符串 str.add(url.substring(0,url.indexOf("/"))); } } return str; } }
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.aaa.ssm.dao.UsersDao"> <select id="login" resultType="com.aaa.ssm.entity.Users"> select * from users where username=#{username} and password=#{password} </select> <select id="listAll" resultType="com.aaa.ssm.entity.Users"> select * from Users </select> <select id="listOneModule" resultType="com.aaa.ssm.entity.Module"> select distinct m.* from users u inner join user_role ur on u.id=ur.u_id inner join role r on r.id=ur.r_id inner join role_module rm on r.id=rm.r_id inner join module m on m.id=rm.m_id where u.id=#{id} and m.level_=1 </select> <select id="listTwoModule" resultType="com.aaa.ssm.entity.Module"> select distinct m.* from users u inner join user_role ur on u.id=ur.u_id inner join role r on r.id=ur.r_id inner join role_module rm on r.id=rm.r_id inner join module m on m.id=rm.m_id where u.id=#{users.id} and m.level_=2 and m.pid=#{parent.id} </select> <select id="findByUsername" resultType="com.aaa.ssm.entity.Users"> select * from users where username=#{username} </select> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:component-scan base-package="com.aaa.ssm.service"></context:component-scan> <context:property-placeholder location="classpath:oracle.properties"></context:property-placeholder> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="${driver}"></property> <property name="url" value="${url}"></property> <property name="username" value="${user}"></property> <property name="password" value="${password}"></property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mapperLocations" value="classpath:mapper/*.xml"></property> <property name="configLocation" value="classpath:mybatis.xml"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.aaa.ssm.dao"></property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <!--spring导入shiro框架--> <import resource="classpath:sping-shiro.xml"></import> </beans>
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <!--<diskStore path="D:/ehcache"></diskStore>--> <!-- eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。 maxElementsInMemory:缓存中允许创建的最大对象数 overflowToDisk:内存不足时,是否启用磁盘缓存。 timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前, 两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。 timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。 memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。 diskPersistent:设定在虚拟机重启时是否进行磁盘存储,默认为false diskExpiryThreadIntervalSeconds: 属性可以设置该线程执行的间隔时间(默认是120秒,不能太小 1 FIFO,先进先出 2 LFU,最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 3 LRU,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 --> <defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration>
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl user=scott password=tiger
<?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.xsd"> <!--创建自定义域对象--> <bean id="myRealm" class="com.aaa.ssm.realm.MyRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"></property> </bean> <!--声明cookie对象--> <bean id="cookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="rememberMe"></constructor-arg> <property name="httpOnly" value="true"></property> <property name="maxAge" value="2592000"></property> </bean> <!--声明rememberMe对象--> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cookie" ref="cookie"></property> </bean> <!--创建回话管理器--> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!--设置全局session的超时时间--> <property name="globalSessionTimeout" value="180000"></property> </bean> <!--配置shiro的缓存管理--> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property> </bean> <!--创建安全管理器--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"></property> <property name="rememberMeManager" ref="rememberMeManager"></property> <property name="sessionManager" ref="sessionManager"></property> <property name="cacheManager" ref="cacheManager"></property> </bean> <!--加密方式--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashIterations" value="5"></property> <property name="hashAlgorithmName" value="md5"></property> </bean> <!--过滤器--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="unauthorizedUrl" value="/error.jsp"></property> <!--/user/login.do--> <property name="loginUrl" value="/user/tologin.do"></property> <property name="filterChainDefinitions"> <value> <!--对静态资源不拦截 anon指的是匿名--> /static/*=anon /user/tologin.do=anon /user/login.do=anon /user/list.do=perms[user] <!--配置退出登录的请求 logout是shiro自带的一个退出登录的过滤器--> /user/logout.do=logout <!--authc是指必须经过认证--> /**=user <!-- /*=authc /*/*=authc--> </value> </property> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.aaa.ssm.controller"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--配置以注解的方式声明shiro--> <aop:config proxy-target-class="true"></aop:config> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"></property> </bean> <!--spring统一异常处理机制--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="defaultErrorView" value="../../error"></property> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!--解决中文乱码--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>/user/tologin.do</welcome-file> </welcome-file-list> </web-app>
<?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>aaa</groupId> <artifactId>maven_meun</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring.version>4.3.18.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</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.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>6</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.18.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!--json转化--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectj相关jar包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.5.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build> </project>