springboot mybatis redis shiro 权限控制(springboot模块化使用,后台代码已经完成)

springboot mybatis redis shiro 权限控制(springboot模块化使用,后台代码已经完成)

配置文件 以及 module创建

1、新建parent maven项目,编写 pom.xml

<?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.vuix</groupId>
    <artifactId>vuixparent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>service</module>
        <module>bts</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>1.8.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.44</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-cas</artifactId>
            <version>1.2.4</version>
        </dependency>
    </dependencies>


</project>

2、新建service module maven项目,编写pom.xml

<?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">
    <parent>
        <artifactId>vuixparent</artifactId>
        <groupId>com.vuix</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service</artifactId>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、新建bts module maven工程 pom.xml

<?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">
    <parent>
        <artifactId>vuixparent</artifactId>
        <groupId>com.vuix</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bts</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.vuix</groupId>
            <artifactId>service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>


</project>

4、在应用 bts 下面resources 下面新建 application.yml

server:
  port: 8888
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_vuix
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
  redis:
    database: 0
    password:
    port: 6379
    host: 127.0.0.1
    pool:
      max-active: 8
      max-wait: 10
      max-idle: 8
      min-idle: 0
  thymeleaf:
      cache: false
      mode: LEGACYHTML5

mybatis:
  config-location: classpath:mybatis-config.xml
  type-aliases-package: com.vuix.dao.entity
  mapper-locations: classpath:mapper/*.xml

下面是mapper.xml配合和应用代码

## mybatis-config.xml 代码如下 ##
<?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>
        <!--&lt;!&ndash; 这个配置使全局的映射器启用或禁用缓存 &ndash;&gt;-->
        <!--<setting name="cacheEnabled" value="true" />-->
        <!--&lt;!&ndash; 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 &ndash;&gt;-->
        <!--<setting name="lazyLoadingEnabled" value="true" />-->
        <!--&lt;!&ndash; 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 &ndash;&gt;-->
        <!--<setting name="aggressiveLazyLoading" value="true" />-->
        <!--&lt;!&ndash; 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) &ndash;&gt;-->
        <!--<setting name="multipleResultSetsEnabled" value="true" />-->
        <!--&lt;!&ndash; 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 &ndash;&gt;-->
        <!--<setting name="useColumnLabel" value="true" />-->
        <!--&lt;!&ndash; 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) &ndash;&gt;-->
        <!--<setting name="useGeneratedKeys" value="true" />-->
        <!--&lt;!&ndash; 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) &ndash;&gt;-->
        <!--<setting name="autoMappingBehavior" value="PARTIAL" />-->
        <!--&lt;!&ndash;当检测出未知列(或未知属性)时,如何处理,默认情况下没有任何提示,这在测试的时候很不方便,不容易找到错误。-->
        <!--NONE : 不做任何处理 (默认值)-->
        <!--WARNING : 警告日志形式的详细信息-->
        <!--FAILING : 映射失败,抛出异常和详细信息-->
        <!--&ndash;&gt;-->
        <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>-->
        <!--&lt;!&ndash; 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 &ndash;&gt;-->
        <!--<setting name="defaultExecutorType" value="SIMPLE" />-->
        <!--&lt;!&ndash; 设置超时时间,它决定驱动等待一个数据库响应的时间 &ndash;&gt;-->
        <!--<setting name="defaultStatementTimeout" value="25000" />-->
        <!--&lt;!&ndash;设置查询返回值数量,可以被查询数值覆盖  &ndash;&gt;-->
        <!--<setting name="defaultFetchSize" value="100"/>-->
        <!--&lt;!&ndash; 允许在嵌套语句中使用分页&ndash;&gt;-->
        <!--<setting name="safeRowBoundsEnabled" value="false"/>-->
        <!--&lt;!&ndash;是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。&ndash;&gt;-->
        <!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
        <!--&lt;!&ndash;MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。&ndash;&gt;-->
        <!--<setting name="localCacheScope" value="SESSION"/>-->
        <!--&lt;!&ndash; 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR-->
        <!--OTHER。&ndash;&gt;-->
        <!--<setting name="jdbcTypeForNull" value="OTHER"/>-->
        <!--&lt;!&ndash; 指定哪个对象的方法触发一次延迟加载。&ndash;&gt;-->
        <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>

    <!-- 别名定义 -->
    <!--<typeAliases>-->
        <!--<typeAlias alias="pageAccessURL" type="com.lgm.mybatis.model.PageAccessURL" />-->
    <!--</typeAliases>-->

    <!--自定义类型处理器 -->
    <!--<typeHandlers>-->
        <!--&lt;!&ndash; <typeHandler handler="com.xhm.util.BooleanTypeHandlder" /> &ndash;&gt;-->
        <!--&lt;!&ndash;扫描整个包下的自定义类型处理器&ndash;&gt;-->
        <!--<package name="com.xhm.util"/>-->
    <!--</typeHandlers>-->

    <!--plugins插件之 分页拦截器  -->
    <!--<plugins>-->
        <!---->
    <!--</plugins>-->
</configuration>

业务代码的mapper.xml代码如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.vuix.dao.mapper.MenuMapper" >
    <resultMap id="BaseResultMap" type="com.vuix.dao.entity.MenuEntity" >
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="icon" property="icon"/>
        <result column="parent_id" property="parentId" />
        <result column="is_delete" property="isDelete" />
        <result column="url" property="url"/>
        <result column="created_time" property="createdTime" />
        <result column="update_time" property="updateTime"/>
    </resultMap>

    <select id="queryByPrimarykey" resultMap="BaseResultMap">
        select * from xx_menu where is_delete = 0 and id = #{id}
    </select>

    <select id="findListByParentId" resultMap="BaseResultMap" parameterType="long">
        select * from xx_menu where parent_id = #{parentId}
    </select>

</mapper>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.vuix.dao.mapper.SysPermissionMapper" >
    <resultMap id="BaseResultMap" type="com.vuix.dao.entity.SysPermission" >
        <id column="id" property="id" />
        <result column="available" property="available" />
        <result column="name" property="name"/>
        <result column="parent_id" property="parentId" />
        <result column="parent_ids" property="parentIds"/>
        <result column="permission" property="permission" />
        <result column="resource_type" property="resourceType"/>
        <result column="url" property="url" />
    </resultMap>

    <select id="findListByRoleId" resultMap="BaseResultMap" parameterType="long">
        select * from sys_permission where id in (select permission_id from sys_role_permission where role_id = #{roleId})
    </select>

    <select id="queryAll" resultMap="BaseResultMap" >
        select * from sys_permission
    </select>

</mapper>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.vuix.dao.mapper.SysRoleMapper" >
    <resultMap id="BaseResultMap" type="com.vuix.dao.entity.SysRole" >
        <id column="id" property="id" />
        <result column="available" property="available" />
        <result column="description" property="description"/>
        <result column="role" property="role" />
    </resultMap>

    <select id="findListByUid" resultMap="BaseResultMap" parameterType="long">
        select * from sys_role where id in (select role_id from sys_user_role where uid = #{uid})
    </select>

</mapper>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.vuix.dao.mapper.TeampleMapper" >
    <resultMap id="BaseResultMap" type="com.vuix.dao.entity.TeampleEntity" >
        <id column="id" property="id" />
        <result column="user_name" property="userName" />
        <result column="password" property="password"/>
        <result column="phone" property="phone" />
    </resultMap>

    <select id="queryByPrimarykey" resultMap="BaseResultMap">
        select * from xx_teample where id = #{id}
    </select>
    
    <select id="queryAll" resultMap="BaseResultMap">
        select * from xx_teample order by id desc
    </select>

</mapper>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.vuix.dao.mapper.UserInfoMapper" >

    <resultMap id="BaseResultMap" type="com.vuix.dao.entity.UserInfo">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="name" column="name"/>
        <result property="password" column="password"/>
        <result property="salt" column="salt"/>
        <result property="state" column="state"/>
    </resultMap>

    <select id="findByUsername" parameterType="string" resultMap="BaseResultMap">
        select * from user_info where username = #{username}
    </select>

</mapper>

下面是java类


## entity 类##
package com.vuix.dao;

import com.alibaba.fastjson.JSON;

import java.io.Serializable;

public class ABaseEntity implements Serializable{

    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

package com.vuix.dao.entity;

import java.io.Serializable;
import java.util.List;

public class UserInfo implements Serializable{

    private Long uid;

    private String username;

    private String name;

    private String password;

    private String salt;

    private int state;

    private List<SysRole> roleList;

    public List<SysRole> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<SysRole> roleList) {
        this.roleList = roleList;
    }

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    /**
     * 密码盐.
     * @return
     */
    public String getCredentialsSalt(){
        return this.username+this.salt;
    }
}

