記錄心得-shiro框架demo示例


從懵懂到了解,再到熟悉,是一個進步的過程!

 

先擼代碼,跑起來看效果,再做詳細的介紹,開始干活!

1,先列出工程目錄結構,自己需要創建對應層級的程序和相關配置文件。

 

2,導入maven依賴的jar包。打開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>mvc_shiro</groupId>
  <artifactId>mvc_shiro</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>mvc_shiro Maven Webapp</name>

<!-- 這個地址可以改為自己項目的地址--> <url>http://maven.apache.org</url> <properties> <!-- spring版本號 --> <spring.version>4.0.2.RELEASE</spring.version> <!-- mybatis版本號 --> <mybatis.version>3.2.6</mybatis.version> <!-- log4j日志文件管理包版本 --> <slf4j.version>1.7.7</slf4j.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencies> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <!-- 表示開發的時候引入,發布的時候不會加載此包 --> <scope>test</scope> </dependency> <!-- spring核心包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <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.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- mybatis核心包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis/spring包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- 導入java ee jar 包 --> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <!-- 導入Mysql數據庫鏈接jar包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!-- 導入dbcp的jar包,用來在applicationContext.xml中配置數據庫 --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2.2</version> </dependency> <!-- JSTL標簽類 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 日志文件管理包 --> <!-- log start --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <!-- 格式化對象,方便輸出日志 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.41</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!-- log end --> <!-- 映入JSON --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <!-- 上傳組件包 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency> </dependencies> <build> <finalName>mvc_shiro</finalName> </build> </project>

 

3,配置web.xml文件。簡單的spring-mvc配置。

<?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"
         version="3.0">
  <display-name>Archetype Created Web Application</display-name>
  <!-- Spring和mybatis的配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mybatis.xml</param-value>
  </context-param>
  <!-- 編碼過濾器 -->
  <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>
  <!-- Spring監聽器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 防止Spring內存溢出監聽器 -->
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>
  <!-- Spring MVC servlet -->
  <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>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
  </servlet>

  <!-- 配置由Spring提供的過濾器,用於整合shiro框架 -->
  <!-- 在項目啟動的過程中,當前過濾器會從Spring工廠中提取同名對象 -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

            
  <!-- Spring MVC 普通頁面攔截 -->
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <!-- 此處可以可以配置成*.do,對應struts的后綴習慣 -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>/index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

 

4,配置數據庫配置文件jdbc.properties,需要配置自己的本地的數據庫信息。

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/自己的數據庫名稱
username=自己的數據庫登錄賬戶
password=自己的數據庫登錄密碼
#定義初始連接數
initialSize=0
#定義最大連接數
maxActive=20
#定義最大空閑
maxIdle=20
#定義最小空閑
minIdle=1
#定義最長等待時間
maxWait=60000

 

5,配置日志log4j.properties。注意 自己指定日志輸出的位置。

#定義LOG輸出級別
log4j.rootLogger=DEBUG,File  
#定義日志輸出目的地為控制台
#log4j.appender.Console=org.apache.log4j.ConsoleAppender
#log4j.appender.Console.Target=System.out
#可以靈活地指定日志輸出格式,下面一行是指定具體的格式
#log4j.appender.Console.layout = org.apache.log4j.PatternLayout
#log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n

#文件大小到達指定尺寸的時候產生一個新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender  
#指定輸出目錄
log4j.appender.File.File = 需要自己配置輸出的日志位置及日志名稱。比如c:/desktop/shiro.log
#定義文件最大大小
log4j.appender.File.MaxFileSize = 10MB  
log4j.appender.File.Encoding = UTF-8
# 輸出所以日志,如果換成DEBUG表示輸出DEBUG以上級別日志
log4j.appender.File.Threshold = ALL  
log4j.appender.File.layout = org.apache.log4j.PatternLayout  
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n 

 

