SSM项目与Shiro项目的整合(单体式项目)

Posted psy-code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSM项目与Shiro项目的整合(单体式项目)相关的知识,希望对你有一定的参考价值。

1.项目的包结构:

技术分享图片

2.jar包,配置文件及工具类

2.1pom.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.zy</groupId>
  <artifactId>ssm-shiro</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>ssm-shiro Maven Webapp</name>
  <!-- FIXME change it to the projects website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <shiro.version>1.2.3</shiro.version>
    <commons-logging.version>1.2</commons-logging.version>
    <!--spring家族版本号-->
    <spring.version>4.2.4.RELEASE</spring.version>
    <!--aop版本-->
    <org.aspectj.version>1.6.11</org.aspectj.version>
    <aopalliance.version>1.0</aopalliance.version>
    <!--数据源,mybatis,分页相关配置-->
    <druid.version>1.0.21</druid.version>
    <mybatis.version>3.2.6</mybatis.version>
    <mybatis.spring.version>1.3.1</mybatis.spring.version>
    <pageHelper.version>5.1.2</pageHelper.version>
    <mybatis-paginator.version>1.2.15</mybatis-paginator.version>
    <mysql.version>5.1.45</mysql.version>
    <!--jsp-->
    <jstl.version>1.2</jstl.version>
    <servlet.api>2.5</servlet.api>
    <jsp.api.version>2.0</jsp.api.version>
    <!--动态代理-->
    <cglib.version>2.1_3</cglib.version>
    <!--日志-->
    <org.slf4j.version>1.6.1</org.slf4j.version>
    <!--配置junit-->
    <junit.version>4.11</junit.version>
    <!--配置jackson的包-->
    <jackson.version>2.4.2</jackson.version>
  </properties>

  <dependencies>
    <!--配置jackson的包-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
    </dependency>
    <!--配置shiro的依赖-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-quartz</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>${commons-logging.version}</version>
    </dependency>
    <!--配置spring核心包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--配置springMVC-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--配置aop-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${org.aspectj.version}</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>${org.aspectj.version}</version>
    </dependency>
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>${aopalliance.version}</version>
    </dependency>
    <!--配置数据源,连接池,Mybatis,分页插件-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${druid.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>${pageHelper.version}</version>
    </dependency>
    <dependency>
      <groupId>com.github.miemiedev</groupId>
      <artifactId>mybatis-paginator</artifactId>
      <version>${mybatis-paginator.version}</version>
    </dependency>
    <!--jsp相关-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>${servlet.api}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>${jsp.api.version}</version>
      <scope>provided</scope>
    </dependency>
    <!--动态代理-->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>${cglib.version}</version>
    </dependency>
    <!--配置日志-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${org.slf4j.version}</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>ssm-shiro</finalName>
    <!--配置静态资源不发布-->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
    <!--配置tomcat-->
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <configuration>
          <path>/</path>
          <port>8081</port>
        </configuration>
      </plugin>
    </plugins>

  </build>
</project>

2.2配置springmvc.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" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--开启自动扫包:注意这里只扫描controller层的包,防止重复扫描-->
    <context:component-scan base-package="com.zy.controller"/>

    <!--开启注解驱动:用来替换处理器适配器和处理器映射器-->
    <mvc:annotation-driven/>

    <!--视图解析器:配置返回的前缀及后缀-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--拦截静态资源并放行-->
    <mvc:default-servlet-handler />
    <!--此处的mapping指代前台引用的地址,location指代资源实际地址-->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"></mvc:resources>
    <mvc:resources mapping="/css/**" location="/WEB-INF/css/"></mvc:resources>
    <mvc:resources mapping="/fonts/**" location="/WEB-INF/fonts/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/WEB-INF/images/"></mvc:resources>
    <mvc:resources mapping="/layui/**" location="/WEB-INF/layui/"></mvc:resources>

    <!--开启aop注解支持-->
    <aop:config proxy-target-class="true"/>

    <!--开启全局异常处理-->
    <bean class="com.zy.common.MyExceptionHandler"/>

</beans>

2.3配置spring相关内容

2.3.1配置applicationContext-dao.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
       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://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">

    <!--1.配置自动扫描:注意这里只扫描dao层和service层的包,不扫描controller,防止与springmvc重复扫描-->
    <context:component-scan base-package="com.zy.mapper"/>
    <!--2.读取配置文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--3.配置数据库连接的基本情况-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--3.1数据库连接的基本属性的设置-->
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <!--3.2配置最大最小值以及初始化的值-->
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <property name="maxActive" value="10"/>
    </bean>
    <!--4.配置dao层,整合Mybatis-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--配置Mybatis的全局配置文件-->
        <property name="configLocation" value="classpath:mybatis/sqlMappingConfig.xml"/>
        <!--mapperLocations: 指定mapper文件的位置-->
        <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
    </bean>
    <!--4.1也可以扫描与mapper层同级目录的文件配置
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zy.mapper"/>
    </bean>
-->
    <!-- 扫描所有的mapper接口的实现,让这些mapper能够自动注入;
    base-package:指定mapper接口的包名
     -->
    <mybatis-spring:scan base-package="com.zy.mapper"/>
</beans>

2.3.2配置applicationContext-service.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"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

    <context:component-scan base-package="com.zy.service"/>

</beans>

2.3.3配置applicationContext-tx.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" xmlns:tx="http://www.springframework.org/schema/tx"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--5.添加事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--6.基于XML的事务-->
    <tx:advice transaction-manager="transactionManager" id="transactionInterceptor">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="query*" propagation="SUPPORTS"/>
            <tx:method name="get*" propagation="SUPPORTS"/>
            <tx:method name="find*" propagation="SUPPORTS"/>
            <tx:method name="select*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>
    <!--配置切入点-->
    <aop:config>
        <aop:pointcut id="serviceAdvice" expression="execution(* com.zy.service..* .*(..))"></aop:pointcut>
        <!--将事务织入切入对象中-->
        <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="serviceAdvice"/>
    </aop:config>
</beans>

2.3.4配置applicationContext-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.xsd">

    <!--申明缓存管理器-->
    <!--本地缓存,不推荐-->
    <!--<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>-->
    <!-- 缓存管理器使用Ehcache实现 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
    </bean>

    <!--密码凭证管理器-->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="md5"/>
        <!--次数-->
        <property name="hashIterations" value="1"/>
    </bean>

    <!--================================配置自定义的realm====================================-->
    <bean id="tbUserRealm" class="com.zy.shiro.TbUserRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher"/>
        <!--配置缓存时,改为true-->
        <property name="cachingEnabled" value="true"/>
    </bean>

    <!--记住我的cookie-->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="rememberMe"/>
        <!--设置cookie有效期-->
        <property name="maxAge" value="604800"/>
    </bean>
    <!--记住我管理器-->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>
    <!--安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="tbUserRealm"/>
        <!--注入记住我-->
        <property name="rememberMeManager" ref="rememberMeManager"/>
        <!--缓存管理器-->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!--=====================开启切面支持,spring拦截支持=====================-->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
    <!--调用securityManagerUtils.setSecurityManager-->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
        <property name="arguments" ref="securityManager"/>
    </bean>
    <!--==============================shiro的web过滤器====================================-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login/login"/>
        <property name="successUrl" value="/login/loginCheck"/>
        <property name="filterChainDefinitions">
            <value>
                <!--
                    anon:匿名使用,用户不登录也可以访问,如 /item/** = anon
                    authc:认证后才能使用           /order/** = authc
                    roles:需要特定角色才能访问    /admin/** = roles["admin,test"]
                    perms:需要特定权限才能访问    /admin/user/** = perms["user:add,user:delete"]
                    user:必须存在用户,登录而不限制检查    /** = user

                    rest: restFul风格 /adimn/** = rest[user]
                    port: 限制访问端口 /admin/** = port[8088]
                    authcBasic: 限制协议请求是https
                    ssl: 安全的url请求,请求协议是http
                -->
                <!--切记此处路径名与前台传.递的路径名是一致的,除了在此处配置以外,还需要在spring.xml中进行配置-->
                /css/** = anon<!--设置静态资源文件为游客可访问-->
                /js/** = anon<!--设置静态资源文件为游客可访问-->
                /fonts/** = anon<!--设置静态资源文件为游客可访问-->
                /images/** = anon<!--设置静态资源文件为游客可访问-->
                /layui/** = anon<!--设置静态资源文件为游客可访问-->
                <!--配置用户退出
                不用我们去实现退出,只要去访问一个退出的url(该 url是可以不存在),由LogoutFilter拦截住,清除session。
                在applicationContext-shiro.xml配置LogoutFilter
                -->
                /login/logout = logout
                <!--不拦截-->
                /login/** = anon
                /** = user
            </value>
        </property>
    </bean>

    <!--生命周期的配置-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

2.4配置mybatis相关内容
技术分享图片

2.4.1配置sqlMappingConfig.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>
        <!--开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
        <!--开启懒加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--关闭延迟加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    <!--配置分页插件pageHelper的拦截器:5.0版本之后的配置-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
</configuration>

2.4.2配置其他***Mappper.xml文件(以TbUserMapper.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.zy.mapper.TbUserMapper">

    <!--封装结果集-->
    <resultMap id="tbUserResultMap" type="com.zy.model.TbUser">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="username" property="username" jdbcType="VARCHAR"/>
        <result column="password" property="password" jdbcType="VARCHAR"/>
        <result column="salt" property="salt" jdbcType="VARCHAR"/>
        <result column="status" property="status" jdbcType="VARCHAR"/>
    </resultMap>

    <!--
    根据用户名查询用户信息
    TbUser getTbUserByUserName(String username);
    -->
    <select id="getTbUserByUserName" resultMap="tbUserResultMap">
        select id,username,password,salt,status
        from tb_user
        where username = #{username}
    </select>

    <!--
     // 注册用户
    int addTbUser(TbUser tbUser);
    -->
    <insert id="addTbUser">
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select last_insert_id()
        </selectKey>
        insert into tb_user values(null,#{username},#{password},#{salt},#{status})
    </insert>

    <!--
    // 查询所有用户信息
    List<TbUser> getAllUser();
    -->
    <select id="getAllUser" resultMap="tbUserResultMap">
        select id,username,password,salt,status
        from tb_user
    </select>

    <!--
    // 删除用户信息及其关联角色信息,还需要去关联表中删除该信息
    void deleteUser(Integer id);
    -->
    <delete id="deleteUser">
        delete from tb_user where id = #{id}
    </delete>
    <delete id="deleteUserRole">
        delete from tb_user_role where user_id = #{id}
    </delete>

</mapper>

2.5配置db.properties

####配置mysql的连接
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shiro
jdbc.username=root
jdbc.password=123456

####配置oracle的连接
orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:orcl
orcl.username=tom
orcl.password=123456

2.6配置ehcache.xml

<?xml version="1.1" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shirocache">

    <diskStore path="D:developehcache" />
    <defaultCache
            maxElementsInMemory="1000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

2.7配置log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=/scheduler.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change info to debug ###

log4j.rootLogger=debug,stdout,file

2.8mapper层,以TbUserMapper为例

技术分享图片

package com.zy.mapper;

import com.zy.model.TbUser;
import org.springframework.stereotype.Repository;

/**
 * 用户信息的Mapper
 */
import java.util.List;

/**
 * Created by Administrator on 2018/7/3.
 *
 * 用户登录的mapper
 */
@Repository
public interface TbUserMapper {

    // 根据用户名查询用户信息
    TbUser getTbUserByUserName(String username);

    // 注册用户
    int addTbUser(TbUser tbUser);

    // 查询所有用户信息
    List<TbUser> getAllUser();

    // 删除用户信息及其关联角色信息
    void deleteUser(Integer id);
    void deleteUserRole(Integer id);

}

2.9service层(以TbUserServiceI和TbUserServiceImpl为例)

技术分享图片

package com.zy.service;

import com.zy.model.TbPermission;
import com.zy.model.TbRole;
import com.zy.model.TbUser;
import com.zy.util.PageUtils;

import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018/7/3.
 */
public interface TbUserServiceI {

    // 登录验证:根据用户名查询用户信息
    TbUser getTbUserByUserName(String username);

    // 授权验证第一步:根据用户id查询用户角色
    List<TbRole> getTbRoleByUserId(Integer id);

    // 授权验证:根据用户id查询用户权限信息
    List<TbPermission> getTbPermissionByUserId(Integer userId);

    // 查询菜单信息
    Map<TbPermission, List<TbPermission>> getMenuByUserId(Integer userId);

    // 注册用户
    int addTbUser(TbUser tbUser);

    // 查询所有用户信息
    PageUtils getAllUser(Integer pageNo);

    // 删除用户信息及其关联角色信息
    void deleteUser(Integer id);

}
package com.zy.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zy.common.ConstantValue;
import com.zy.mapper.TbPermissionMapper;
import com.zy.mapper.TbRoleMapper;
import com.zy.mapper.TbUserMapper;
import com.zy.model.TbPermission;
import com.zy.model.TbRole;
import com.zy.model.TbUser;
import com.zy.service.TbUserServiceI;
import com.zy.util.MD5;
import com.zy.util.PageUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018/7/3.
 *
 * 登录的业务层
 */
@Service("tbUserService")
public class TbUserServiceImpl implements TbUserServiceI {

    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private TbRoleMapper tbRoleMapper;

    @Autowired
    private TbPermissionMapper tbPermissionMapper;

    // 登录验证:根据用户名查询用户信息
    @Override
    public TbUser getTbUserByUserName(String username) {
        TbUser tbUser = tbUserMapper.getTbUserByUserName(username);
        return tbUser;
    }

    // 授权验证第一步:根据用户id查询用户角色
    @Override
    public List<TbRole> getTbRoleByUserId(Integer id) {
        List<TbRole> tbRoleList = tbRoleMapper.getTbRoleByUserId(id);
        return tbRoleList;
    }

    // 授权验证:根据用户id查询用户权限信息
    @Override
    public List<TbPermission> getTbPermissionByUserId(Integer userId) {
        List<TbPermission> permissionList = tbPermissionMapper.getTbPermissionByUserId(userId);
        return permissionList;
    }

    // 查询菜单信息
    @Override
    public Map<TbPermission, List<TbPermission>> getMenuByUserId(Integer userId){
        List<TbPermission> permissionList = tbPermissionMapper.getTopTbPermissionByUserId(userId);
        Map<TbPermission, List<TbPermission>> map = new HashMap<TbPermission, List<TbPermission>>();
        for(TbPermission tbPermission : permissionList){
            if(tbPermission.getParentId() == null){
                // 当用户id是确定的时候,根据父菜单id查询子菜单id
                List<TbPermission> list = tbPermissionMapper.getTbPermissionByParentIdAndUserId(tbPermission.getId(),userId);
                if(list != null){
                    map.put(tbPermission,list);
                }
            }
        }
        return map;
    }

    // 注册用户
    @Override
    public int addTbUser(TbUser tbUser) {
        // 获取salt
        String salt=new SecureRandomNumberGenerator().nextBytes().toHex();
        tbUser.setSalt(salt);
        // 进行加密
        String md5Pwd = MD5.getMD5(tbUser.getPassword(), salt);
        tbUser.setPassword(md5Pwd);
        // 设置状态
        tbUser.setStatus(ConstantValue.USER_STATUS_UNLOCKED);
        tbUserMapper.addTbUser(tbUser);
        /*返回主键*/
        Integer id = tbUser.getId();
        return id;
    }

    // 查询所有用户信息
    @Override
    public PageUtils getAllUser(Integer pageNo) {
        PageHelper.startPage(pageNo, ConstantValue.PAGE_SIZE);
        List<TbUser> userList = tbUserMapper.getAllUser();
        PageUtils pageInfo = new PageUtils();
        pageInfo.setRows(userList);
        PageInfo<TbUser> pageInfoList = new PageInfo<TbUser>(userList);
        pageInfo.setTotalPages(pageInfoList.getPages());
        pageInfo.setCurrentPage(pageNo);
        pageInfo.setPageSize(pageInfoList.getPageSize());
        return pageInfo;
    }

    // 删除用户信息及其关联角色信息
    @Override
    public void deleteUser(Integer id) {
        tbUserMapper.deleteUser(id);
        tbUserMapper.deleteUserRole(id);
    }

}

2.10权限Realm(以TbUserRealm 为例)

技术分享图片

package com.zy.shiro;

import com.zy.common.ConstantValue;
import com.zy.model.TbPermission;
import com.zy.model.TbRole;
import com.zy.model.TbUser;
import com.zy.service.TbUserServiceI;
import com.zy.util.MD5;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Administrator on 2018/7/2.
 *
 * 认证及授权的realm
 */
public class TbUserRealm extends AuthorizingRealm {

    @Autowired
    private TbUserServiceI tbUserService;

    /*
    *
    * 认证
    * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        /*获取输入的用户名及密码*/
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        /*调用service层方法返回用户信息*/
        TbUser tbUser = tbUserService.getTbUserByUserName(username);
        /*如果用户信息为Null,则抛出用户不存在异常*/
        if(tbUser == null){
            throw new UnknownAccountException("用户名为空-----------------");
        }
        /*如果用户状态为1,则抛出账户锁定异常*/
        if(tbUser.getStatus().equals(ConstantValue.USER_STATUS_LOCKED)){
            throw new LockedAccountException("账号被锁定-----------------------");
        }
        /*比较密码是否一致,如果不一致,则抛出密码错误异常*/
        final String md5Password = MD5.getMD5(password, tbUser.getSalt());
        if(!md5Password.equals(tbUser.getPassword())){
            throw new IncorrectCredentialsException("密码错误---------------------");
        }
        /*如果一切顺利,则返回该信息*/
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                tbUser,
                md5Password,
                ByteSource.Util.bytes(tbUser.getSalt()),
                this.getName());
        return info;
    }

    /*
    *
    * 授权
    *
    * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //从principals获取主身份信息
        //将getPrimaryPrincipal方法返回值转为真实身份类型
        //在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型
        TbUser tbUser = (TbUser) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if(tbUser != null){
            //根据身份信息获取角色信息并且设置到PrincipalCollection中
            List<TbRole> roleList = tbUserService.getTbRoleByUserId(tbUser.getId());
            Set<String> roles = new HashSet<String>();
            if(roleList != null){
                for(TbRole tbRole : roleList){
                    if(tbRole.getRoleName() != null && !tbRole.getRoleName().equals("")){
                        roles.add(tbRole.getRoleName());
                    }
                }
                info.setRoles(roles);
            }
            //根据身份信息获取权限信息并且设置到PrincipalCollection中
            List<TbPermission> permissionList = tbUserService.getTbPermissionByUserId(tbUser.getId());
            if(permissionList != null){
                Set<String> permissions = new HashSet<String>();
                for(TbPermission tbPermission : permissionList){
                    if(tbPermission.getPerCode() != null && !tbPermission.getPerCode().trim().equals("")){
                        permissions.add(tbPermission.getPerCode());
                    }
                }
                info.setStringPermissions(permissions);
            }
            else{
                throw new UnauthorizedException();
            }
        }
        return info;
    }

}

2.11controller层(以LoginController 为例)

package com.zy.controller;

import com.zy.common.ConstantValue;
import com.zy.model.TbPermission;
import com.zy.model.TbUser;
import com.zy.service.TbUserServiceI;
import org.apache.shiro.SecurityUtils;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018/7/3.
 * <p>
 * 登录注册相关的controller
 */
