SSM+shiro核心配置文件

一、web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <!-- SpringMVC配置 开始 -->
  <!-- Spring MVC 核心控制器 DispatcherServlet 配置 -->
  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <!-- 拦截所有/的请求,交给DispatcherServlet处理-->
    <url-pattern>/</url-pattern>
  </servlet-mapping> 
  <!-- SpringMVC配置 结束 -->

  <!-- Spring配置 开始 -->
  <!-- 配置Spring配置文件路径、将Shiro的配置文件交给Spring监听器初始化 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:/spring/spring-application.xml,classpath*:/spring/spring-shiro.xml</param-value>
  </context-param>
  <!-- 配置Spring上下文监听器 --> 
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 配置Spring字符编码过滤器 -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <!-- 只要发起的操作是一次HTTP请求,比如请求某个URL发起了一个GET请求、表单提交方式为POST时提交表单则发起了一个POST请求、
        表单提交方式为GET时提交表单则发起了一次GET请求、一次重定向则前后相当于发起了两次请求,这些情况下有几次请求就会走几次指定过滤器 -->
    <dispatcher>REQUEST</dispatcher>
    <!-- 只有当当前页面是通过请求转发转发过来的场景,才会走指定的过滤器 -->
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>
  <!-- Spring配置 结束 -->

  <!-- shiro配置 开始 -->
  <!-- 由于项目通过Spring管理,因此所有的配置原则上都是交给Spring。
       DelegatingFilterProxy的功能是通知Spring将所有的Filter交给ShiroFilter管理。 -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>
  <!-- shiro配置 结束 -->
</web-app>

二、spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 自动扫描且只扫描@Controller -->
    <context:component-scan base-package="com" use-default-filters="false">
        <!-- 平台的controller,可以写多个 -->
        <!-- type="aspectj"     expression为AspectJ語法   例如:org.example..*Service+
             type="regex"       表达式为正则表达式语法  例如:org\.example\.Default.*  (.表示所有字符,而\.才表示真正的.字符)
        -->
        <context:include-filter type="aspectj" expression="com.jy.controller..*Controller"/>
    </context:component-scan>

    <!-- 对静态资源文件的访问  
            补充说明:多个HandlerMapping的执行顺序问题:
            DefaultAnnotationHandlerMapping的order属性值是:0
            <mvc:resources/ >自动注册的 SimpleUrlHandlerMapping的order属性值是: 2147483646
            <mvc:default-servlet-handler/>自动注册的SimpleUrlHandlerMapping的order属性值是:2147483647
            spring会先执行order值比较小的。
            当访问一个a.jpg图片文件时,先通过DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,我们没有叫a.jpg的Action。
            再按order值升序找,由于最后一个SimpleUrlHandlerMapping 是匹配"/**"的,所以一定会匹配上,再响应图片。    
    -->   
    <!-- 对静态资源文件的访问  方式1:SpringMVC3.0之后推荐使用 -->  
    <mvc:default-servlet-handler/>
    <!-- 对静态资源文件的访问  方式2:SpringMVC3.0之前推荐使用 --> 
    <!--<mvc:resources mapping="/static/**" location="/static/" /> -->
    <!--<mvc:resources mapping="/plugins/**" location="/plugins/" />
    <mvc:resources mapping="/uploadFiles/**" location="/uploadFiles/" />  -->

    <!-- freemarker的配置 -->
    <!-- 配置freeMarker模板加载地址 -->
    <bean id="freemarkerConfig"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/views/" />
        <property name="defaultEncoding" value="utf-8" />
        <property name="freemarkerSettings">
            <props>
                <prop key="template_update_delay">1</prop>
                <prop key="locale">zh_CN</prop>
                <prop key="datetime_format">yyyy-MM-dd</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="number_format">#.##</prop>
                <prop key="auto_import">/manager/include/macro.ftl as ms</prop>                 
            </props>
        </property>
    </bean>

    <!-- FreeMarker视图解析 如返回student。。在这里配置后缀名ftl和视图解析器。。 -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">

        <property name="viewClass"
            value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
        <property name="suffix" value=".ftl" />
        <property name="contentType" value="text/html;charset=utf-8" />
        <property name="allowRequestOverride" value="true" /> 
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="exposeSpringMacroHelpers" value="true" />
        <!-- 给视图解析器配置优先级,你可以给之后jsp视图解析器的值配为2 -->
        <property name="order" value="1" />
    </bean>

    <!--  springmvc试图解析器    -->
    <bean id="JSPviewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
        <property name="order" value="2" />
    </bean>

    <mvc:annotation-driven>
        <!-- 
         <context:component-scan/>标签是告诉Spring 来扫描指定包下的类,并注册被@Component,@Controller,@Service,@Repository等注解标记的组件。
           而<mvc:annotation-driven/>是告知Spring,我们启用注解驱动。
           然后Spring会自动为我们注册几个Bean到工厂中,来处理我们的请求。
          最重要的就是RequestMappingHandlerMapping和RequestMappingHandlerAdapter。
          第一个是HandlerMapping的实现类,它会处理@RequestMapping 注解,并将其注册到请求映射表中。
          第二个是HandlerAdapter的实现类,它是处理请求的适配器,说白了,就是确定调用哪个类的哪个方法,并且构造方法参数,返回值。        
         -->
        <!-- 
        四种内置标签:
        message-converters  出参转换 ,配置了@ResponseBody注解的时候才会生效
        argument-resolvers  入参转换
        async-support       异步支持
        return-value-handlers 
         -->
        <mvc:message-converters register-defaults="true">
            <!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
            <bean
                class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>text/json;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 默认编码 -->
        <property name="defaultEncoding" value="utf-8" />
        <!-- 文件大小最大值 -->
        <property name="maxUploadSize" value="1048576000" />
        <!-- 内存中的最大值 -->
        <property name="maxInMemorySize" value="40960" />

    </bean>
    <!--
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.jy.interceptor.ActionInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors> 
    -->