6,配置shiro-context.xml配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    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-3.2.xsd
                http://www.springframework.org/schema/context
                 http://www.springframework.org/schema/context/spring-context-3.2.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" /> <!--加載管理器-->
        <property name="loginUrl" value="/user/login" />    <!--沒有登錄的時候,跳轉到這個頁面-->
        <property name="unauthorizedUrl" value="/user/nopermission" /> <!--當沒有權限的時候,跳轉到這個url-->
         
        <property name="filterChainDefinitions">
            <value>
                /user/login = anon <!--可以不需要登錄-->
                /user/readName = authc, perms[/readName]  <!-- perms 表示需要該權限才能訪問的頁面 -->
                /user/readData = authc, perms[/readData]
                /user/* = authc <!-- authc 表示需要認證才能訪問的頁面 -->
            </value>
        </property>
    </bean>

    <!-- 自定義Realm -->
    <bean id="myShiroRealm" class="com.Shiro.MyShiroReaml">
        <!-- businessManager 用來實現用戶名密碼的查詢 -->
        <property name="shiroService" ref="accountService" />
    </bean>

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 注入realm -->
        <property name="realm" ref="myShiroRealm"/>
    </bean>

    <!--聲明一個Service 注入到自定義Realm-->
    <bean id="accountService" class="com.Service.Impl.ShiroServiceImpl"/>
    <!-- <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> 
        <property name="cacheManager" ref="cacheManager" /> </bean> -->
</beans>

 

 

7,配置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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <import resource="shiro-context.xml"/>
    <!-- 自動掃描該包,使SpringMVC認為包下用了@controller注解的類是控制器 -->
    <context:component-scan base-package="com.*" />
    <!--避免IE執行AJAX時,返回JSON出現下載文件 -->
    <bean id="mappingJacksonHttpMessageConverter"
          class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean>

    <!-- 啟動SpringMVC的注解功能,完成請求和注解POJO的映射 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON轉換器 -->
            </list>
        </property>
    </bean>
    <!-- 定義跳轉的文件的前后綴 ,視圖模式配置-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 這里的配置我的理解是自動給后面action的方法return的字符串加上前綴和后綴,變成一個 可用的url地址 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 配置文件上傳,如果沒有使用文件上傳可以不用配置,當然如果不配,那么配置文件中也不必引入上傳組件包 -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 默認編碼 -->
        <property name="defaultEncoding" value="utf-8" />
        <!-- 文件大小最大值 -->
        <property name="maxUploadSize" value="10485760000" />
        <!-- 內存中的最大值 -->
        <property name="maxInMemorySize" value="40960" />
    </bean>

</beans>

 

 

 8,配置spring-mybatis.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自動掃描 -->
    <context:component-scan base-package="com" />
    <import resource="shiro-context.xml"/>
    <!-- 引入配置文件 -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties" />
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化連接大小 -->
        <property name="initialSize" value="${initialSize}"/>
        <!-- 連接池最大數量 -->
        <property name="maxActive" value="${maxActive}"/>
        <!-- 連接池最大空閑 -->
        <property name="maxIdle" value="${maxIdle}"/>
        <!-- 連接池最小空閑 -->
        <property name="minIdle" value="${minIdle}"/>
        <!-- 獲取連接最大等待時間 -->
        <property name="maxWait" value="${maxWait}"/>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自動掃描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:mapping/*.xml"/>
    </bean>

    <!-- DAO接口所在包名,Spring會自動查找其下的類 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.Dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

 

 

9,在本地數據庫維護初始化數據。

CREATE DATABASE `shirotest;USE `shirotest`;

/*Table structure for table `permission` */

DROP TABLE IF EXISTS `permission`;

CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `url` varchar(30) NOT NULL,
  `roleid` int(11) DEFAULT NULL,
  `description` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `permission` */

insert  into `permission`(`id`,`url`,`roleid`,`description`) values (1,'/readName',1,'查看名單'),(2,'/readData',2,'查看數據');

/*Table structure for table `role` */

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role` varchar(20) NOT NULL,
  `description` varchar(120) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `role` */

insert  into `role`(`id`,`role`,`description`) values (1,'管理員','管理員'),(2,'普通用戶','普通用戶');

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account` varchar(20) NOT NULL,
  `password` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`account`,`password`) values (1,'123','123'),(2,'1234','1234');

/*Table structure for table `user_role` */

DROP TABLE IF EXISTS `user_role`;

