把Shiro整合到SSM框架中

来源:互联网 发布:b2b软件 编辑:程序博客网 时间:2024/05/01 16:27


转载自:http://blog.csdn.net/eson_15/article/details/51787391


其实Shiro整合到Spring中并没有想象的那么困难,整到Spring中后,我们自定义的realm啊、securityManager啊等等都会交给spring去管理了,包括我们需要指定哪些url需要做什么样的验证,都是交给spring,也就是说,完全可以摆脱原来的那个.ini配置文件了,会觉得非常清爽,非常有逻辑。好了,下面开始整,Shiro部分参考了它的官方文档:http://shiro.apache.org/spring.html。

1. 整个工程目录结构

首先看一下整个工程的目录结构,先在宏观上对整体有个把握。 
工程目录

2. 配置文件

首先来完成一些配置文件,先从pom.xml开始,我已经用注释将它们归归类了,很清晰。

2.1 pom.xml

<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/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>demo.shiro</groupId>  <artifactId>ShiroSpring</artifactId>  <packaging>war</packaging>  <version>0.0.1-SNAPSHOT</version>  <name>ShiroSpring Maven Webapp</name>  <url>http://maven.apache.org</url>  <dependencies>    <!-- shiro核心包 -->    <dependency>        <groupId>org.apache.shiro</groupId>        <artifactId>shiro-core</artifactId>        <version>1.2.5</version>    </dependency>    <!-- 添加shiro web支持 -->    <dependency>        <groupId>org.apache.shiro</groupId>        <artifactId>shiro-web</artifactId>        <version>1.2.5</version>    </dependency>    <!-- 添加shiro spring支持 -->    <dependency>        <groupId>org.apache.shiro</groupId>        <artifactId>shiro-spring</artifactId>        <version>1.2.5</version>    </dependency>    <!-- 添加sevlet支持 -->    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>javax.servlet-api</artifactId>        <version>3.1.0</version>    </dependency>    <!-- 添加jsp支持 -->    <dependency>        <groupId>javax.servlet.jsp</groupId>        <artifactId>javax.servlet.jsp-api</artifactId>        <version>2.3.1</version>    </dependency>    <!-- 添加jstl支持 -->    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>jstl</artifactId>        <version>1.2</version>    </dependency>    <!-- 添加log4j日志 -->    <dependency>        <groupId>log4j</groupId>        <artifactId>log4j</artifactId>        <version>1.2.17</version>    </dependency>    <dependency>        <groupId>commons-logging</groupId>        <artifactId>commons-logging</artifactId>        <version>1.2</version>    </dependency>    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>slf4j-api</artifactId>        <version>1.7.21</version>    </dependency>    <!-- 添加spring支持 -->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-core</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-beans</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context-support</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-web</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>       <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-tx</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-jdbc</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>    <groupId>org.springframework</groupId>        <artifactId>spring-aop</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-aspects</artifactId>        <version>4.3.0.RELEASE</version>    </dependency>    <!-- 添加mybatis支持 -->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.4.0</version>    </dependency>    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis-spring</artifactId>        <version>1.3.0</version>    </dependency>    <!-- mysql -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.38</version>    </dependency>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.12</version>      <scope>test</scope>    </dependency>  </dependencies>  <build>    <finalName>ShiroSpring</finalName>  </build></project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147

2.2 log4j.properties

这个文件,我都是直接从官方拷贝过来的,也贴一下:

log4j.rootLogger=DEBUG, Console  #Console  log4j.appender.Console=org.apache.log4j.ConsoleAppender  log4j.appender.Console.layout=org.apache.log4j.PatternLayout  log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  log4j.logger.java.sql.ResultSet=INFO  log4j.logger.org.apache=INFO  log4j.logger.java.sql.Connection=DEBUG  log4j.logger.java.sql.Statement=DEBUG  log4j.logger.java.sql.PreparedStatement=DEBUG  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.3 web.xml

接下来在web.xml中添加Spring监听器、Shiro过滤器和SpringMVC支持:

<?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_3_0.xsd" id="WebApp_ID" version="3.0">  <display-name>ShiroSpring</display-name>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list>  <!-- spring监听器 -->  <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>  <context-param>    <param-name>contextConfigLocation</param-name>    <param-value>classpath:applicationContext.xml</param-value>  </context-param>  <!-- 添加springmvc支持 -->  <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-mvc.xml</param-value>    </init-param>  </servlet>  <servlet-mapping>    <servlet-name>springMVC</servlet-name>    <url-pattern>*.do</url-pattern>  </servlet-mapping>  <!-- 添加shiro过滤器 -->  <filter>    <filter-name>shiroFilter</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    <init-param>        <!-- 该值缺省为false,表示声明周期由SpringApplicationContext管理,设置为true表示ServletContainer管理 -->        <param-name>targetFilterLifecycle</param-name>        <param-value>true</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>shiroFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>  <!-- 编码过滤器 -->  <filter>    <filter-name>encodingFilter</filter-name>    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    <async-supported>true</async-supported>    <init-param>        <param-name>encoding</param-name>        <param-value>UTF-8</param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>encodingFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping></web-app>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

2.4 applicationContext.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:p="http://www.springframework.org/schema/p"      xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"      xmlns:jee="http://www.springframework.org/schema/jee"      xmlns:tx="http://www.springframework.org/schema/tx"      xsi:schemaLocation="            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">        <!-- 自动扫描 -->    <context:component-scan base-package="demo.service" />    <!-- 配置数据源 -->    <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/db_shiro"/>        <property name="username" value="root"/>        <property name="password" value="root"/>    </bean>    <!-- 配置mybatis的sqlSessionFactory -->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <property name="dataSource" ref="dataSource" />        <!-- 自动扫描mappers.xml文件 -->        <property name="mapperLocations" value="classpath:demo/mappers/*.xml"></property>        <!-- mybatis配置文件 -->        <property name="configLocation" value="classpath:mybatis-config.xml"></property>    </bean>    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="basePackage" value="demo.dao" />        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>    </bean>    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->    <bean id="transactionManager"        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource" />    </bean>    <!-- 自定义Realm -->    <bean id="myRealm" class="demo.realm.MyRealm"/>      <!-- 安全管理器 -->    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <property name="realm" ref="myRealm"/>      </bean>      <!-- Shiro过滤器 -->    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">          <!-- Shiro的核心安全接口,这个属性是必须的 -->          <property name="securityManager" ref="securityManager"/>        <!-- 身份认证失败,则跳转到登录页面的配置 -->          <property name="loginUrl" value="/login.jsp"/>        <!-- 权限认证失败,则跳转到指定页面 -->          <property name="unauthorizedUrl" value="/unauthorized.jsp"/>          <!-- Shiro连接约束配置,即过滤链的定义 -->          <property name="filterChainDefinitions">              <value>                  /login=anon                /user/admin*=authc                /user/student*/**=roles[teacher]                /user/teacher*/**=perms["user:create"]            </value>          </property>    </bean>      <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->      <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>      <!-- 开启Shiro注解 -->    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>          <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">        <property name="securityManager" ref="securityManager"/>      </bean>      <!-- 配置事务通知属性 -->      <tx:advice id="txAdvice" transaction-manager="transactionManager">          <!-- 定义事务传播属性 -->          <tx:attributes>              <tx:method name="insert*" propagation="REQUIRED" />              <tx:method name="update*" propagation="REQUIRED" />              <tx:method name="edit*" propagation="REQUIRED" />              <tx:method name="save*" propagation="REQUIRED" />              <tx:method name="add*" propagation="REQUIRED" />              <tx:method name="new*" propagation="REQUIRED" />              <tx:method name="set*" propagation="REQUIRED" />              <tx:method name="remove*" propagation="REQUIRED" />              <tx:method name="delete*" propagation="REQUIRED" />              <tx:method name="change*" propagation="REQUIRED" />              <tx:method name="check*" propagation="REQUIRED" />              <tx:method name="get*" propagation="REQUIRED" read-only="true" />              <tx:method name="find*" propagation="REQUIRED" read-only="true" />              <tx:method name="load*" propagation="REQUIRED" read-only="true" />              <tx:method name="*" propagation="REQUIRED" read-only="true" />          </tx:attributes>      </tx:advice>      <!-- 配置事务切面 -->      <aop:config>          <aop:pointcut id="serviceOperation"              expression="execution(* demo.service.*.*(..))" />          <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />      </aop:config>         </beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

  spring的配置文件中,我主要来说明一下shiro这一部分,因为其他部分都一样,扫描bean,配置数据源相关的,配置事务等等。我把上面shiro部分截图下来了: 
