layui的一個登錄和權(quán)限示例

layui是一個專門為后臺而設計的一個前端框架端姚,功能強大,特別適合后端開發(fā)人員讹俊,本文以一個demo把登錄模塊和權(quán)限模塊基本原理說明垦沉,詳細的內(nèi)容可以參考layui的官方文檔git地址

搭建項目

項目架構(gòu)是springboot+thymeleaf+layui仍劈,結(jié)構(gòu)如下圖厕倍,文件有點多,分成兩張圖


image.png

image.png

其中resources資源文件里的layui文件夾下就是layui的所有文件贩疙,內(nèi)容需要到官網(wǎng)下載讹弯,解壓后全部復制即可

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.haijunyin</groupId>
    <artifactId>layuidemo-permission</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>layuidemo-permission</name>
    <description>Demo project for Spring Boot</description>
    <packaging>war</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除內(nèi)置容器况既,排除內(nèi)置容器導出成war包可以讓外部容器運行spring-boot項目-->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.11.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>3.0.11.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties

#thymelea模板配置
xspring.thymeleaf.prefi=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
#熱部署文件,頁面不產(chǎn)生緩存组民,及時更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

LayuidemoPermissionApplication.java

package com.haijunyin.layuidemo.permission;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 繼承SpringBootServletInitializer棒仍,因為繼承SpringBootServletInitializer是繼承WebApplicationInitializer的,而servlet容器啟動的時候
 * 會將WebApplicationInitializer相關(guān)的所有子類實例化(這也是servlet3.0以上的版本提供支持)臭胜,所以我們還需要在pom.xml
 * 文件中導入servlet3.0及以上的版本
 */
@ComponentScan(value = "com.haijunyin.layuidemo.permission")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAsync
public class LayuidemoPermissionApplication extends SpringBootServletInitializer{

    @Override
    public SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(LayuidemoPermissionApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(LayuidemoPermissionApplication.class, args);
    }

}

admin_user_list.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>layui在線調(diào)試</title>
    <link rel="stylesheet" href="../layui/css/layui.css" media="all">
    <style>
        body{margin: 10px;}
        .demo-carousel{height: 200px; line-height: 200px; text-align: center;}
    </style>
</head>
<body>

<table class="layui-hide" id="demo" lay-filter="test"></table>

<script type="text/html" id="barDemo">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
    <a class="layui-btn layui-btn-xs" lay-event="edit">編輯</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>

<div class="layui-tab layui-tab-brief" lay-filter="demo">
    <ul class="layui-tab-title">
        <li class="layui-this">演示說明</li>
        <li>日期</li>
        <li>分頁</li>
        <li>上傳</li>
        <li>滑塊</li>
    </ul>
    <div class="layui-tab-content">
        <div class="layui-tab-item layui-show">

            <div class="layui-carousel" id="test1">
                <div carousel-item>
                    <div><p class="layui-bg-green demo-carousel">在這里莫其,你將以最直觀的形式體驗 layui!</p></div>
                    <div><p class="layui-bg-red demo-carousel">在編輯器中可以執(zhí)行 layui 相關(guān)的一切代碼</p></div>
                    <div><p class="layui-bg-blue demo-carousel">你也可以點擊左側(cè)導航針對性地試驗我們提供的示例</p></div>
                    <div><p class="layui-bg-orange demo-carousel">如果最左側(cè)的導航的高度超出了你的屏幕</p></div>
                    <div><p class="layui-bg-cyan demo-carousel">你可以將鼠標移入導航區(qū)域耸三,然后滑動鼠標滾輪即可</p></div>
                </div>
            </div>
        </div>
        <div class="layui-tab-item">
            <div id="laydateDemo"></div>
        </div>
        <div class="layui-tab-item">
            <div id="pageDemo"></div>
        </div>
        <div class="layui-tab-item">
            <div class="layui-upload-drag" id="uploadDemo">
                <i class="layui-icon"></i>
                <p>點擊上傳榜配,或?qū)⑽募献У酱颂?lt;/p>
            </div>
        </div>
        <div class="layui-tab-item">
            <div id="sliderDemo" style="margin: 50px 20px;"></div>
        </div>
    </div>
</div>

<blockquote class="layui-elem-quote layui-quote-nm layui-hide" id="footer">layui {{ layui.v }} 提供強力驅(qū)動</blockquote>