CREATE TABLE `user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) NOT NULL,
  `roleid` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;

/*Data for the table `user_role` */

insert  into `user_role`(`id`,`userid`,`roleid`) values (1,1,1),(2,2,2);

 

 

10,實現自己的reaml類。

package com.Shiro;

import com.Controller.loginController;
import com.Pojo.Permission;
import com.Pojo.User;
import com.Service.ShiroService;
import org.apache.log4j.Logger;
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 java.util.List;

public class MyShiroReaml extends AuthorizingRealm {
    private Logger logger = Logger.getLogger(MyShiroReaml.class);

0
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) { logger.debug("doGetAuthorizationInfo----權限驗證"); /** * * 流程 * 1.根據用戶user->2.獲取角色id->3.根據角色id獲取權限permission */ //方法一:獲得user對象 User user=(User)pc.getPrimaryPrincipal(); logger.debug("user========="+user); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //獲取permission if(user!=null) { List<Permission> permissionsByUser = shiroService.getPermissionsByUser(user); if (permissionsByUser.size()!=0) { for (Permission p: permissionsByUser) { info.addStringPermission(p.getUrl()); } return info; } } return null; } // 認證方法 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { logger.debug("doGetAuthenticationInfo----登錄驗證"); //驗證賬號密碼 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; logger.debug("1:"+token.getUsername()); User user = shiroService.getUserByUserName(token.getUsername()); logger.debug("2"); if(user==null){ return null; } //最后的比對需要交給安全管理器 //三個參數進行初步的簡單認證信息對象的包裝 AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getSimpleName()); logger.debug("info===="+info); return info; } private ShiroService shiroService; public ShiroService getShiroService() { return shiroService; } public void setShiroService(ShiroService shiroService) { this.shiroService = shiroService; } }

 

11,完善pojo對象類。

Permission.java

package com.Pojo;

import org.springframework.stereotype.Component;

@Component
public class Permission {
    private int id;
    private String token;
    /**資源url**/
    private String url;
    /**權限說明**/
    private String description;
    /**所屬角色編號**/
    private int roleId;

    public int getId() {
        return id;
    }

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

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getUrl() {
        return url;
    }

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

    public String getDescription() {
        return description;
    }

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

    public int getRoleId() {
        return roleId;
    }

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

    @Override
    public String toString() {
        return "PermissionPojo{" +
                "id=" + id +
                ", token='" + token + '\'' +
                ", url='" + url + '\'' +
                ", description='" + description + '\'' +
                ", roleId=" + roleId +
                '}';
    }
}

 

Role.java

package com.Pojo;

public class Role {
    private int id;
    /**角色**/
    private String role;
    /**說明**/
    private String description;


    public int getId() {
        return id;
    }

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

    public String getRole() {
        return role;
    }

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

    public String getDescription() {
        return description;
    }

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

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", role='" + role + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}

 

User.java

package com.Pojo;

import org.springframework.stereotype.Component;

@Component
public class User {
    private int id;
    private String account;
    private String password;

    public User(int id, String account, String password) {
        this.id = id;
        this.account = account;
        this.password = password;
    }

    public User() {
        super();
    }

    public int getId() {
        return id;
    }

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

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString() {
        return "UserPojo{" +
                "id=" + id +
                ", account='" + account + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

 

12,開始寫驗證代碼,按照Controller-Service-Dao-Mapping

LoginController.java

package com.Controller;

import com.Pojo.User;
import com.Service.ShiroService;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class loginController {
    @Autowired
    private ShiroService shiroService;
    private Logger logger = Logger.getLogger(loginController.class);
    /**
     * 驗證登錄
     * @param username
     * @param password
     * @param session
     * @return url
     */
    @RequestMapping(value = "/login")
    public String Login(String username, String password, HttpSession session, Model model){
        if(username==null){
            model.addAttribute("message", "賬號不為空");
            return "login";
        }
        //主體,當前狀態為沒有認證的狀態“未認證”
        Subject subject = SecurityUtils.getSubject();
        // 登錄后存放進shiro token
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);
        User user;
        //登錄方法(認證是否通過)
        //使用subject調用securityManager,安全管理器調用Realm
        try {
            //利用異常操作
            //需要開始調用到Realm中
            logger.debug("========================================");
            logger.debug("1、進入認證方法");
            subject.login(token);
            user = (User)subject.getPrincipal();
            session.setAttribute("user",subject);
            model.addAttribute("message", "登錄完成");
            logger.debug("登錄完成");
        } catch (UnknownAccountException e) {
            model.addAttribute("message", "賬號密碼不正確");
            return "index";
        }
        return "test";
    }

    @RequestMapping("/check")
    public String check(HttpSession session){
        Subject subject=(Subject)session.getAttribute("user");
        User user=(User)subject.getPrincipal();
        logger.debug(user.toString());
        return "permission";
    }

    @RequestMapping("/readName")
    public String readName(HttpSession session){

        return "name";
    }

    @RequestMapping("/readData")
    public String readData(){

        return "data";
    }


    @RequestMapping("/nopermission")
    public String noPermission(){
        return "error";
    }
}

 

ShiroService.java

package com.Service;

import com.Pojo.Permission;
import com.Pojo.User;

import java.util.List;
 
public interface ShiroService {

    /**
     * 根據賬號獲取賬號密碼
     * @param username
     * @return UserPojo
     */
     User getUserByUserName(String username);

    /**
     * 根據賬號獲取該賬號的權限
     *
     * @param user
     * @return List
     */
    List<Permission> getPermissionsByUser(User user);
}

 

ShiroServiceImpl.java

package com.Service.Impl;

import com.Dao.ShiroDao;
import com.Pojo.Permission;
import com.Pojo.User;
import com.Service.ShiroService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service("shiroService")
public class ShiroServiceImpl implements ShiroService {

    @Autowired
    private ShiroDao shiroDao;

    public User getUserByUserName(String username) {
        //根據賬號獲取賬號密碼
        User userByUserName = shiroDao.getUserByUserName(username);
        return userByUserName;
    }

    public List<Permission> getPermissionsByUser(User user) {
        //獲取到用戶角色userRole
        List<Integer> roleId = shiroDao.getUserRoleByUserId(user.getId());
        List<Permission> perArrary = new ArrayList<Permission>();

        if (roleId!=null&&roleId.size()!=0) {
            //根據roleid獲取peimission
            for (Integer i : roleId) {
                perArrary.addAll(shiroDao.getPermissionsByRoleId(i));
            }
        }

        System.out.println(perArrary);
        return perArrary;
    }
}

 

ShiroDao.java

package com.Dao;

import com.Pojo.Permission;
import com.Pojo.User;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public interface ShiroDao {

    /**
     * 根據賬號獲取賬號密碼
     * @param username
     * @return UserPojo
     */
    User getUserByUserName(String username);

    /**
     * 根據角色id獲取該賬號的權限
     * @param roleId
     * @return List
     */
    List<Permission> getPermissionsByRoleId(int roleId);

    /**
     * 根據userId獲取角色id
     * @param id
     * @return LIST
     */
    List<Integer> getUserRoleByUserId(int id);
}

 

Shiro.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.Dao.ShiroDao">
    <select id="getUserByUserName" resultType="com.Pojo.User">
        select * FROM user
        WHERE account= #{0}
    </select>

    <select id="getUserRoleByUserId" resultType="int">
        SELECT roleid FROM user_role
        where userid = #{_parameter}
    </select>

    <select id="getPermissionsByRoleId" resultType="com.Pojo.Permission">
        SELECT a.id,a.url,a.roleid as roleId,a.description FROM permission a
        WHERE roleid = #{_parameter}
    </select>

</mapper>

 

13,簡單的頁面jsp,可參考,也可自己擼前端的代碼,本文只起示例作用。

WEB-INF/index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<html>
<body>
<h2>Hello World!</h2>

<script type="text/javascript">
    window.location.href="user/login";
</script>
</body>
</html>

 

 

WEB-INF/jsp/data.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<ul>
    <li>數據1</li>
    <li>數據2</li>
</ul>
</body>
</html>

 

 

WEB-INF/jsp/error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h2>你沒有查看的權利</h2>
</body>
</html>

 

 

WEB-INF/jsp/index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<html>
<body>
<h2>Hello World!</h2>

<form action="login" method="post" >
    賬號:<input type="text" name="username"/>
    密碼<input type="password" name="password"/>
    <button type="submit">提交</button>
</form>
</body>
</html>

 

 

WEB-INF/jsp/login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="login" method="post" style="margin: 0 auto">
    賬號:<input type="text" name="username" value="${message}"/>
    密碼<input type="password" name="password"/>
    <button type="submit">提交</button>
</form>
</body>
</html>

 

 

WEB-INF/jsp/name.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<ul>
    <li>小米</li>
    <li>小紅</li>
</ul>

</body>
</html>

 

 

WEB-INF/jsp/permission.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="readName">查看名單</a>
<a href="readData">查看數據</a>
</body>
</html>

 

 

WEB-INF/jsp/test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${message}

<a href="check">查看</a>
</body>
</html>

 

 

至此,框架搭建起了,測試代碼也擼好了。假設上面一切順利,沒有飄紅報錯,那么就可以用maven幫我們打個war包,直接扔tomcat上,跑起來玩了。如圖打包。瀏覽器訪問127.0.0.1:8080/mvc_shiro

 

實際操作中,可能不會很順利,有遇到一些問題,但是都解決了,現在沒法復現,所以暫不列出,如果有遇到問題的,歡迎留言討論。后續會把自己的一些理解添加到博文中,今天累了,先溜了。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM