前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《SSM篇》《整合SSM+Mybitas-plus+shiro+quartz容灾项目登录篇》

《SSM篇》《整合SSM+Mybitas-plus+shiro+quartz容灾项目登录篇》

作者头像
发布2020-10-29 11:42:25
8440
发布2020-10-29 11:42:25
举报
文章被收录于专栏:后端JavaEE

一、环境搭建

1.配置pom

代码语言:javascript
复制
<?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>org.example</groupId>
    <artifactId>1022_3_ssm1</artifactId>
    <version>1.0-SNAPSHOT</version>


    <packaging>war</packaging>
    <properties>
        <spring.version>4.3.5.RELEASE</spring.version>
        <mybatis.version>3.2.7</mybatis.version>
        <quartz.version>2.2.3</quartz.version>
        <shiro.version>1.4.0</shiro.version>
        <mybatis-plus.version>3.0.6</mybatis-plus.version>
        <swagger.version>2.7.0</swagger.version>
        <mysql.version>5.1.47</mysql.version>
    </properties>
    <dependencies>
        <!--1.springmvc依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--2.spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</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-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>
        <!--3.mybatis-->
        <!--<dependency>-->
        <!--<groupId>org.mybatis</groupId>-->
        <!--<artifactId>mybatis</artifactId>-->
        <!--<version>${mybatis.version}</version>-->
        <!--</dependency>-->

        <!--3. mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <!--4.驱动+dataSource-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--5.spring+mybatis整合包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--6.jackson-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <!--7.lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>

        <!--8. swagger2 依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <!--9.log4j-->
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>${shiro.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.shiro</groupId>
                    <artifactId>shiro-quartz</artifactId>
                </exclusion>
            </exclusions>
            <type>pom</type>
        </dependency>
        <!--
        quartz
        -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>${quartz.version}</version>
        </dependency>

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


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.45</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <!--配置文件的路径
                     项目路径
                    -->
                    <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.applicationContext.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- dataSource -->
    <!-- 读取properties文件 -->
    <context:property-placeholder location="classpath:dbinfo.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value=""></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
<!--        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>-->
    </bean>

    <!-- dao
        	扫描mapper层 创建代理对象
         -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper"></property>
    </bean>

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

</beans>

3.applicationContext-shiro.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--自定义cookie
    rememberMe配置
    -->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!--生命时间-->
        <property name="maxAge" value="180000"></property>
        <!--自定义cookie的name-->
        <property name="name" value="rememberMe"></property>
    </bean>
    <bean id="cookieRememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <!--引用自定义cookie-->
        <property name="cookie" ref="rememberMeCookie"></property>
    </bean>
    <!--===========rememberMe配置结束============-->
    <!--===========session配置============-->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <property name="name" value="sessionId"></property>
        <property name="maxAge" value="18000"></property>
    </bean>
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionIdCookie" ref="sessionIdCookie"></property>
        <!-- in milliseconds-->
        <property name="globalSessionTimeout" value="180000"></property>
        <!--清空过期会话 -->
        <property name="sessionValidationSchedulerEnabled" value="true"></property>
        <!--是否允许url重写  (地址后拼接jsessionid)-->
        <property name="sessionIdUrlRewritingEnabled" value="false"></property>
    </bean>

    <!--===========session配置结束============-->

    <!--===========ehcache配置开始============-->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
    </bean>
    <!--===========ehcache配置结束============-->



    <!--
    shiro+spring整合的核心配置
    -->
    <!--1.SecurityManager  -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 配置realm -->
        <property name="realms" ref="myUserRealm"></property>
        <!--配置记住我的cookie-->
        <property name="rememberMeManager" ref="cookieRememberMeManager"></property>
        <!--会话管理-->
        <property name="sessionManager" ref="sessionManager"></property>
        <!--缓存管理-->
        <property name="cacheManager" ref="cacheManager"></property>

    </bean>


    <!--2.配置自定义realm  走数据库
        默认:iniRealm shiro.ini
     -->
    <bean id="myUserRealm" class="realm.MyUserRealm"></bean>

    <!--3.shiroFilter
    Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
     web.xml uses the DelegatingFilterProxy to access this bean.

     web.xml  /*  shiro拦截后,会把请求交给该过滤器处理
     id="shiroFilter"  id需要和  web.xml 配置的filter的name属性一致
     filter-name:shiroFilter
    -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="loginUrl" value="/login.html"></property><!--登录界面-->
        <property name="unauthorizedUrl" value="/unauthorized.json"></property><!--没有权限的跳转页面-->
        <!--SecurityManager property must be set.-->
        <property name="securityManager" ref="securityManager"></property>
        <property name="filterChainDefinitions">
            <!--
                1)顺序  严格的过滤器往后配置
                2)anon  匿名访问  DefaultFilter
                3)authc  认证(登录)后才能访问
                4)user   勾选了记住我能访问
            -->
            <value>
                /json/** = anon
                /public/** = anon
                /sys/login = anon
                /js/** = anon
                /** = user
            </value>
        </property>

    </bean>
</beans>

4.dbinfo.properties

代码语言:javascript
复制
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///rzdbinfo?characterEncoding=utf-8
#不要直接命名username  不然冲突了
jdbc.username=root
#m默认spring内部已经存在username=你电脑的主机名的一个键值对
jdbc.password=root

5.ehcache.xml缓存

代码语言:javascript
复制
<!-- EhCache XML configuration file used for Shiro spring sample application -->
<ehcache>

    <!-- The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
    <diskStore path="java.io.tmpdir/shiro-spring-sample"/>


    <!--
    name:缓存名称
    maxElementsInMemory:内存中最大缓存对象数
    maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大
    eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
    overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
   diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。
    diskPersistent:是否缓存虚拟机重启期数据
    diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒
    timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
    timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />

    <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
expirations explicitly.  If we set it to false and then set corresponding timeToIdle and timeToLive properties,
ehcache would evict sessions without Shiro's knowledge, which would cause many problems
(e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)

diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
even after a JVM restart.  -->
    <cache name="shiro-activeSessionCache"
           maxElementsInMemory="10000"
           eternal="true"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="600"/>

    <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
           maxElementsInMemory="100"
           eternal="false"
           timeToLiveSeconds="600"
           overflowToDisk="false"/>

</ehcache>

6.mybatisgenerator.xml自动生成实体类

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="test" targetRuntime="MyBatis3">
        <!-- 一些工具 -->
        <!-- <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin>-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
        <!--<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>-->
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--数据库链接 参数 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/rzdbinfo" userId="root"
                        password="root">
        </jdbcConnection>
        <javaTypeResolver>
            <!-- This property is used to specify whether MyBatis Generator should
                force the use of java.math.BigDecimal for DECIMAL and NUMERIC fields, -->
            <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
			NUMERIC 类型解析为java.math.BigDecimal -->
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- 生成模型的包名和位置
         实体类
         -->
        <javaModelGenerator targetPackage="entity"
                            targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!--&lt;!&ndash; 生成映射文件的包名和位置 &ndash;&gt;-->
        <!--<sqlMapGenerator targetPackage="mapper"-->
        <!--targetProject="src/main/resources">-->
        <!--<property name="enableSubPackages" value="true" />-->
        <!--</sqlMapGenerator>-->
        <!--&lt;!&ndash; 生成DAO的包名和位置 &ndash;&gt;-->
        <!--<javaClientGenerator type="XMLMAPPER"-->
        <!--targetPackage="com.qianfeng.dao" targetProject="src/main/java">-->
        <!--<property name="enableSubPackages" value="true" />-->
        <!--</javaClientGenerator>-->
        <!---->


        <!-- 要生成哪些表 -->

        <table tableName="sys_user"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_role"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_menu"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_log"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_Config"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_schedule"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="sys_schedule_log"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="tb_user"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>
        <table tableName="tb_token"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"></table>


    </context>
</generatorConfiguration>

7.springmvc-servlet.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描controller注解-->
    <context:component-scan base-package="controller,exception" use-default-filters="false">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    </context:component-scan>
    <!--注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--静态资源放行-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>



    <!--==========shiro注解能在springmvc容器中使用============-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"></bean>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <!--
        securityManager
        -->
        <property name="securityManager" ref="securityManager"></property>
    </bean>



</beans>

8.前端页面

login.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>容灾管理平台</title>
  <!-- Tell the browser to be responsive to screen width -->
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
  <link rel="stylesheet" href="public/css/bootstrap.min.css">
  <link rel="stylesheet" href="public/css/font-awesome.min.css">
  <link rel="stylesheet" href="public/css/AdminLTE.min.css">
  <!-- AdminLTE Skins. Choose a skin from the css/skins
       folder instead of downloading all of them to reduce the load. -->
  <link rel="stylesheet" href="public/css/all-skins.min.css">
  <link rel="stylesheet" href="public/css/main.css">
  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
</head>
<body class="hold-transition login-page">
<div class="login-box" id="rrapp" v-cloak>
  <div class="login-logo">
    <b>容灾管理平台</b>
  </div>
  <!-- /.login-logo -->
  <div class="login-box-body">
      <p class="login-box-msg">用户登录</p>
      <div v-if="error" class="alert alert-danger alert-dismissible">
        <h4 style="margin-bottom: 0px;"><i class="fa fa-exclamation-triangle"></i> {{errorMsg}}</h4>
      </div>
      <div class="form-group has-feedback">
        <input type="text" class="form-control" v-model="user.username" placeholder="账号">
        <span class="glyphicon glyphicon-user form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <input type="password" class="form-control" v-model="user.password" placeholder="密码">
        <span class="glyphicon glyphicon-lock form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <input type="text" class="form-control" v-model="user.captcha" @keyup.enter="login" placeholder="验证码">
        <span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <img alt="如果看不清楚,请单击图片刷新!" class="pointer" src="src" @click="refreshCode">
        &nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:;" @click="refreshCode">点击刷新</a>
      </div>
      <div class="checkbox text-left">
          <label><input type="checkbox" v-model="user.rememberMe" value="true">记住我</label>
      </div>
      
      <div class="row">
        <div class="col-xs-8">
          <div class="checkbox icheck">
          </div>
        </div>
        <!-- /.col -->
        <div class="col-xs-4">
          <button type="button" class="btn btn-primary btn-block btn-flat" @click="login">登录</button>
        </div>
        <!-- /.col -->
      </div>
    <!-- /.social-auth-links -->

  </div>
  <!-- /.login-box-body -->
</div>
<!-- /.login-box -->
<script src="public/libs/jquery.min.js"></script>
<script src="public/libs/vue.min.js"></script>
<script src="public/libs/bootstrap.min.js"></script>
<script src="public/libs/jquery.slimscroll.min.js"></script>
<script src="public/libs/fastclick.min.js"></script>
<script src="public/libs/app.js"></script>
<script type="text/javascript">
var vm = new Vue({
	el:'#rrapp',
	data:{
	    user:{},
		error: false,
		errorMsg: '',
		src: 'captcha.jpg'
	},
    beforeCreate: function(){
        if(self != top){
            top.kk = self.kk;
        }
    },
	methods: {
		refreshCode: function(){
            this.src = "captcha.jpg?t=" + $.now();
		},
		login: function (event) {

		    $.ajax({
                type: "POST",
                url: "/sys/login",
                data: JSON.stringify(vm.user),
                dataType: "json",
                contentType: "application/json",
                cache: false,
                success: function(result){
                    if(result.code == 0){//登录成功
                        parent.kk ='index.html';
                    }else{
                        vm.error = true;
                        vm.errorMsg = result.msg;

                        vm.refreshCode();
                    }
                }
            });
		}
	}
});
</script>
</body>
</html>

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>容灾管理平台</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <link rel="stylesheet" href="public/css/bootstrap.min.css">
    <link rel="stylesheet" href="public/css/font-awesome.min.css">
    <link rel="stylesheet" href="public/css/AdminLTE.min.css">
    <!-- AdminLTE Skins. Choose a skin from the css/skins
         folder instead of downloading all of them to reduce the load. -->
    <link rel="stylesheet" href="public/css/all-skins.min.css">
    <link rel="stylesheet" href="public/css/main.css">
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<!-- ADD THE CLASS layout-boxed TO GET A BOXED LAYOUT -->
<body class="hold-transition skin-blue sidebar-mini">
<!-- Site wrapper -->
<div class="wrapper" id="dtapp" v-cloak>
    <header class="main-header">
        <a href="javascript:void(0);" class="logo">
            <!-- mini logo for sidebar mini 50x50 pixels -->
            <span class="logo-mini"><b>容灾</b></span>
            <!-- logo for regular state and mobile devices -->
            <span class="logo-lg"><b>容灾管理平台</b></span>
        </a>
        <!-- Header Navbar: style can be found in header.less -->
        <nav class="navbar navbar-static-top" role="navigation">
            <!-- Sidebar toggle button-->
            <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
                <span class="sr-only">Toggle navigation</span>
            </a>
            <div style="float:left;color:#fff;padding:15px 10px;">欢迎 {{user.username}}</div>
            <div class="navbar-custom-menu">
                <ul class="nav navbar-nav">
                    <li><a href="javascript:;" @click="updatePassword"><i class="fa fa-lock"></i> &nbsp;修改密码</a></li>
                    <li><a href="logout"><i class="fa fa-sign-out"></i> &nbsp;退出系统</a></li>
                </ul>
            </div>
        </nav>
    </header>

    <!-- =============================================== -->

    <!-- Left side column. contains the sidebar -->
    <aside class="main-sidebar">
        <!-- sidebar: style can be found in sidebar.less -->
        <section class="sidebar">
            <!-- /.search form -->
            <!-- sidebar menu: : style can be found in sidebar.less -->
            <ul class="sidebar-menu">
                <li class="header">导航菜单</li>
                <!-- vue生成的菜单 -->
                <menu-item :item="item" v-for="item in menuList"></menu-item>
                <!--<li class="treeview">
                    <a href="#">
                        <i class="fa fa-clock-o"></i>
                        <span>定时任务</span>
                        <span class="pull-right-container">
                            <i class="fa fa-angle-left pull-right"></i>
                        </span>
                    </a>
                    <ul class="treeview-menu">
                        <li><a href="#sys/job.html"><i class="fa fa-circle-o"></i> 任务管理</a></li>
                        <li><a href="#sys/schedule_log.html"><i class="fa fa-circle-o"></i> 任务日志</a></li>
                    </ul>
                </li>
                <li class="treeview">
                    <a href="#">
                        <i class="fa fa-binoculars"></i>
                        <span>系统监控</span>
                        <span class="pull-right-container">
                            <i class="fa fa-angle-left pull-right"></i>
                        </span>
                    </a>
                    <ul class="treeview-menu">
                        <li><a href="#druid/sql.html"><i class="fa fa-circle-o"></i> SQL监控</a></li>
                        <li><a href="#sys/log.html"><i class="fa fa-circle-o"></i> 系统日志</a></li>
                    </ul>
                </li>
                <li>
                    <a href="#">
                        <i class="fa fa-cog"></i>
                        <span>系统管理</span>
                        <span class="pull-right-container">
                            <i class="fa fa-angle-left pull-right"></i>
                        </span>
                    </a>
                    <ul class="treeview-menu">
                        <li><a href="#sys/user.html"><i class="fa fa-circle-o"></i> 用户管理</a></li>
                        <li><a href="#sys/role.html"><i class="fa fa-circle-o"></i> 角色管理</a></li>
                        <li><a href="#sys/menu.html"><i class="fa fa-circle-o"></i> 菜单管理</a></li>
                        <li><a href="#sys/config.html"><i class="fa fa-circle-o"></i> 参数管理</a></li>
                    </ul>
                </li>-->

            </ul>
        </section>
        <!-- /.sidebar -->
    </aside>
    <!-- =============================================== -->
    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <section class="content-header">
            <ol class="breadcrumb" id="nav_title" style="position:static;float:none;">
                <li class="active"><i class="fa fa-home"
                                      style="font-size:20px;position:relative;top:2px;left:-3px;"></i> &nbsp; 首页
                </li>
                <li class="active">{{navTitle}}</li>
            </ol>
        </section>

        <!-- Main content -->
        <section class="content" style="background:#fff;">
            <iframe scrolling="yes" frameborder="0"
                    style="width:100%;min-height:200px;overflow:visible;background:#fff;" :src="main"></iframe>
        </section>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

    <!-- Add the sidebar's background. This div must be placed
         immediately after the control sidebar -->
    <div class="control-sidebar-bg"></div>

    <!-- 修改密码 -->
    <div id="passwordLayer" style="display: none;">
        <form class="form-horizontal">
            <div class="form-group">
                <div class="form-group">
                    <div class="col-sm-2 control-label">账号</div>
                    <span class="label label-success" style="vertical-align: bottom;">{{user.username}}</span>
                </div>
                <div class="form-group">
                    <div class="col-sm-2 control-label">原密码</div>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" v-model="password" placeholder="原密码"/>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-2 control-label">新密码</div>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" v-model="newPassword" placeholder="新密码"/>
                    </div>
                </div>
            </div>
        </form>
    </div>

</div>
<!-- ./wrapper -->


<script src="public/libs/jquery.min.js"></script>
<script src="public/libs/vue.min.js"></script>
<script src="public/libs/router.js"></script>
<script src="public/libs/bootstrap.min.js"></script>
<script src="public/libs/app.js"></script>
<script src="public/plugins/layer/layer.js"></script>
<script src="public/js/index.js"></script>
</body>
</html>

二、代码

1.controller

SysUserController

代码语言:javascript
复制
package controller;

import com.baomidou.mybatisplus.extension.api.R;
import entity.SysUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * zt
 * 2020/10/22
 * 22:32
 */
@RestController
public class SysUserController {
    @RequestMapping("/sys/login")
    public R login(@RequestBody SysUser sysUser){
        System.out.println("00000000000000");
        UsernamePasswordToken token = new UsernamePasswordToken(sysUser.getUsername()
        ,sysUser.getPassword());
        System.out.println("token:"+token);

        Subject subject = SecurityUtils.getSubject();
        subject.login(token);
        System.out.println("11111");
        return R.ok("登录成功");
    }

}

2.entity自动生成

3.exception

MyExceptionHandler

代码语言:javascript
复制
package exception;


import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import utils.R;

/**
 * @Author zt
 * @Date 2020/10/19
 */
public class MyExceptionHandler {
    @ExceptionHandler(UnknownAccountException.class)
    public R unknown(UnknownAccountException e){
        System.out.println("message"+e.getMessage());
        System.out.println("LocalizedMessage"+e.getLocalizedMessage());
        return R.error(e.getMessage());
    }


    @ExceptionHandler(Exception.class)
    public R unknown(Exception e){
        System.out.println("message"+e.getMessage());
        System.out.println("LocalizedMessage"+e.getLocalizedMessage());
        return R.error(e.getMessage());
    }



}

MyQuartzException

代码语言:javascript
复制
package exception;

/**
 * @Description:
 * @Company: 千锋互联
 * @Author: 李丽婷
 * @Date: 2020/10/21
 * @Time: 下午2:51
 */
public class MyQuartzException extends  RuntimeException {

    private   String   msg;

    public MyQuartzException(){}

    public MyQuartzException(String msg){
        super(msg);
    }




}

4.mapper

SysUserMapper

代码语言:javascript
复制
package mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import entity.SysUser;

/**
 * zt
 * 2020/10/22
 * 21:55
 */
public interface SysUserMapper extends BaseMapper<SysUser> {
}

5.realm

MyUserRealm

代码语言:javascript
复制
package realm;

import entity.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import service.SysUserService;

import javax.annotation.Resource;

/**
 * zt
 * 2020/10/22
 * 22:25
 */
public class MyUserRealm extends AuthorizingRealm {
    @Resource
    private SysUserService sysUserService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String  username= (String) token.getPrincipal();
        String password=new String((char[]) token.getCredentials());
        System.out.println(username);
        System.out.println(password);

        SysUser sysUser=sysUserService.login(username);
        if(sysUser==null){
            throw new UnknownAccountException("用户名错误");
        }
        if(!sysUser.getPassword().equals(password)){
            throw  new IncorrectCredentialsException("密码错误");
        }
        if(sysUser.getStatus()!=1){
            throw  new LockedAccountException("账号被禁用,请联系管理员");
        }
        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(sysUser,password,this.getName());
        return info;
    }
}

6.service

SysUserService

代码语言:javascript
复制
package service;

import entity.SysUser;

/**
 * zt
 * 2020/10/22
 * 22:37
 */
public interface SysUserService {
    SysUser login(String username);
}

SysUserServiceImpl

代码语言:javascript
复制
package service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import entity.SysUser;
import mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import service.SysUserService;

import javax.annotation.Resource;

/**
 * zt
 * 2020/10/22
 * 22:37
 */
@Service
public class SysUserServiceImpl implements SysUserService {
    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    public SysUser login(String username) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        return sysUserMapper.selectOne(wrapper);
    }
}

8.utils

R

代码语言:javascript
复制
package utils;

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

public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    public R() {
        put("code", 0);
    }

    public static R error() {
        return error(500, "未知异常,请联系管理员");
    }

    public static R error(String msg) {
        return error(500, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }

    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }
}

shiroutils

代码语言:javascript
复制
package utils;

import entity.SysUser;
import org.apache.shiro.SecurityUtils;

/**
 * @Author zt
 * @Date 2020/10/20
 */
public class shiroutils {
    public static SysUser getCurrentUser(){
       return (SysUser) SecurityUtils.getSubject().getPrincipal();
    }
    public static long getUserid(){
      return   getCurrentUser().getUserId();
    }
}

SysConstant

代码语言:javascript
复制
package utils;

/**
 * @Author zt
 * @Date 2020/10/21
 */
public class SysConstant {
    public  static final byte JOB_PAUSE=0;
    public  static final byte JOB_RESUME=1;
    public  static final String TRIGGER_PREFIX="MyTrigger_";
    public  static final String JOB_PREFIX="MyJob_";
    public  static final String  DATA_KEY="task";
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、环境搭建
  • 1.配置pom
  • 2.applicationContext.xml
  • 3.applicationContext-shiro.xml
  • 4.dbinfo.properties
  • 5.ehcache.xml缓存
  • 6.mybatisgenerator.xml自动生成实体类
  • 7.springmvc-servlet.xml
  • 8.前端页面
  • 二、代码
  • 1.controller
  • 2.entity自动生成
  • 3.exception
  • 4.mapper
  • 5.realm
  • 6.service
  • 8.utils
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档