package com.vuix.dao.entity;

import com.vuix.dao.ABaseEntity;

public class TeampleEntity extends ABaseEntity {

    private String userName;

    private String password;

    private String phone;

    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 getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}


package com.vuix.dao.entity;

import java.io.Serializable;

public class SysUserRole implements Serializable {

    private Long roleId;

    private Long uid;

    public Long getRoleId() {
        return roleId;
    }

    public void setRoleId(Long roleId) {
        this.roleId = roleId;
    }

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }
}


package com.vuix.dao.entity;

import java.io.Serializable;

public class SysRolePermission implements Serializable{

    private Long permissionId;

    private Long roleId;

    public Long getPermissionId() {
        return permissionId;
    }

    public void setPermissionId(Long permissionId) {
        this.permissionId = permissionId;
    }

    public Long getRoleId() {
        return roleId;
    }

    public void setRoleId(Long roleId) {
        this.roleId = roleId;
    }
}


package com.vuix.dao.entity;

import java.io.Serializable;
import java.util.List;

public class SysRole implements Serializable {

    private Long id;

    private Integer available;

    private String description;

    private String role;

    private List<SysPermission> permissions;



    public List<SysPermission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<SysPermission> permissions) {
        this.permissions = permissions;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getAvailable() {
        return available;
    }

    public void setAvailable(Integer available) {
        this.available = available;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

package com.vuix.dao.entity;

import java.io.Serializable;
import java.util.List;

public class SysPermission implements Serializable {

    private Long id;

    private Integer available;

    private String name;

    private Long parentId;

    private String parentIds;

    private String permission;

    private String resourceType;

    private String url;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getAvailable() {
        return available;
    }

    public void setAvailable(Integer available) {
        this.available = available;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getParentId() {
        return parentId;
    }

    public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    public String getParentIds() {
        return parentIds;
    }

    public void setParentIds(String parentIds) {
        this.parentIds = parentIds;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }

    public String getResourceType() {
        return resourceType;
    }

    public void setResourceType(String resourceType) {
        this.resourceType = resourceType;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

package com.vuix.dao.entity;

import com.vuix.dao.ABaseEntity;

import java.util.Date;
import java.util.List;

public class MenuEntity extends ABaseEntity {

    private String name;

    private String icon;

    private Long parentId;

    private Integer isDelete;

    private String url;

    private Date createdTime;

    private Date updateTime;

    private boolean isHasMenu = false;

    public boolean isHasMenu() {
        return isHasMenu;
    }

    public void setHasMenu(boolean hasMenu) {
        isHasMenu = hasMenu;
    }

    private List<MenuEntity> list;

    public List<MenuEntity> getList() {
        return list;
    }

    public void setList(List<MenuEntity> list) {
        this.list = list;
    }

    public Integer getIsDelete() {
        return isDelete;
    }

    public void setIsDelete(Integer isDelete) {
        this.isDelete = isDelete;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public Long getParentId() {
        return parentId;
    }

    public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Date getCreatedTime() {
        return createdTime;
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}

## mapper 类 ##

package com.vuix.dao;

import java.util.List;

public interface IBaseMapper<T extends ABaseEntity> {

    // 增加
    Long insert(T entity);

    // 修改
    void update(T entity);

    // 删除
    void deleteByPrimarykey(Long id);

    // 查询单个对象
    T queryByPrimarykey(Long id);

    // 分页查询
    List<T> queryByPager(APagerEntity<T> pagerEntity);

    // 查询所有的
    List<T> queryAll();

}

package com.vuix.dao;

public class APagerEntity<T extends ABaseEntity> {

    // 条件
    private T entity;

    public APagerEntity(){
        super();
    }

    private int index; // 当前页码

    private int isStart = 0; // 开始值  entity 下面不得有这些条件

    private int isLength = 10; // 大小 entity 下面不得有这些条件

    public T getEntity() {
        return entity;
    }

    public void setEntity(T entity) {
        this.entity = entity;
    }

    public int getIndex() {
        if (index <= 0) {
            index = 1;
        }
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public int getIsStart() {
        isStart = (getIndex() - 1 ) * getIsLength();
        return isStart;
    }

    public void setIsStart(int isStart) {
        this.isStart = isStart;
    }

    public int getIsLength() {
        return isLength;
    }

    public void setIsLength(int isLength) {
        this.isLength = isLength;
    }
}

package com.vuix.dao.mapper;

import com.vuix.dao.entity.UserInfo;
import org.apache.ibatis.annotations.Param;

public interface UserInfoMapper {

    // 用户名查询 userInfo
    UserInfo findByUsername(@Param("username") String username);

}

package com.vuix.dao.mapper;

import com.vuix.dao.IBaseMapper;
import com.vuix.dao.entity.TeampleEntity;

public interface TeampleMapper extends IBaseMapper<TeampleEntity> {
}

package com.vuix.dao.mapper;

import com.vuix.dao.entity.SysRole;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface SysRoleMapper {

    // 查询用户权限
    List<SysRole> findListByUid(@Param("uid") Long uid);
}


package com.vuix.dao.mapper;

import com.vuix.dao.entity.SysPermission;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface SysPermissionMapper {

    List<SysPermission> findListByRoleId(@Param("roleId") Long roleId);

    List<SysPermission> queryAll();
    
}


package com.vuix.dao.mapper;

import com.vuix.dao.IBaseMapper;
import com.vuix.dao.entity.MenuEntity;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface MenuMapper extends IBaseMapper<MenuEntity> {

    List<MenuEntity> findListByParentId(@Param("parentId") Long parentId);

}


## util 类 ##

package com.vuix.util;

public class VuixUtil {

    public static boolean isNull(String value) {
        if (value == null || value.trim().equals("") || value.length() == 0){
            return true;
        }
        return false;
    }

    public static boolean isNotNull(String value) {
        return !isNull(value);
    }


}

## service类##

package com.vuix.service;

import com.alibaba.fastjson.JSON;
import com.vuix.util.VuixUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;

/**
 * @Cacheable    表明在Spring调用之前,首先应该在缓存中查找方法的返回值,
 *              如果这个值能够找到,就会返回缓存的值,
 *              否则这个方法会被调用,返回值会放到缓存中
 *
 * @CachePut    表明Spring应该将该方法返回值放到缓存中,在方法调用前不会检查缓存,方法始终会被调用
 *
 * @CacheEvict    表明Spring应该在缓存中清楚一个或多个条目
 *
 * @Caching    分组注解,能够同时应用多个其他的缓存注解
 *
 * @CacheConfig    可以在类层级配置一些共有的缓存配置
 *
 * @Cacheable和@CachePut有一些共有的属性:
 *
 *      属性    类型    描述
 *      value    String[]    缓存名称
 *      condition    SpEL表达式,如果得到的值是false,则不会应用缓存在该方法
 *      key    String    SpEl表达式,用来计算自定义的缓存key
 *      unless    String    SpEl表达式,如果得到的值为true,返回值不会放到缓存中
 *
 */
public abstract class ABaseService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    protected static final String root_symbol = ":";

    // 默认保存时间
    protected static final Long default_millisecond = 24 * 60 * 60 * 1000L;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    protected String generalRedisKey(String... parameters) {
        StringBuffer stringBuffer = new StringBuffer();
        if (parameters.length > 0) {
            for (String parameter : parameters) {
                stringBuffer.append(parameter).append(root_symbol);
            }
        }
        if (stringBuffer.length() > 0) {
            return stringBuffer.toString().substring(0,stringBuffer.length()-1);
        }
        return null;
    }

    protected void removeCache(String key) {
        if (VuixUtil.isNotNull(key)){
            stringRedisTemplate.delete(key);
        }
    }

    protected <T>List<T> getListCache(String key,Class<T> targetClass) {
        if (VuixUtil.isNotNull(key)) {
            String value = stringRedisTemplate.opsForValue().get(key);
            logger.info("ABaseService getListCache:value:{}",value);
            if (VuixUtil.isNotNull(value)){
                List<T> targets = JSON.parseArray(value,targetClass);
                return targets;
            }
        }
        return null;
    }

    // get缓存
    protected <T> T getFormCache(String key,Class<T> targetClass) {
        if (VuixUtil.isNotNull(key)) {
            String value = stringRedisTemplate.opsForValue().get(key);
            if (VuixUtil.isNotNull(value)){
                logger.info("ABaseService getFormCache:value:{}",value);
                T target = JSON.parseObject(value,targetClass);
                return target;
            }
        }
        return null;
    }

    // 放进缓存
    protected void putCache(String key,Object object) {
        putCache(key,object,default_millisecond);
    }

    protected void putCache(String key,Object object,Long millisecond) {
        if (object != null) {
            String value = JSON.toJSONString(object);
            logger.info("ABaseService putCache:value:{}",value);
            stringRedisTemplate.opsForValue().set(key,value,millisecond);
        }
    }

}


package com.vuix.service;

public interface RootNamespace {

    String root_namespace = "root";

    String root_symbol = ":";

}


package com.vuix.service;

import com.vuix.dao.entity.MenuEntity;

import java.util.List;

public interface MenuService extends RootNamespace {

    List<MenuEntity> findList(Long parentId);

}


package com.vuix.service;

import com.vuix.dao.entity.SysPermission;

import java.util.List;

public interface SysPermissionService extends RootNamespace{

    String class_name = "sysPermission";

    List<SysPermission> findListByRoleId(Long roleId);

    // 查询全部的权限
    List<SysPermission> queryAll();
}

package com.vuix.service;

import com.vuix.dao.entity.SysRole;

import java.util.List;

public interface SysRoleService extends RootNamespace {

    String class_name = "sysRole";

    List<SysRole> findListByUid(Long uid);
}


package com.vuix.service;

import com.vuix.dao.entity.TeampleEntity;

import java.util.List;

public interface TeampleService extends RootNamespace {

    String class_name = "teample";

    TeampleEntity queryByPrimarykey(Long id);

    List<TeampleEntity> queryAll();

    void update(TeampleEntity entity);

    Long insert(TeampleEntity entity);

}


package com.vuix.service;

import com.vuix.dao.entity.UserInfo;

public interface UserInfoService extends RootNamespace{

    String class_name = "userInfo";

    UserInfo findByUsername(String username);

}


## service impl 类 ###
package com.vuix.service.impl;

import com.vuix.dao.entity.MenuEntity;
import com.vuix.dao.mapper.MenuMapper;
import com.vuix.service.ABaseService;
import com.vuix.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MenuServiceImpl extends ABaseService implements MenuService{

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List<MenuEntity> findList(Long parentId) {
        if (parentId == null) {
            parentId = 0L;
        }
        // 加入redis 缓存  做两级菜单  后期有的话  使用递归
        List<MenuEntity> list = menuMapper.findListByParentId(parentId);
        for (MenuEntity menu : list) {
            List<MenuEntity> list2 = menuMapper.findListByParentId(menu.getId());
            if ( list2 != null && list2.size() > 0) {
                menu.setHasMenu(true);
                menu.setList(list2);
            }
        }
        return list;
    }
}

package com.vuix.service.impl;

import com.vuix.dao.entity.SysPermission;
import com.vuix.dao.mapper.SysPermissionMapper;
import com.vuix.service.ABaseService;
import com.vuix.service.SysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SysPermissionServiceImpl extends ABaseService implements SysPermissionService {

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Override
    public List<SysPermission> findListByRoleId(Long roleId) {
//        String key = generalRedisKey(root_namespace,class_name,"roleId",roleId.toString());
//        List<SysPermission> list = getListCache(key,SysPermission.class);
//        if (list == null) {
//            list = sysPermissionMapper.findListByRoleId(roleId);
//            putCache(key,list);
//        }
        return sysPermissionMapper.findListByRoleId(roleId);
    }

    @Override
    public List<SysPermission> queryAll() {
        return sysPermissionMapper.queryAll();
    }
}

package com.vuix.service.impl;

import com.vuix.dao.entity.SysRole;
import com.vuix.dao.mapper.SysRoleMapper;
import com.vuix.service.ABaseService;
import com.vuix.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SysRoleServiceImpl extends ABaseService implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Override
    public List<SysRole> findListByUid(Long uid) {
//        String key = generalRedisKey(root_namespace,class_name,"uid",uid.toString());
//        List<SysRole> list = getListCache(key,SysRole.class);
//        if (list == null) {
//            list = sysRoleMapper.findListByUid(uid);
//            putCache(key,list);
//        }
        return sysRoleMapper.findListByUid(uid);
    }
}


package com.vuix.service.impl;

import com.vuix.dao.entity.TeampleEntity;
import com.vuix.dao.mapper.TeampleMapper;
import com.vuix.service.ABaseService;
import com.vuix.service.TeampleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class TeampleServiceImpl extends ABaseService implements TeampleService {

    @Autowired
    private TeampleMapper teampleMapper;

    @Override
    public TeampleEntity queryByPrimarykey(Long id) {
        String key = generalRedisKey(root_namespace,class_name,id.toString());
        TeampleEntity result = getFormCache(key,TeampleEntity.class);
        if (result == null) {
            result = teampleMapper.queryByPrimarykey(id);
            putCache(key,result);
        }
        return result;
    }

    @Override
    public List<TeampleEntity> queryAll() {
        List<TeampleEntity> list = teampleMapper.queryAll();
        return list;
    }

    @Override
    public void update(TeampleEntity entity) {

    }

    @Override
    public Long insert(TeampleEntity entity) {
        return null;
    }
}


package com.vuix.service.impl;

import com.vuix.dao.entity.SysPermission;
import com.vuix.dao.entity.SysRole;
import com.vuix.dao.entity.UserInfo;
import com.vuix.dao.mapper.UserInfoMapper;
import com.vuix.service.ABaseService;
import com.vuix.service.SysPermissionService;
import com.vuix.service.SysRoleService;
import com.vuix.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserInfoServiceImpl extends ABaseService implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPermissionService sysPermissionService;

    @Override
    public UserInfo findByUsername(String username) {
        // 查询redis下面的值
//        String key = generalRedisKey(root_namespace,class_name,"username",username);
//        UserInfo userInfo = getFormCache(key,UserInfo.class);
//        if (userInfo == null) {
            // 数据库处理业务
            UserInfo userInfo = userInfoMapper.findByUsername(username);
            // 放入缓存
//            putCache(key,userInfo);
//        }
        // 查询权限
        List<SysRole> sysRoles = sysRoleService.findListByUid(userInfo.getUid());
        // 给sysRole对象  赋值权限
        for (SysRole sysRole : sysRoles) {
            List<SysPermission> sysPermissions = sysPermissionService.findListByRoleId(sysRole.getId());
            sysRole.setPermissions(sysPermissions);
        }
        userInfo.setRoleList(sysRoles);
        return userInfo;
    }
}

下面是bts下面controller包下面的java类

package com.vuix.bts;

import com.vuix.dao.entity.UserInfo;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public abstract class ABaseController {

    protected final Logger logger = LoggerFactory.getLogger(ABaseController.class);


    protected UserInfo getCurrentUserInfo(){
        UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        return userInfo;
    }

    /**
     * springMVC 获取requset
     *
     * @return
     */
    public HttpServletRequest getRequest() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        return request;
    }

    /**
     * 获取response
     *
     * @return
     */
    public HttpServletResponse getResponse() {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getResponse();
        return response;
    }

    /**
     * 获取session
     *
     * @return
     */
    public HttpSession getSession() {
        HttpSession session = this.getRequest().getSession();
        return session;
    }

    /**
     * 获取ServletContext
     *
     * @return
     */
    public ServletContext getServletContent() {
        // ServletContext application= request.getServletContext();

        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext servletContext = webApplicationContext.getServletContext();
        return servletContext;
    }

    /**
     * 获取ModelAndView
     *
     * @return
     */
    public ModelAndView getModelAndView() {
        return new ModelAndView();
    }

    public ModelAndView get404ModelAndView() {
        ModelAndView view = new ModelAndView();
        view.setViewName("404");
        return view;
    }

    /**
     * 获取ip
     *
     * @return
     */
    public String getRemortIP() {
        HttpServletRequest request = this.getRequest();
        String ip = "";
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        return ip;
    }

    /**
     * 获取port
     *
     * @return
     */
    public int getPort() {
        return this.getRequest().getServerPort();
    }

    /**
     * 获取ip
     *
     * @return
     */
    public String getIpAddr() {
        HttpServletRequest request = this.getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}


package com.vuix.bts.controller;


import com.alibaba.fastjson.JSON;
import com.vuix.bts.ABaseController;
import com.vuix.dao.entity.MenuEntity;
import com.vuix.dao.entity.UserInfo;
import com.vuix.service.MenuService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

@Controller
public class IndexController extends ABaseController{

    @Autowired
    private MenuService menuService;

    @RequestMapping({"/","/index"})
    public String index(Model model) {
        // 加载菜单树
        List<MenuEntity> menuList = menuService.findList(null);
        // 获取登录用户的详细
        UserInfo userInfo = getCurrentUserInfo();

        logger.info("IndexController index:  userInfo:{}", JSON.toJSONString(userInfo));
        model.addAttribute("userInfo",userInfo);
        model.addAttribute("menuList",menuList);
        return"/index";
    }

    @RequestMapping(value = "logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        //跳转登陆页面
        return "login";
    }

    @RequestMapping("/login")
    public String login(HttpServletRequest request, Map<String, Object> map) throws Exception{
        logger.info("HomeController.login()");
        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.
        String exception = (String) request.getAttribute("shiroLoginFailure");
        logger.info("exception:{}",exception);
        String msg = "";
        if (exception != null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                logger.error("UnknownAccountException -- > 账号不存在:");
                msg = "UnknownAccountException -- > 账号不存在:";
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                logger.error("IncorrectCredentialsException -- > 密码不正确:");
                msg = "IncorrectCredentialsException -- > 密码不正确:";
            } else if ("kaptchaValidateFailed".equals(exception)) {
                logger.error("kaptchaValidateFailed -- > 验证码错误");
                msg = "kaptchaValidateFailed -- > 验证码错误";
            } else {
                msg = "else >> "+exception;
                logger.error("else -- >" + exception);
            }
        }
        map.put("msg", msg);
        // 此方法不处理登录成功,由shiro进行处理
        return "/login";
    }

    @RequestMapping("/403")
    public String unauthorizedRole(){
        logger.info("------没有权限-------");
        return "403";
    }


}

package com.vuix.bts.controller;

import com.vuix.bts.ABaseController;
import com.vuix.dao.entity.MenuEntity;
import com.vuix.service.MenuService;
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(value = "menu")
public class MenuController extends ABaseController{

    @Autowired
    private MenuService menuService;

    @RequestMapping(value = "list")
    public String list(Model model) {
        List<MenuEntity> list = menuService.findList(null);
        model.addAttribute("list",list);
        return "page/menu/list";
    }

}


package com.vuix.bts.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PageController {

    private static final Logger logger = LoggerFactory.getLogger(PageController.class);

    @RequestMapping("/include/{pageName}")
    public String include(@PathVariable("pageName") String pageName){
        logger.info("PageController include : /include/"+pageName);
        return "include/"+pageName;
    }

}

package com.vuix.bts.controller;

import com.vuix.bts.ABaseController;
import com.vuix.dao.entity.TeampleEntity;
import com.vuix.service.TeampleService;
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(value = "teample")
public class TeampleController extends ABaseController{

    @Autowired
    private TeampleService teampleService;

    @RequestMapping(value = "list")
    public String list(Model model) {
        List<TeampleEntity> list = teampleService.queryAll();
        model.addAttribute("list",list);
        return "page/teample/list";
    }
}


package com.vuix.bts.controller;


import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/userInfo")
public class UserInfoController {

    /**
     * 用户查询.
     * @return
     */
    @RequestMapping("/userList")
    @RequiresPermissions("userInfo:view")//权限管理;
    public String userInfo(){
        return "userInfo";
    }

    /**
     * 用户添加;
     * @return
     */
    @RequestMapping("/userAdd")
    @RequiresPermissions("userInfo:add")//权限管理;
    public String userInfoAdd(){
        return "userInfoAdd";
    }

    /**
     * 用户删除;
     * @return
     */
    @RequestMapping("/userDel")
    @RequiresPermissions("userInfo:del")//权限管理;
    public String userDel(){
        return "userInfoDel";
    }

    @RequestMapping("/userEdit")
    @RequiresPermissions("userInfo:edit")//权限管理;
    public String userEdit(){
        return "userInfoEdit";
    }

}

## bts Config类 ##
package com.vuix.bts.config;

import com.alibaba.fastjson.JSON;
import com.vuix.dao.entity.SysPermission;
import com.vuix.dao.entity.SysRole;
import com.vuix.dao.entity.UserInfo;
import com.vuix.service.UserInfoService;
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.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class LoginShiroRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(LoginShiroRealm.class);

    @Autowired
    private UserInfoService userInfoService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.info("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        UserInfo userInfo  = (UserInfo)principals.getPrimaryPrincipal();
        for(SysRole role:userInfo.getRoleList()){
            authorizationInfo.addRole(role.getRole());
            for(SysPermission p:role.getPermissions()){
                authorizationInfo.addStringPermission(p.getPermission());
            }
        }
        return authorizationInfo;
    }

    /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        logger.info("LoginShiroRealm.doGetAuthenticationInfo()");
        //获取用户的输入的账号.
        String username = (String)token.getPrincipal();
        logger.info("token.getCredentials() : str:{}", JSON.toJSONString(token.getCredentials()));
        //通过username从数据库中查找 User对象,如果找到,没找到.
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        UserInfo userInfo = userInfoService.findByUsername(username);
        logger.info("----->>userInfo={}",JSON.toJSONString(userInfo));
        if(userInfo == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassword(), //密码
                ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }

}

package com.vuix.bts.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.Method;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{

//    @Bean
//    public KeyGenerator keyGenerator() {
//        return new KeyGenerator() {
//            @Override
//            public Object generate(Object target, Method method, Object... params) {
//                StringBuilder sb = new StringBuilder();
//                sb.append(target.getClass().getSimpleName());
//                sb.append(method.getName());
//                for (Object obj : params) {
//                    sb.append(obj.toString());
//                }
//                return sb.toString();
//            }
//        };
//    }

    @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间
        //rcm.setDefaultExpiration(60);//秒
        return redisCacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory);
        return stringRedisTemplate;
    }

}

package com.vuix.bts.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class SessionConfig {
}

package com.vuix.bts.config;

import com.vuix.dao.entity.SysPermission;
import com.vuix.service.SysPermissionService;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

@Configuration
public class ShiroConfig {

    private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

    @Autowired
    private SysPermissionService sysPermissionService;

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        logger.info("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/bower_components/**", "anon");
        filterChainDefinitionMap.put("/dist/**", "anon");
        filterChainDefinitionMap.put("/images/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/plugins/**", "anon");
        filterChainDefinitionMap.put("/ztree/**", "anon");
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->

        List<SysPermission> sysPermissions = sysPermissionService.queryAll();
        for (SysPermission sysPermission : sysPermissions) {
            filterChainDefinitionMap.put("/" + sysPermission.getUrl(), "perms["+sysPermission.getPermission()+"]");
        }
        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
        return hashedCredentialsMatcher;
    }

    @Bean
    public LoginShiroRealm loginShiroRealm(){
        LoginShiroRealm loginShiroRealm = new LoginShiroRealm();
        loginShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return loginShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(loginShiroRealm());
        return securityManager;
    }

    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
        mappings.setProperty("UnauthorizedException","403");
        r.setExceptionMappings(mappings);  // None by default
        r.setDefaultErrorView("error");    // No default
        r.setExceptionAttribute("ex");     // Default is "exception"
        //r.setWarnLogCategory("example.MvcLogger");     // No default
        return r;
    }
}