shiro 
  从这部分的配置可以看出,其实就是和上一节中在.ini文件中配置的一样的,只不过现在换成让spring去管理了,也很好理解,当然这里自定义的MyRealm还没写,因为MyRealm中需要有关于数据库的操作,所以下面先把mybatis部分整合好(其实加上MyRealm,shiro部分已经整合完了~)。

3. 整合MyBatis

3.1 全局配置文件

  首先配置一下mybatis的全局配置文件mybatis-config.xml,因为数据源啥的都交给spring管理了,所以全局配置文件就比较清爽了,当然还有一些设置上的东西,就不配置了,这个要看具体实际中使用的时候在配置。

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!-- 别名 -->    <typeAliases>        <package name="demo.entity"/>    </typeAliases></configura
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.2 配置mapper映射文件

配置一下UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="demo.dao.UserDao"><!--     <resultMap type="User" id="UserResult">        <result property="id" column="id"/>        <result property="username" column="username"/>        <result property="password" column="password"/>    </resultMap> -->    <select id="getByUsername" parameterType="String" resultType="User">        select * from t_user where username=#{username}    </select>    <select id="getRoles" parameterType="String" resultType="String">        select r.rolename from t_user u,t_role r where u.role_id=r.id and u.username=#{username}    </select>    <select id="getPermissions" parameterType="String" resultType="String">        select p.permissionname from t_user u,t_role r,t_permission p where u.role_id=r.id and p.role_id=r.id and u.username=#{username}    </select></mapper> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

  由配置可知,我们指定的是demo.dao.UserDao这个类,扫描mapper类是交给spring管理的,所以mapper接口可以不用和mapper映射文件同名且放到同一目录下,如果是交给mybatis管理我测试过是需要这么做的,在我之前mybatis的博文中也有提到这些。接下来就是写dao接口了(其实就是mapper映射文件对应的mapper接口)。

3.3 mapper接口

public interface UserDao {    public User getByUsername(String username);    public Set<String> getRoles(String username);    public Set<String> getPermissions(String username);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