@Controller
@RequestMapping("login")
public class LoginController {

    @Autowired
    private TbUserServiceI tbUserService;

    // 登录界面
    @RequestMapping("login")
    public String login() {
        return "login/login";
    }

    // 登录验证
    @RequestMapping("loginCheck")
    public String loginCheck(TbUser tbUser, String rememberMe,Map map) {
        UsernamePasswordToken token = new UsernamePasswordToken(tbUser.getUsername(), tbUser.getPassword());
        Subject subject = SecurityUtils.getSubject();
        if (rememberMe == null) {
            token.setRememberMe(false);
        } else {
            token.setRememberMe(true);
        }
        try {
            subject.login(token);
            return "forward:toIndex";
        } catch (Exception e) {
            map.put("msg","用户名或密码错误");
            return "login/login";
        }
    }

    // 如果登录成功,则跳转到此处,由此处获取信息,并发送至前台页面
    @RequestMapping("toIndex")
    public String toIndex(Map map){
        /*获取TbUserRealm中的Subject*/
        final Subject subject = SecurityUtils.getSubject();
        TbUser tbUser = (TbUser) subject.getPrincipal();
        if(tbUser == null){
            return "redirect:/login/login";
        }
        /*将用户信息放到map中*/
        map.put("tbUser", tbUser);
        /*查询菜单信息,并将菜单信息放置到map中*/
        Map<TbPermission, List<TbPermission>> menu = tbUserService.getMenuByUserId(tbUser.getId());
        map.put("menu",menu);
        return "index";
    }