启动类 BtsMainApplication


package com.vuix;

import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.vuix.dao.mapper")
public class BtsMainApplication {

    private static final Logger logger = LoggerFactory.getLogger(BtsMainApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(BtsMainApplication.class,args);

        logger.info("BtsMainApplication main running...");
    }
}
下面附上对应的sql

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50537
Source Host           : localhost:3306
Source Database       : db_vuix

Target Server Type    : MYSQL
Target Server Version : 50537
File Encoding         : 65001

Date: 2018-04-27 15:37:24
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `sys_permission`
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `available` int(10) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `parent_ids` varchar(255) DEFAULT NULL,
  `permission` varchar(255) DEFAULT NULL,
  `resource_type` varchar(255) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '0', '用户管理', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userList');
INSERT INTO `sys_permission` VALUES ('2', '0', '用户添加', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd');
INSERT INTO `sys_permission` VALUES ('3', '0', '用户删除', '1', '0/1', 'userInfo:del', 'button', 'userInfo/userDel');

-- ----------------------------
-- Table structure for `sys_role`
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `available` int(10) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  `role` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', '0', '管理员', 'admin');
INSERT INTO `sys_role` VALUES ('2', '0', 'VIP会员', 'vip');
INSERT INTO `sys_role` VALUES ('3', '1', 'test', 'test');

-- ----------------------------
-- Table structure for `sys_role_permission`
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `permission_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('2', '1');
INSERT INTO `sys_role_permission` VALUES ('3', '2');

-- ----------------------------
-- Table structure for `sys_user_role`
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `role_id` int(11) NOT NULL,
  `uid` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('1', '1');

-- ----------------------------
-- Table structure for `user_info`
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `password` varchar(255) NOT NULL,
  `salt` varchar(255) DEFAULT NULL,
  `state` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_info
-- ----------------------------
INSERT INTO `user_info` VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', '0');
INSERT INTO `user_info` VALUES ('2', 'yang', 'VIP', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', '0');

-- ----------------------------
-- Table structure for `xx_menu`
-- ----------------------------
DROP TABLE IF EXISTS `xx_menu`;
CREATE TABLE `xx_menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `icon` varchar(255) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `is_delete` int(2) DEFAULT '0' COMMENT '是否删除  0:未删除 1:删除',
  `url` varchar(255) DEFAULT NULL,
  `created_time` datetime DEFAULT NULL,
  `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of xx_menu
-- ----------------------------
INSERT INTO `xx_menu` VALUES ('1', '系统管理', 'fa fa-gears', '0', '0', '#', '2018-04-13 14:54:36', '2018-04-13 15:35:19');
INSERT INTO `xx_menu` VALUES ('2', '菜单管理', 'fa fa-gears', '1', '0', 'menu/list', '2018-04-13 14:55:12', '2018-04-13 15:33:59');
INSERT INTO `xx_menu` VALUES ('3', '模板自定义', 'fa fa-gears', '1', '0', 'teample/list', '2018-04-13 16:46:48', '2018-04-13 16:46:50');

-- ----------------------------
-- Table structure for `xx_teample`
-- ----------------------------
DROP TABLE IF EXISTS `xx_teample`;
CREATE TABLE `xx_teample` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `phone` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of xx_teample
-- ----------------------------
INSERT INTO `xx_teample` VALUES ('1', 'yang_zhongren', '123456', '15261811115');
INSERT INTO `xx_teample` VALUES ('2', '杨中仁', '21121', '18888888888');

做了好几年了 也不知道怎么写文章 多多包涵

案例下面的代码 直接复制粘贴过来的 如果有何不懂的 可以直接在下面提问。

    原文作者:疯狂的杨中仁
    原文地址: https://segmentfault.com/a/1190000014636600
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