</beans>

三、spring-application.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:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <description>Spring Configuration</description>

    <!-- 启用注解 -->
    <!-- 
        当我们需要使用注解模式时,直接在Spring配置文件中定义这些Bean显得比较笨拙,例如:
        使用@Autowired注解,必须事先在Spring容器中声明AutowiredAnnotationBeanPostProcessor的Bean
        使用@Required注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean  

      这样的声明未免太不优雅,而Spring为我们提供了一种极为方便注册这些BeanPostProcessor的方式,
      即使用<context:annotation- config/>
      隐式地向 Spring容器注册AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、
     CommonAnnotationBeanPostProcessor以及PersistenceAnnotationBeanPostProcessor这4个BeanPostProcessor。
     -->
    <context:annotation-config />

    <!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 -->
    <!-- 使用注解时一般都会配置扫描包路径选项,即<context:component-scan/>。
                  该配置项其实也包含了自动注入上述Processor的功能,因此当使用<context:component-scan/>后,即可将<context:annotation-config/>省去,但必须要配置全!
                  以防万一,还是同时声明的好。 -->
    <context:component-scan base-package="com.jy">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <import resource="spring-datasource.xml"/>  
</beans>

spring-datasource.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"
       default-lazy-init="true">

    <!-- 数据源配置, 使用应用服务器的数据库连接池 -->
    <!--<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/${jndi.name}" />-->
    <!-- 读取数据库配置文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath*:/spring/dbconfig.properties" /> 

    <!-- 配置数据源 -->
    <bean name="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.mysql.driver}"/>
        <property name="url" value="${jdbc.mysql.url}" />
        <property name="username" value="${jdbc.mysql.username}" />
        <property name="password" value="${jdbc.mysql.password}" />
        <!-- 如果数据源的defaultAutoCommit设置为True了,那么方法中如果自己捕获了异常,事务是不会回滚的,
               如果没有自己捕获异常则事务会回滚 -->
        <property name="defaultAutoCommit" value="true"></property>

        <!-- 初始化连接数量 -->
        <property name="initialSize" value="${druid.initialSize}" />
        <!-- 最大并发连接数 -->
        <property name="maxActive" value="${druid.maxActive}" />
        <!-- 最大空闲连接数 -->
      <!--   <property name="maxIdle" value="${druid.maxIdle}" /> -->
        <!-- 最小空闲连接数 -->
        <property name="minIdle" value="${druid.minIdle}" />
        <!-- 配置获取连接等待超时的时间 -->     
        <property name="maxWait" value="${druid.maxWait}" />
        <!-- 超过时间限制是否回收 -->
        <property name="removeAbandoned" value="${druid.removeAbandoned}" />
        <!-- 超过时间限制多长; -->
        <property name="removeAbandonedTimeout" value="${druid.removeAbandonedTimeout}" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />
        <!-- 用来检测连接是否有效的sql,要求是一个查询语句-->
        <property name="validationQuery" value="${druid.validationQuery}" />
        <!-- 申请连接的时候检测 -->
        <property name="testWhileIdle" value="${druid.testWhileIdle}" />
        <!-- 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
        <property name="testOnBorrow" value="${druid.testOnBorrow}" />
        <!-- 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能  -->
        <property name="testOnReturn" value="${druid.testOnReturn}" />
        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />     
        <property name="maxPoolPreparedStatementPerConnectionSize" value="${druid.maxPoolPreparedStatementPerConnectionSize}" />
        <!--属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:                 
                监控统计用的filter:stat
                日志用的filter:log4j
               防御SQL注入的filter:wall -->
        <property name="filters" value="${druid.filters}" />     

    </bean>

    <!-- MyBatis配置 -->
    <bean id="mysqlSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- dataSource属性是必须指定的,它表示用于连接数据库的数据源 -->
        <property name="dataSource" ref="mysqlDataSource" />

        <!-- 
            用于指定Mybatis的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的SqlSessionFactoryBuilder,
            但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。
         -->
        <property name="configLocation" value="classpath:/spring/mybatis-config.xml" /> 

        <!-- 自动扫描entity实体类目录, 省掉xml里的手工配置 
            它一般对应我们的实体类所在的包,这个时候会自动取对应包中,不包括包名的简单类名,作为,包括包名的别名。
            User 作为com.jy.entiry.user.User 的别名。
            多个package之间可以用逗号或者分号等来进行分隔。(value的值一定要是包的全名)
        -->
        <property name="typeAliasesPackage" value="com.jy.entity" />

        <!-- 显式指定Mapper文件位置
               它表示我们的Mapper文件存放的位置,当我们的Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值
          -->
        <property name="mapperLocations">
            <list>
                <value>classpath:/mybatis/**/**/*Mapper.xml</value>
            </list>
        </property>

        <!-- 数组类型,用来指定Mybatis的Interceptor -->
        <property name="plugins"><array><ref bean="pagePlugin" /></array></property>
    </bean>
    <!-- 分页配置-->
    <bean id="pagePlugin" class="com.jy.common.mybatis.PageInterceptor">
        <property name="properties">
            <props>
                <prop key="databaseType">mysql</prop>
            </props>
        </property>
    </bean>
    <!-- 分页配置end-->

    <!-- 这段配置会扫描basePackage下所有以@JYBatis标识的 接口,然后spring内部 创建各自接口的动态代理类。(动态代理:代理类在程序运行时被创建 。)
        理解1:Mapper接口生成代理注入到Spring
        理解2:Spring创建的代理类实现了 Mapper接口,并且注入到Spring
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="mysqlSqlSessionFactory"/>
        <property name="basePackage" value="com.jy.repository" />
        <!-- 优化速度-->
        <property name="annotationClass" value="com.jy.repository.base.JYBatis"/>
    </bean>

    <!-- 配置声明式事务管理器 -->
    <bean id="mysqlTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="mysqlDataSource" />
    </bean>
    <!--  拦截器方式配置事务 -->
    <tx:advice id="mysqlTransactionAdvice" transaction-manager="mysqlTransactionManager">
        <tx:attributes>
            <!-- 对save,insert,update,delete 开头的方法进行事务管理,只要有异常就回滚 -->
            <tx:method name="save*" propagation="REQUIRED"  rollback-for="java.lang.Throwable"/>
            <tx:method name="insert*" propagation="REQUIRED"  rollback-for="java.lang.Throwable"/>
            <tx:method name="delete*" propagation="REQUIRED"   rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED"  rollback-for="java.lang.Throwable"/>
            <!-- find,select,count开头的方法,开启只读,提高数据库访问性能 -->
            <tx:method name="find*" read-only="true" />
            <tx:method name="select*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <!-- 对其他方法 使用默认的事务管理 -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <aop:config proxy-target-class="true">
        <!-- 定义切入点 -->
        <aop:pointcut id="mysqlTransactionPointcut" expression="execution(* com.jy.service.*.*(..))" />
        <!-- 将事务通知 与 切入点组合 -->
        <aop:advisor pointcut-ref="mysqlTransactionPointcut" advice-ref="mysqlTransactionAdvice" order="1"/>
    </aop:config>

    <!-- 开启注解事务 
    基于JDK动态代理 ,可以将@Transactional放置在接口和具体类上。
    基于CGLIB类代理(proxy-target-class="true"),只能将@Transactional放置在具体类上。
    -->
    <tx:annotation-driven transaction-manager="mysqlTransactionManager" proxy-target-class="true"  order="0"/>

    <!-- 
    备注:当同时配置声明式事务 和 注解式事务时,可通过order值进行排序,order值越小,在AOP的chain 中越靠前,越先执行。这样就属于事务嵌套。
     -->
</beans>

JYBatis注解

package com.jy.repository.base;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Component;

/**
 * 标识MyBatis的DAO,方便{@link org.mybatis.spring.mapper.MapperScannerConfigurer}的扫描。
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Component
public @interface JYBatis {
    String value() default "";
}

四、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>
        <!-- 打印查询语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" /> 
        <!-- <setting name="logImpl" value="LOG4J" /> -->
    </settings>

    <!-- mapper已经在spring-datasource.xml中的sqlSessionFactory配置,这里不再需要配置 -->
<!--     <mappers> -->
<!--         <mapper resource="com/a/b/c/dao/BusinessInfoDaoMapper.xml" /> -->
<!--     </mappers> -->
</configuration>

五、spring-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
       default-lazy-init="true">

    <description>Shiro Configuration</description>

         <!-- 安全管理器 -->
         <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="ShiroRealm" />
            <!-- <property name="sessionManager" ref="sessionManager"/> -->
                    <!-- 使用下面配置的缓存管理器 -->
            <!-- <property name="cacheManager" ref="cacheManager" /> -->
        </bean>

        <!-- Realm实现:項目自定义的Realm -->
        <bean id="ShiroRealm" class="com.jy.interceptor.shiro.ShiroRealm" ></bean>

        <!-- Shiro Filter   Shiro的Web过滤器 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />   
            <!-- 如果你没有登录,访问有登录验证的请求,都会跳转到/loginIndex页面 -->  
            <property name="loginUrl" value="/loginIndex" />        
            <!-- 登录成功跳转的页面 -->
            <property name="successUrl" value="/backstage/index" /> 
            <!-- 没有权限跳转的页面 -->
            <property name="unauthorizedUrl" value="/loginIndex" />
                <!-- anon:匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤
                     authc:如果没有登录会跳到相应的登录页面登录 
                          表示访问该地址用户【必须身份验证通过】(Subject. isAuthenticated()==true)
                     user:用户拦截器,用户已经身份验证/记住我登录的都可 -->
            <property name="filterChainDefinitions">
            <value>
                /api/**              = anon
                /iclock/**              = anon
                /static/js/system/login/**  = anon
                /static/js/system/**        = authc
                /static/**                  = anon
                /favicon.ico                = anon
                /verifyCode/**              = anon
                /system_login               = anon
                /exterInt/**               = anon
                /weixin/**                  = anon
                /upload/**                  = anon
                /**                         = authc
                </value>
            </property>
        </bean>
       <!-- 缓存管理器 使用Ehcache实现-->  
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
        <property name="cacheManagerConfigFile" value="classpath:/spring/ehcache.xml"/>  
    </bean>  

      <!-- AOP式方法级权限检查 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true" />
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>

六、ShiroRealm

package com.jy.interceptor.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * 用户身份验证,授权 Realm 组件
 * 
 **/
public class ShiroRealm extends AuthorizingRealm {

//    @Resource
//    private UserService userService;
//
//    @Resource
//    private RoleService roleService;
//
//    @Resource
//    private PermissionService permissionService;

    /**
     * 权限检查(添加角色、权限)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String username = String.valueOf(principals.getPrimaryPrincipal());

//        final User user = userService.selectByUsername(username);
//        final List<Role> roleInfos = roleService.selectRolesByUserId(user.getId());
//        for (Role role : roleInfos) {
//            // 添加角色
//            System.err.println(role);
//            authorizationInfo.addRole(role.getRoleSign());
//
//            final List<Permission> permissions = permissionService.selectPermissionsByRoleId(role.getId());
//            for (Permission permission : permissions) {
//                // 添加权限
//                System.err.println(permission);
//                authorizationInfo.addStringPermission(permission.getPermissionSign());
//            }
//        }
        return authorizationInfo;
    }

    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = String.valueOf(token.getPrincipal());
        String password = new String((char[]) token.getCredentials());
        // 通过数据库进行验证
        // ...

        // 在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,从而应用能验证用户身份
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
        return authenticationInfo;
    }

}
好的,下面是一个简单的SSM+Shiro的登录认证示例: 首先,需要在pom.xml中添加相关依赖: ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.3</version> </dependency> ``` 其中,spring-webmvc和spring-jdbc是Spring的核心依赖,mybatis-spring-boot-starter是MyBatis的依赖,shiro-core和shiro-spring是Shiro的依赖。 然后,在Spring的配置文件中配置数据源和MyBatis: ```xml <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.example.demo.entity"/> <property name="mapperLocations" value="classpath:/mapper/*.xml"/> </bean> <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.demo.mapper"/> </bean> ``` 接下来,配置Shiro: ```xml <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> </bean> <bean id="myRealm" class="com.example.demo.shiro.MyRealm"/> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login"/> <!-- 登录页面 --> <property name="successUrl" value="/index"/> <!-- 登录成功页面 --> <property name="filterChainDefinitions"> <value> /login = anon /logout = logout /** = authc </value> </property> </bean> ``` 其中,DefaultWebSecurityManager是Shiro的安全管理器,MyRealm是自定义的Realm类,ShiroFilterFactoryBean是Shiro的过滤器。 最后,实现登录认证: ```java @Controller public class LoginController { @Autowired private UserService userService; @RequestMapping("/login") public String login() { return "login"; } @RequestMapping("/index") public String index() { return "index"; } @RequestMapping("/loginCheck") @ResponseBody public String loginCheck(String username, String password) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); return "success"; } catch (AuthenticationException e) { return "fail"; } } } ``` 其中,UserService是自定义的用户服务类,login方法返回登录页面,index方法返回登录成功页面,loginCheck方法处理登录请求,判断用户名和密码是否正确。 以上就是一个简单的SSM+Shiro的登录认证示例,希望可以帮到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值