    /*注册*/
    /*注册前用户名查重*/
    @RequestMapping("isUserExist")
    @ResponseBody
    public String isUserExist(String username) {
        TbUser tbUser = tbUserService.getTbUserByUserName(username);
        if (tbUser == null) {
            return ConstantValue.USER_IS_NOT_EXIST;
        }
        return ConstantValue.USER_IS_EXIST;
    }

    @RequestMapping("register")
    public String register(String username, String password) {
        /*用户注册*/
        TbUser tbUser = new TbUser();
        tbUser.setUsername(username);
        tbUser.setPassword(password);
        tbUserService.addTbUser(tbUser);
        /*用户注册后,登录到首页展示页面*/
        return "forward:loginCheck";
    }

    /*用户退出登录*/
    @RequestMapping("logout")
    public String logout(HttpSession session){
        /*清除缓存*/
        session.invalidate();
        return "redirect:/login/login";
    }

}

2.12model层(以TBUser为例)

 

package com.zy.model;

import java.io.Serializable;

/**
 *
 * 定义用户登录表中的实体类
 * Created by Administrator on 2018/7/3.
 */
public class TbUser implements Serializable {

    private Integer id;
    private String username;
    private String password;
    private String salt;
    private String status;

    @Override
    public String toString() {
        return "TbUser{" +
                "id=" + id +
                ", username=‘" + username +  +
                ", password=‘" + password +  +
                ", salt=‘" + salt +  +
                ", status=‘" + status +  +
                };
    }

    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 getSalt() {
        return salt;
    }

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

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public TbUser() {

    }

    public TbUser(Integer id, String username, String password, String salt, String status) {

        this.id = id;
        this.username = username;
        this.password = password;
        this.salt = salt;
        this.status = status;
    }
}

2.13webapp下的web.xml配置

技术分享图片

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>ssmshiro</display-name>


  <!--配置spring-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>
  <!--配置乱码过滤器-->
  <filter>
    <filter-name>CharacterFilter</filter-name>
    <filter-class>com.zy.util.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <!--配置shiro拦截-->
  <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>CharacterFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!--配置spring-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--配置springmvc-->
  <servlet>
    <servlet-name>Dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc/springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!--配置欢迎界面-->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <!--配置404和500-->
  <error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/error/404.jsp</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/error/500.jsp</location>
  </error-page>
</web-app>

 


以上是关于SSM项目与Shiro项目的整合(单体式项目)的主要内容,如果未能解决你的问题,请参考以下文章

008-shiro与spring web项目整合认证授权session管理

shiro学习笔记_0700_整合ssm

重磅回归-SSM整合进阶项目实战之个人博客系统

单体物联平台系统(Springboot整合shiro实现多realm多用户表多权限表登陆)

007-shiro与spring web项目整合基础搭建

ssm整合shiro时web。xml中配置filter,tomcat报错