<script src="../layui/layui.js"></script>
<script>
    layui.config({
        version: '1545041465480' //為了更新 js 緩存,可忽略
    });

    layui.use(['laydate', 'laypage', 'layer', 'table', 'carousel', 'upload', 'element', 'slider'], function(){
        var laydate = layui.laydate //日期
            ,laypage = layui.laypage //分頁
            ,layer = layui.layer //彈層
            ,table = layui.table //表格
            ,carousel = layui.carousel //輪播
            ,upload = layui.upload //上傳
            ,element = layui.element //元素操作
            ,slider = layui.slider //滑塊

        //向世界問個好
        layer.msg('Hello World');

        //監(jiān)聽Tab切換
        element.on('tab(demo)', function(data){
            layer.tips('切換了 '+ data.index +':'+ this.innerHTML, this, {
                tips: 1
            });
        });

        //執(zhí)行一個 table 實例
        table.render({
            elem: '#demo'
            ,height: 420
            ,url: '/demo/table/user/' //數(shù)據(jù)接口
            ,title: '用戶表'
            ,page: true //開啟分頁
            ,toolbar: 'default' //開啟工具欄吕晌,此處顯示默認圖標,可以自定義模板临燃,詳見文檔
            ,totalRow: true //開啟合計行
            ,cols: [[ //表頭
                {type: 'checkbox', fixed: 'left'}
                ,{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left', totalRowText: '合計:'}
                ,{field: 'username', title: '用戶名', width:80}
                ,{field: 'experience', title: '積分', width: 90, sort: true, totalRow: true}
                ,{field: 'sex', title: '性別', width:80, sort: true}
                ,{field: 'score', title: '評分', width: 80, sort: true, totalRow: true}
                ,{field: 'city', title: '城市', width:150}
                ,{field: 'sign', title: '簽名', width: 200}
                ,{field: 'classify', title: '職業(yè)', width: 100}
                ,{field: 'wealth', title: '財富', width: 135, sort: true, totalRow: true}
                ,{fixed: 'right', width: 165, align:'center', toolbar: '#barDemo'}
            ]]
        });

        //監(jiān)聽頭工具欄事件
        table.on('toolbar(test)', function(obj){
            var checkStatus = table.checkStatus(obj.config.id)
                ,data = checkStatus.data; //獲取選中的數(shù)據(jù)
            switch(obj.event){
                case 'add':
                    layer.msg('添加');
                    break;
                case 'update':
                    if(data.length === 0){
                        layer.msg('請選擇一行');
                    } else if(data.length > 1){
                        layer.msg('只能同時編輯一個');
                    } else {
                        layer.alert('編輯 [id]:'+ checkStatus.data[0].id);
                    }
                    break;
                case 'delete':
                    if(data.length === 0){
                        layer.msg('請選擇一行');
                    } else {
                        layer.msg('刪除');
                    }
                    break;
            };
        });

        //監(jiān)聽行工具事件
        table.on('tool(test)', function(obj){ //注:tool 是工具條事件名睛驳,test 是 table 原始容器的屬性 lay-filter="對應的值"
            var data = obj.data //獲得當前行數(shù)據(jù)
                ,layEvent = obj.event; //獲得 lay-event 對應的值
            if(layEvent === 'detail'){
                layer.msg('查看操作');
            } else if(layEvent === 'del'){
                layer.confirm('真的刪除行么', function(index){
                    obj.del(); //刪除對應行(tr)的DOM結(jié)構(gòu)
                    layer.close(index);
                    //向服務端發(fā)送刪除指令
                });
            } else if(layEvent === 'edit'){
                layer.msg('編輯操作');
            }
        });

        //執(zhí)行一個輪播實例
        carousel.render({
            elem: '#test1'
            ,width: '100%' //設置容器寬度
            ,height: 200
            ,arrow: 'none' //不顯示箭頭
            ,anim: 'fade' //切換動畫方式
        });

        //將日期直接嵌套在指定容器中
        var dateIns = laydate.render({
            elem: '#laydateDemo'
            ,position: 'static'
            ,calendar: true //是否開啟公歷重要節(jié)日
            ,mark: { //標記重要日子
                '0-10-14': '生日'
                ,'2018-08-28': '新版'
                ,'2018-10-08': '神秘'
            }
            ,done: function(value, date, endDate){
                if(date.year == 2017 && date.month == 11 && date.date == 30){
                    dateIns.hint('一不小心就月底了呢');
                }
            }
            ,change: function(value, date, endDate){
                layer.msg(value)
            }
        });

        //分頁
        laypage.render({
            elem: 'pageDemo' //分頁容器的id
            ,count: 100 //總頁數(shù)
            ,skin: '#1E9FFF' //自定義選中色值
            //,skip: true //開啟跳頁
            ,jump: function(obj, first){
                if(!first){
                    layer.msg('第'+ obj.curr +'頁', {offset: 'b'});
                }
            }
        });

        //上傳
        upload.render({
            elem: '#uploadDemo'
            ,url: '' //上傳接口
            ,done: function(res){
                console.log(res)
            }
        });

        slider.render({
            elem: '#sliderDemo'
            ,input: true //輸入框
        });

        //底部信息
        var footerTpl = lay('#footer')[0].innerHTML;
        lay('#footer').html(layui.laytpl(footerTpl).render({}))
            .removeClass('layui-hide');
    });
</script>
</body>
</html>

index.html,此文件是顯示菜單的主要文件

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>XXX后臺管理系統(tǒng)</title>
    <link rel="stylesheet" th:href="@{layui/css/layui.css}">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
    <div class="layui-header">
        <div class="layui-logo">XXX后臺管理系統(tǒng)</div>
        <!-- 頭部區(qū)域(可配合layui已有的水平導航) -->
        <ul class="layui-nav layui-layout-left">
            <li class="layui-nav-item"><a href="">控制臺</a></li>
            <li class="layui-nav-item"><a href="">商品管理</a></li>
            <li class="layui-nav-item"><a href="">用戶</a></li>
            <li class="layui-nav-item">
                <a href="javascript:;">其它系統(tǒng)</a>
                <dl class="layui-nav-child">
                    <dd><a href="">郵件管理</a></dd>
                    <dd><a href="">消息管理</a></dd>
                    <dd><a href="">授權(quán)管理</a></dd>
                </dl>
            </li>
        </ul>
        <ul class="layui-nav layui-layout-right">
            <li class="layui-nav-item">
                <a href="javascript:;">
                    <img src="http://t.cn/RCzsdCq" class="layui-nav-img">
                    <span th:text="${adminUserInfo.userName}"></span>
                </a>
                <dl class="layui-nav-child">
                    <dd><a href="">基本資料</a></dd>
                    <dd><a href="">安全設置</a></dd>
                </dl>
            </li>
            <li class="layui-nav-item"><a href="">退了</a></li>
        </ul>
    </div>

    <div class="layui-side layui-bg-black">
        <div class="layui-side-scroll">
            <!-- 左側(cè)導航區(qū)域(可配合layui已有的垂直導航) -->
            <ul class="layui-nav layui-nav-tree">

                <li class="layui-nav-item" th:each="adminParentMenuInfo : ${adminUserInfo.adminParentMenuInfos}">
                    <a class="" href="javascript:;" th:text="${adminParentMenuInfo.parentMenuName}"></a>
                    <dl class="layui-nav-child" th:each="adminMenuInfo : ${adminParentMenuInfo.adminMenuInfos}">
                        <dd class="layui-nav">
                            <a href="javascript:;" th:id="${adminMenuInfo.filterId}" th:zdy-url="${adminMenuInfo.menuUrl}">
                                <cite th:text="${adminMenuInfo.menuName}"></cite>
                            </a>
                        </dd>
                    </dl>
                </li>

            </ul>
        </div>
    </div>

    <div class="layui-body">
        <div class="layui-tab" lay-allowClose="true" lay-filter="demo">
            <ul class="layui-tab-title" id="myLayuiTab">
            </ul>
            <div class="layui-tab-content">
            </div>
        </div>
    </div>

    <div class="layui-footer">
        <!-- 底部固定區(qū)域 -->
        ? layui.com - 底部固定區(qū)域
    </div>
</div>
<script th:src="@{layui/layui.js}"></script>
<script>
    //JavaScript代碼區(qū)域
    layui.use('element', function(){
        var element = layui.element;
        element.on('nav', function(data){
//            console.log(this); //當前Tab標題所在的原始DOM元素
            var zdyUrl = this.getAttribute("zdy-url"); //獲取url
            var layId = this.getAttribute("id"); //獲取id
            var title = this.getElementsByTagName("cite").item(0).textContent;
            //組裝content
            var content = '<iframe  frameborder="0" scrolling="no" width="100%" height="100%" src="' + zdyUrl + '"></iframe>';

            //判斷myLayuiTab中有沒有重復膜廊,如果有乏沸,則不添加
            var documentLis = document.getElementById("myLayuiTab").getElementsByTagName("li");
            var flag = false;
            for(var i=0; i<documentLis.length; i++){
                var documentLi = documentLis[i];
                var layIdView = documentLi.getAttribute("lay-id");
                if(layId == layIdView){
                    flag = true;
                }
            }
            if(!flag) {
                //添加
                element.tabAdd('demo', {
                    title: title
                    , content: content
                    , id: layId
                });
            }
            //切換
            element.tabChange('demo', layId);
        });

    });

</script>
</body>
</html>

login.html,登錄頁

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>XXX后臺登錄</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" th:href="@{layui/css/layui.css}"  media="all">
</head>
<body>

<blockquote class="layui-elem-quote layui-text">
    歡迎訪問后臺管理系統(tǒng)
</blockquote>

<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
    <legend>登錄</legend>
</fieldset>

<form class="form-horizontal" th:action="@{/login}" method="get">
    <div class="layui-form-item">
        <label class="layui-form-label">輸入框</label>
        <div class="layui-input-block">
            <input type="text" name="userName" lay-verify="title" autocomplete="off" placeholder="用戶名" required="true" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">密碼框</label>
        <div class="layui-input-block">
            <input type="password" name="userPwd" placeholder="請輸入密碼" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">驗證碼</label>
        <div class="layui-input-block">
            <input type="text" name="verifyCode" placeholder="驗證碼" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-input-block">
            <button class="layui-btn" lay-submit="" lay-filter="demo1">立即提交</button>
        </div>
    </div>
</form>
<script th:src="@{layui/layui.js}" charset="utf-8"></script>
</body>
</html>

layui下的所有文件都是官網(wǎng)下載然后解壓的

DefineAdapter.java爪瓜,攔截器配置

package com.haijunyin.layuidemo.permission.config;

import com.haijunyin.layuidemo.permission.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

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

@Configuration
public class DefineAdapter implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    //登錄攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //排除不被攔截的資源
        List<String> excludePaths = new ArrayList<>();
        //layui的靜態(tài)文件
        excludePaths.add("/layui/**");

        //靜態(tài)頁面
        excludePaths.add("/**/*.html");

        //登錄
        excludePaths.add("/");
        excludePaths.add("/login");
//        excludePaths.add("/error");

        registry.addInterceptor(loginInterceptor).
                addPathPatterns("/**").excludePathPatterns(excludePaths);

    }


}

AdminController.java

package com.haijunyin.layuidemo.permission.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "admin")
public class AdminController {

    @RequestMapping(value = "list",method = RequestMethod.GET)
    public String list(){
        return "權(quán)限List測試";
    }

}

LoginController.java

package com.haijunyin.layuidemo.permission.controller;

import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {

    @Autowired
    private AdminUserService adminUserService;

    /**
     * 設置默認打開地址http://localhost:8020的跳轉(zhuǎn)(需要在攔截器中排除)
     * 1.已登錄蹬跃,跳轉(zhuǎn)到index.html,把adminUserInfo返回前端渲染
     * 2.未登錄铆铆,跳轉(zhuǎn)到登錄頁
     */
    @RequestMapping(value = "/",method = RequestMethod.GET)
    public String index(HttpServletRequest request, ModelMap modelMap){
        HttpSession session = request.getSession();
        AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
        if(null != adminUserInfo){
            modelMap.addAttribute("adminUserInfo",adminUserInfo);
            return "index";
        }else{
            return "login";
        }
    }

    /**
     * 登錄(需要在攔截器中排除)
     * 1.已登錄蝶缀,跳轉(zhuǎn)到index.html,把adminUserInfo返回前端渲染
     * 2.未登錄薄货,驗證密碼翁都,如果密碼正確,跳轉(zhuǎn)到index.html, 則把用戶信息放入session谅猾,并把adminUserInfo返回前端渲染
     *                     如果密碼錯誤柄慰,跳轉(zhuǎn)到login.html
     */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(@RequestParam(value = "userName", required = false) String userName,
                        @RequestParam(value = "userPwd", required = false) String userPwd,
                        @RequestParam(value = "verifyCode", required = false) String verifyCode,
                        HttpServletRequest request,
                        ModelMap modelMap){

        //先驗證session,再驗證密碼
        HttpSession session = request.getSession();
        AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
        if(null != adminUserInfo){
            modelMap.addAttribute("adminUserInfo",adminUserInfo);
            return "index";
        }else{
            //驗證密碼
            AdminUserInfo adminUserInfo0 = adminUserService.findByUserName(userName);
            System.out.println("驗證登錄...userName="+userName+"userPwd="+userPwd+"verifyCode="+verifyCode);
            if(adminUserInfo0.getUserPwd().equals(userPwd)){
                //用戶信息放入session
                System.out.println("登錄...成功..." + "用戶名:" + userName);
                request.getSession().setAttribute("adminUserInfo", adminUserInfo0);
                modelMap.addAttribute("adminUserInfo",adminUserInfo0);
                return "index";
            }else{
                System.out.println("登錄...密碼輸入錯誤..." + "用戶名:" + userName);
                return "login";
            }
        }
    }

}

LoginInterceptor.java税娜,登錄攔截器坐搔,用于攔截處理登錄和為登錄狀態(tài)下的ajax請求

package com.haijunyin.layuidemo.permission.interceptor;

import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Service
public class LoginInterceptor extends HandlerInterceptorAdapter{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
        //未登錄去登錄
        if(null == adminUserInfo){
            //注意:這里需要寫上"/login",而不是"login"敬矩,否則重定向的地址只會替換最后一個"/"后面的字符串
            response.sendRedirect("/login");
        }
        return true;
    }

}

AdminMenuInfo.java概行,子菜單信息,權(quán)限需要真正控制的信息

package com.haijunyin.layuidemo.permission.module;

public class AdminMenuInfo {

    /** 子菜單唯一ID谤绳,在頁面上面會以它做唯一區(qū)分的占锯,對應到相應子窗口的lay-id屬性 */
    private String filterId;

    /** 子菜單名袒哥,對應子窗口的title */
    private String menuName;

    /** 子菜單URL,對應子窗口的鏈接html消略,點擊子菜單后堡称,會打開一個iframe并鏈接到此url */
    private String menuUrl;

    public AdminMenuInfo(){

    }

    public AdminMenuInfo(String filterId, String menuName, String menuUrl){
        this.filterId = filterId;
        this.menuName = menuName;
        this.menuUrl = menuUrl;
    }

    public String getFilterId() {
        return filterId;
    }

    public void setFilterId(String filterId) {
        this.filterId = filterId;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public String getMenuUrl() {
        return menuUrl;
    }

    public void setMenuUrl(String menuUrl) {
        this.menuUrl = menuUrl;
    }
}

AdminParentInfo.java,父菜單信息

package com.haijunyin.layuidemo.permission.module;

import java.util.List;

public class AdminParentMenuInfo {

    private String parentMenuName;

    private List<AdminMenuInfo> adminMenuInfos;

    public AdminParentMenuInfo(){

    }

    public AdminParentMenuInfo(String parentMenuName, List<AdminMenuInfo> adminMenuInfos){
        this.parentMenuName = parentMenuName;
        this.adminMenuInfos = adminMenuInfos;
    }

    public String getParentMenuName() {
        return parentMenuName;
    }

    public void setParentMenuName(String parentMenuName) {
        this.parentMenuName = parentMenuName;
    }

    public List<AdminMenuInfo> getAdminMenuInfos() {
        return adminMenuInfos;
    }

    public void setAdminMenuInfos(List<AdminMenuInfo> adminMenuInfos) {
        this.adminMenuInfos = adminMenuInfos;
    }
}

AdminUserInfo.java艺演,用戶信息却紧,用戶登陸后會放入session

package com.haijunyin.layuidemo.permission.module;

import java.util.List;

public class AdminUserInfo {

    private long id;

    private String userName;

    private String userPwd;

    private List<AdminParentMenuInfo> adminParentMenuInfos;

    public long getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

    public List<AdminParentMenuInfo> getAdminParentMenuInfos() {
        return adminParentMenuInfos;
    }

    public void setAdminParentMenuInfos(List<AdminParentMenuInfo> adminParentMenuInfos) {
        this.adminParentMenuInfos = adminParentMenuInfos;
    }
}

AdminUserService.java

package com.haijunyin.layuidemo.permission.services;


import com.haijunyin.layuidemo.permission.module.AdminUserInfo;

public interface AdminUserService {

    AdminUserInfo findByUserName(String userName);

}

AdminUserServiceImpl.java,用戶登陸信息加載胎撤,實際開發(fā)過程中晓殊,信息都是從數(shù)據(jù)庫中讀取的,設計用戶-角色-資源的模型結(jié)構(gòu)伤提,本文不做敘述巫俺,

package com.haijunyin.layuidemo.permission.services.impl;

import com.haijunyin.layuidemo.permission.module.AdminMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminParentMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.stereotype.Service;

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

@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Override
    public AdminUserInfo findByUserName(String userName) {
        AdminUserInfo userInfo = new AdminUserInfo();
        userInfo.setId(1);
        userInfo.setUserName("yhj");
        userInfo.setUserPwd("123456");
        List<AdminParentMenuInfo> adminParentMenuInfos = new ArrayList<>();
        //權(quán)限管理
        List<AdminMenuInfo> adminMenuInfos1 = new ArrayList<>();
        AdminMenuInfo adminMenuInfo1 = new AdminMenuInfo("filter1","用戶","admin/admin_user_list.html");
        adminMenuInfos1.add(adminMenuInfo1);
        AdminMenuInfo adminMenuInfo2 = new AdminMenuInfo("filter2", "角色","admin/admin_role_list.html");
        adminMenuInfos1.add(adminMenuInfo2);
        AdminParentMenuInfo adminParentMenuInfo1 = new AdminParentMenuInfo("權(quán)限管理",adminMenuInfos1);
        adminParentMenuInfos.add(adminParentMenuInfo1);
        //訂單管理
        List<AdminMenuInfo> adminMenuInfos2 = new ArrayList<>();
        AdminMenuInfo adminMenuInfo11 = new AdminMenuInfo("filter3", "訂單列表","order/order_list.html");
        adminMenuInfos2.add(adminMenuInfo11);
        AdminMenuInfo adminMenuInfo22 = new AdminMenuInfo("filter4", "訂單推送","order/order_send.html");
        adminMenuInfos2.add(adminMenuInfo22);
        AdminParentMenuInfo adminParentMenuInfo2 = new AdminParentMenuInfo("訂單管理",adminMenuInfos2);
        adminParentMenuInfos.add(adminParentMenuInfo2);

        userInfo.setAdminParentMenuInfos(adminParentMenuInfos);
        return userInfo;
    }
}

運行結(jié)果

瀏覽器中輸入地址

http://localhost:8020/

彈出登陸頁面


image.png

輸入用戶名,密碼(123456)肿男,出現(xiàn)首頁


,

點擊權(quán)限管理或訂單管理介汹,出現(xiàn)子窗口信息


image.png

總結(jié)

到此,Demo結(jié)束舶沛,可以看出一個完整的登陸和權(quán)限也是不簡單的嘹承,本文只是把主干完成了,細節(jié)的東西沒用去設計如庭,比如登陸頁的校驗叹卷、驗證碼,還有權(quán)限的表設計坪它,等等骤竹,不過這些都不是問題了,后續(xù)只需要慢慢完善即可哟楷,我們通過這個Demo瘤载,已經(jīng)成功地開啟了layui的大門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市卖擅,隨后出現(xiàn)的幾起案子鸣奔,更是在濱河造成了極大的恐慌,老刑警劉巖惩阶,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挎狸,死亡現(xiàn)場離奇詭異,居然都是意外死亡断楷,警方通過查閱死者的電腦和手機锨匆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恐锣,你說我怎么就攤上這事茅主。” “怎么了土榴?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵诀姚,是天一觀的道長。 經(jīng)常有香客問我玷禽,道長赫段,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任矢赁,我火速辦了婚禮糯笙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撩银。我一直安慰自己给涕,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布额获。 她就那樣靜靜地躺著稠炬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咪啡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天暮屡,我揣著相機與錄音撤摸,去河邊找鬼。 笑死褒纲,一個胖子當著我的面吹牛准夷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播莺掠,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼衫嵌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了彻秆?” 一聲冷哼從身側(cè)響起楔绞,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唇兑,沒想到半個月后酒朵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡扎附,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年蔫耽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片留夜。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡匙铡,死狀恐怖图甜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鳖眼,我是刑警寧澤黑毅,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站具帮,受9級特大地震影響博肋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜂厅,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一匪凡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掘猿,春花似錦病游、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至改橘,卻和暖如春滋尉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背飞主。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工狮惜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碌识。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓碾篡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親筏餐。 傳聞我的和親對象是個殘疾皇子开泽,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容