  只需要写接口即可,不需要写实现,spring的配置文件中会去扫描mapper,会自动创建一个代理对象来执行相应的方法,要注意的是这个接口中的方法名要和上面mapper映射文件中的id号一样的,否则是无法映射到具体的statement上面的,会报错的。

3.4 po类

这里就写一个简单的User类,数据库中的存储信息可以参考上一篇博文,跟那边一样的。

public class User {    private Integer id;    private String username;    private String password;    //省略get set方法}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.5 完成service

顺带着把service层也完善了,这里我就写实现类了,接口就不写了。

@Service("userService")public class UserServiceImpl implements UserService{    @Resource    private UserDao userDao;    public User getByUsername(String username) {        return userDao.getByUsername(username);    }    public Set<String> getRoles(String username) {        return userDao.getRoles(username);    }    public Set<String> getPermissions(String username) {        return userDao.getPermissions(username);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在service的实现类中,注入刚刚写好的dao接口即可调用其中的方法了,使用的是spring自动创建的代理对象去执行的。

4 整合SpringMVC

4.1 配置文件

  上面的工作做完了后,其实需要写一个测试程序来测试一下能否正确访问数据库,因为整合必须步步为营。由于这个比较简单,我就不写测试程序了。因为前面web.xml配置中已经加入springmvc的支持了,所以这里直接写一下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:p="http://www.springframework.org/schema/p"      xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"      xmlns:jee="http://www.springframework.org/schema/jee"      xmlns:tx="http://www.springframework.org/schema/tx"      xsi:schemaLocation="            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">        <!-- 使用注解的包,包括子集 -->    <context:component-scan base-package="demo.controller" />    <!-- 视图解析器 -->    <bean id="viewResolver"        class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/" />        <property name="suffix" value=".jsp"></property>    </bean></beans>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

  我这里只配置了扫描包,没有配映射器和适配器,也没有写那个<mvc:annotation-driven></mvc:annotation-driven>注解驱动,也是可以执行的,我在网上没查到原因,也没去看源码,我的猜测是springmvc中可能有默认的映射器和适配器。如果有看过源码的朋友,请不吝赐教。

4.2 完成controller

配置好了后,就完成controller了,一个controller即可,因为一个controller中可以写很多方法。

@Controller@RequestMapping("/user")public class UserController {    //用户登录    @RequestMapping("/login")    public String login(User user, HttpServletRequest request) {        Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());        try{            subject.login(token);//会跳到我们自定义的realm中            request.getSession().setAttribute("user", user);            return "success";        }catch(Exception e){            e.printStackTrace();            request.getSession().setAttribute("user", user);            request.setAttribute("error", "用户名或密码错误!");            return "login";        }    }    @RequestMapping("/logout")    public String logout(HttpServletRequest request) {        request.getSession().invalidate();        return "index";    }       @RequestMapping("/admin")    public String admin(HttpServletRequest request) {        return "success";    }    @RequestMapping("/student")    public String student(HttpServletRequest request) {        return "success";    }       @RequestMapping("/teacher")    public String teacher(HttpServletRequest request) {        return "success";    }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

4.2 完成自定义realm

  终于可以写自己的realm了,上面用户登录会执行一个subject.login(token);这里会跳转到我们自定义的realm中,接下来就来定义一下我们自己的realm,由于这里是和mybatis整合了,所以不需要原来的那个DbUtil去连接数据库了,直接使用mybatis中的mapper接口,也就是上面我们写的dao。

public class MyRealm extends AuthorizingRealm {    @Resource    private UserService userService;    // 为当前登陆成功的用户授予权限和角色,已经登陆成功了    @Override    protected AuthorizationInfo doGetAuthorizationInfo(            PrincipalCollection principals) {        String username = (String) principals.getPrimaryPrincipal(); //获取用户名        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();        authorizationInfo.setRoles(userService.getRoles(username));        authorizationInfo.setStringPermissions(userService.getPermissions(username));        return authorizationInfo;    }    // 验证当前登录的用户,获取认证信息    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken token) throws AuthenticationException {        String username = (String) token.getPrincipal(); // 获取用户名        User user = userService.getByUsername(username);        if(user != null) {            AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), "myRealm");            return authcInfo;        } else {            return null;        }           }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

  这个自定义realm的原理和上一节是一样的,只不过这里使用注入的是service,然后service中使用的是dao接口中的方法去操作数据库。

5. 几个jsp页面

接下来就剩几个jsp页面了,我简单弄一下:

<!-- 这是login.jsp中的 --><body>    <form action="${pageContext.request.contextPath }/user/login.do" method="post">        username:<input type="text" name="username"/><br>        password:<input type="password" name="password"/><br>        <input type="submit" value="登陆">${error }    </form></body><!-- 这是success.jsp中的 --><body>     欢迎你${user.username }     <a href="${pageContext.request.contextPath }/user/logout.do">退出</a></body><!-- 这是unauthorized.jsp中的 --><body>     认证未通过,或者权限不足     <a href="${pageContext.request.contextPath }/user/logout.do">退出</a></body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

6. 测试

  根据spring的配置文件中对shiro的url拦截配置,我们首先请求:http://localhost:8080/ShiroSpring/user/admin.do来测试身份认证,然后会跳转到登录页面让我们登陆,登陆成功后,再次请求这个url就会进入success.jsp页面了。 
  再测试角色和权限认证,可以先后输入http://localhost:8080/ShiroSpring/user/student.do来测试角色认证,输入http://localhost:8080/ShiroSpring/user/teacher.do来测试权限认证。通过登陆不同的用户去测试即可。 


原创粉丝点击