SSM项目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架实现登录和主页菜单显示

news2024/11/20 4:49:43

目录

前言

一、加入DWZ J-UI框架

二、实现登录页面

三、实现主页面菜单显示


前言

大家好!写文章之前先列出几篇相关文章。本文内容也在其项目中接续实现。

一. SSM项目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式)_spring security4.x 会话管理配置文件版-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/u011529483/article/details/135699004?spm=1001.2014.3001.5501

二. SpringSecurity认证登录成功后获取角色菜单-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/u011529483/article/details/135763209?spm=1001.2014.3001.5501

三. Spring Security 4.X(XML文件配置session超时,单点登录-session并发控制,退出/logout)_spring security session过期时间 xml-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/u011529483/article/details/136043238?spm=1001.2014.3001.5501


一、加入DWZ J-UI框架

1. 下载DWZ J-UI框架并解压

https://download.csdn.net/download/u011529483/87930662

以上为个人下载地址。

2. 在项目中新建dwz文件,如下图:

然后将解压后的 J-UI 框架的内容全部拷贝到 dwz 文件夹中。我解压后的效果如下:

具体可以参考文章:记dwz(JUI)前端框架使用(一)_dwz框架-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/u011529483/article/details/129150062?spm=1001.2014.3001.5501

注意:此项目中由于加入了 spring-security ,所以需要对dwz文件夹进行配置,下图标红处:

好了!现在可以直接访问到 dwz 文件夹中的静态资源了。要复用dwz中的某一个页面只需要拷贝到指定位置修改成想要的模样就可以了。

二、实现登录页面

1. 将 dwz 文件夹中的 login.html 页面拷贝到 webapp 目录下,修改为jsp页面。如下图:

2. 修改 login.jsp 页面代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>wqxx系统登录页面</title>
    <link href="./dwz/themes/css/login.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="login">
    <div id="login_header">
        <h1 class="login_logo">
            <a href="#"><img src="./dwz/themes/default/images/login_logo.gif" /></a>
        </h1>
        <div class="login_headerContent">
            <div class="navList">
                <ul>
                    <li><a href="#">设为首页</a></li>
                    <li><a href="#">反馈</a></li>
                    <li><a href="./dwz/doc/dwz-user-guide.pdf" target="_blank">帮助</a></li>
                </ul>
            </div>
            <h2 class="login_title"><img src="./dwz/themes/default/images/login_title.png" /></h2>
        </div>
    </div>
    <div id="login_content">
        <div class="loginForm">
            <form action="${pageContext.request.contextPath}/spring_security_check" method="post">
                <p>
                    <label>用户名:</label>
                    <input type="text" name="username" size="20" class="login_input" />
                </p>
                <p>
                    <label>密码:</label>
                    <input type="password" name="password" size="20" class="login_input" />
                </p>
                <p>
                    <label>验证码:</label>
                    <input class="code" type="text" size="5" />
                    <span><img src="./dwz/themes/default/images/header_bg.png" alt="" width="75" height="24" /></span>
                </p>
                <div class="login_bar">
                    <input class="sub" type="submit" value=" " />
                </div>
            </form>
        </div>
        <div class="login_banner"><img src="./dwz/themes/default/images/login_banner.jpg" /></div>
        <div class="login_main">
            <div class="login_inner">
            </div>
        </div>
    </div>
    <div id="login_footer">
        Copyright &copy; 2009 www.dwzjs.com Inc. All Rights Reserved.
    </div>
</div>

</body>
</html>

主要注意 CSS, 图片等资源的路劲修改指向./dwz/目录中。

用户名,密码输入控件的修改与你的后台名称绑定。form表单提交请求的修改,因为使用了spring-security,所以提交路径为 spring-security.xml 文件中配置的路径

<form action="${pageContext.request.contextPath}/spring_security_check" method="post">

到此登录页面完成,如有页面显示差异,自己微调CSS等。运行项目效果如下:

另:附上 spring-security.xml 配置文件代码,登录的后台代码参考前言中的第一篇文章。

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

    <!--指定不受Spring Security管理-->
    <security:http security="none" pattern="/login" />
    <!--放行DWZ的静态资源-->
    <security:http security="none" pattern="/dwz/**" />
    <!--spring过滤器链配置
        1) 需要拦截什么资源
        2) 什么资源对应什么角色权限
        3) 定制认证方式: HttpBasic or FormLogin
        4) 自定义登录页面,定义登录请求地址,定义错误处理方式
    -->
    <security:http>

        <!--
            使用form-login的方式进行认证
                login-page:指定获取登录页面的url(需要编写controller返回登录页面)
                login-processing-url:指定登录页面中post请求提交到哪里的url(不需要编写controller,框架已实现)
                default-target-url:指定登录成功后,跳转到哪个url(需要编写controller)
                authentication-success-handler-ref:指定登录成功后,由哪个类来进行处理
                authentication-failure-handler-ref:指定登录失败后,由哪个类来进行处理
                username-parameter:指定登录表单中用户名的input中name值,如果这里不配置,则默认为username
                password-parameter:指定登录表单中密码的input中name值,如果这里不配置,则默认为password
        -->
        <security:form-login login-page="/login" login-processing-url="/spring_security_check"
                             authentication-success-handler-ref="myAuthenticationSuccessHandler"
                             authentication-failure-handler-ref="myAuthenticationFailureHandler"/>

        <!-- 关闭csrf的保护-->
        <security:csrf disabled="true"/>

        <!-- 配置资源拦截规则
            pattern属性指定资源目录: 即需要拦截的资源  /* 代表根目录下的一级目录  /** 代表根目录下的所有目录
            access(SpEL)方法执行Spring EL表达式。提供如下表达式:
                permitALL():设置那些路径可以直接访问,不需要认证。直接返回true
                isAnonymous():只有匿名用户可以访问,登录用户不可访问
                isAuthenticated():需要身份认证成功才能访问。如果认证用户不是匿名用户,则返回true,认证通过
                isFullyAuthenticated():需要身份认证成功才能访问。如果认证用户不是匿名用户或记住我的用户,则返回true,认证通过
                其它自行查找......
        -->
        <!--开始配置拦截规则,注意拦截规则的位置顺序(如不需要身份认证的规则,要放在前面,需要身份认证的规则放在后面)-->
        <!--permitAll()不需要身份认证,无条件放行-->
        <!--<security:intercept-url pattern="/login" access="permitAll()"/>-->
        <!--<security:intercept-url pattern="/system/index" access="permitAll()"/>-->
        <security:intercept-url pattern="/s_timeout.jsp" access="permitAll()"/>

        <!--进行权限划分:hasRole('ROLE_USER'):表示拥有 ROLE_USER 权限的用户可以访问
        hasRole('ROLE_ALL'):表示拥有 ROLE_ALL 权限的用户可以访问。指定特定权限访问
        -->
        <security:intercept-url pattern="/system/add" access="hasAuthority('admin')"/>
        <security:intercept-url pattern="/system/list" access="hasAuthority('ROLE_ALL')"/>

        <!--permitAll()不需要身份认证,无条件放行静态资源-->
        <security:intercept-url pattern="/js/**" access="permitAll()"/>

        <!--拦截所有页面,需要身份认证成功才能访问。如果认证用户不是匿名用户或记住我的用户,则返回true,认证通过-->
        <security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
        <!--结束配置拦截规则-->

        <!-- 自定义用户访问权限不足的处理方式(需要编写controller返回权限不足的页面) -->
        <security:access-denied-handler error-page="/accessDeny"/>

        <!-- session管理,
        invalid-session-url:指定使用已经超时的sessionId(保存在Cookie中)进行请求需要重定向的页面或路径。
        max-sessions:默认值为1,session并发数量控制。控制同一用户在系统中同时允许存在的已经通过认证的session数量。当超过这个值时,
        Spring Security的默认策略是将先前的设为无效。如果要限制用户再次登录可以设置concurrency-control的error-if-maximum-exceeded的值为true。
        -->
        <security:session-management invalid-session-url="/s_timeout.jsp">
            <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
        </security:session-management>
        <!--<security:session-management session-authentication-error-url="/session" invalid-session-url="/session">
            <security:concurrency-control max-sessions="1" session-registry-alias="sessionRegistry" error-if-maximum-exceeded="false" expired-url="/session"/>
        </security:session-management>-->

        <!--加上Remember Me功能,token-validity-seconds:有效时间(秒)-->
        <!--<security:remember-me token-repository-ref="jdbcTokenRepository" token-validity-seconds="604800"/>-->

        <!--<security:logout/>:注销功能
        logout-url="/logout":退出过滤器默认的拦截路径,springSecurity内LogoutFilter要拦截的url(向这/logout发送请求来注销)
        logout-success-url:用户退出后要被重定向的url
        invalidate-session:默认为true,用户在退出后Http session失效
        success-handler-ref:指定一个bean(需要实现LogoutSuccessHandler接口),用来自定义退出成功后的操作
        delete-cookies="JSESSIONID":删除session对应的cookie
        -->
        <security:logout logout-url="/logout" logout-success-url="/login" invalidate-session="true" delete-cookies="JSESSIONID"/>
    </security:http>

    <!--身份验证管理器-->
    <security:authentication-manager>
        <!--
            自定义授权提供类MyUserDetailsService,获得登录用户的用户详情信息。此类实现UserDetailsService接口。
            user-service-ref="myUserDetailsService" : 指定 UserDetailsService 接口的实现类
            最终都要返回一个UserDetail,用户详情
        -->
        <security:authentication-provider user-service-ref="myUserDetailsService">
            <!-- 配置:加密算法对用户输入的密码进行加密,然后和数据库的密码进行配对 -->
            <!--<security:password-encoder ref="bCryptPasswordEncoder"/>-->
        </security:authentication-provider>
    </security:authentication-manager>

    <!--创建 springSecurity 密码加密工具类,使用PasswordEncoder 接口的实现,也可以使用别的-->
    <!--<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>-->


    <!--springSecurity实现 remember me 功能:
        如果用户登录选择 remember me ,springSecurity会将其cookie值存入数据库,来实现remember me 功能
        JdbcTokenRepositoryImpl 用来存取cookie值-->
    <!--<bean id="jdbcTokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
        <property name="dataSource" ref="dataSource"/> &lt;!&ndash;数据库数据源&ndash;&gt;
        &lt;!&ndash;<property name="createTableOnStartup" value="true"/>&ndash;&gt; &lt;!&ndash;createTableOnStartup属性是当项目启动时,springSecurity创建表存储remember me相关信息,第二次启动时要注释这个属性&ndash;&gt;
    </bean>-->

</beans>

三、实现主页面菜单显示

1. 将 dwz 文件夹中的 index.html 页面拷贝到自定义项目目录 main 中,修改为 jsp页面,如下图:

2. 修改 index.jsp 页面代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>百炼成神管理系统</title>

    <link href="../dwz/themes/default/style.css" rel="stylesheet" type="text/css" media="screen"/>
    <link href="../dwz/themes/css/core.css" rel="stylesheet" type="text/css" media="screen"/>
    <link href="../dwz/themes/css/print.css" rel="stylesheet" type="text/css" media="print"/>
    <link href="../dwz/uploadify/css/uploadify.css" rel="stylesheet" type="text/css" media="screen"/>
    <!--[if IE]>
    <link href="../dwz/themes/css/ieHack.css" rel="stylesheet" type="text/css" media="screen"/>
    <![endif]-->

    <!--[if lt IE 9]><script src="../dwz/js/speedup.js" type="text/javascript"></script><script src="../dwz/js/jquery-1.12.4.js" type="text/javascript"></script><![endif]-->
    <!--[if gte IE 9]><!--><script src="../dwz/js/jquery-3.4.1.js" type="text/javascript"></script><!--<![endif]-->

    <script src="../dwz/js/jquery.cookie.js" type="text/javascript"></script>
    <script src="../dwz/js/jquery.validate.js" type="text/javascript"></script>
    <!--<script src="js/jquery.bgiframe.js" type="text/javascript"></script>-->
    <script src="../dwz/xheditor/xheditor-1.2.2.min.js" type="text/javascript"></script>
    <script src="../dwz/xheditor/xheditor_lang/zh-cn.js" type="text/javascript"></script>
    <script src="../dwz/uploadify/scripts/jquery.uploadify.js" type="text/javascript"></script>

    <script type="text/javascript" src="../dwz/chart/echarts.min.js"></script>

    <script src="../dwz/js/dwz.core.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.util.date.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.validate.method.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.barDrag.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.drag.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.tree.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.accordion.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.ui.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.theme.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.switchEnv.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.alertMsg.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.contextmenu.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.navTab.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.tab.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.resize.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.dialog.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.dialogDrag.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.sortDrag.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.cssTable.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.stable.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.taskBar.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.ajax.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.pagination.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.database.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.selectedLoad.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.datepicker.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.effects.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.panel.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.checkbox.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.history.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.combox.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.file.js" type="text/javascript"></script>
    <script src="../dwz/js/dwz.print.js" type="text/javascript"></script>

    <!-- 可以用dwz.min.js替换前面全部dwz.*.js (注意:替换时下面dwz.regional.zh.js还需要引入)
    <script src="bin/dwz.min.js" type="text/javascript"></script>
    -->
    <script src="../dwz/js/dwz.regional.zh.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function(){
            DWZ.init("../dwz/dwz.frag.xml", {
                loginUrl:"../dwz/login_dialog.html", loginTitle:"登录",	// 弹出登录对话框
//		loginUrl:"login.html",	// 跳到登录页面
                statusCode:{ok:200, error:300, timeout:301}, //【可选】
                pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //【可选】
                keys: {statusCode:"statusCode", message:"message"}, //【可选】
                ui:{hideMode:'offsets'}, //【可选】hideMode:navTab组件切换的隐藏方式,支持的值有’display’,’offsets’负数偏移位置的值,默认值为’display’
                debug:false,	// 调试模式 【true|false】
                callback:function(){
                    initEnv();
                    $("#themeList").theme({themeBase:"themes"}); // themeBase 相对于index页面的主题base路径
                }
            });
        });

    </script>

</head>

<body>
<div id="layout">
    <div id="header">
        <div class="headerNav">
            <a class="logo" href="#">标志</a>
            <ul class="nav">
                <li id="switchEnvBox"><a href="javascript:">(<span>北京</span>)切换城市</a>
                    <ul>
                        <li><a href="../dwz/sidebar_1.html">北京</a></li>
                        <li><a href="../dwz/sidebar_2.html">上海</a></li>
                        <li><a href="../dwz/sidebar_2.html">南京</a></li>
                        <li><a href="../dwz/sidebar_2.html">深圳</a></li>
                        <li><a href="../dwz/sidebar_2.html">广州</a></li>
                        <li><a href="../dwz/sidebar_2.html">天津</a></li>
                        <li><a href="../dwz/sidebar_2.html">杭州</a></li>
                    </ul>
                </li>
                <li><a href="../dwz/changepwd.html" target="dialog" rel="changepwd" width="600">设置</a></li>
                <li><a href="<c:url value='/logout'/>">退出系统</a></li>

            </ul>
            <ul class="themeList" id="themeList">
                <li theme="default"><div class="selected">蓝色</div></li>
                <li theme="green"><div>绿色</div></li>
                <!--<li theme="red"><div>红色</div></li>-->
                <li theme="purple"><div>紫色</div></li>
                <li theme="silver"><div>银色</div></li>
                <li theme="azure"><div>天蓝</div></li>
            </ul>
        </div>

        <!-- navMenu -->

    </div>

    <div id="leftside">
        <div id="sidebar_s">
            <div class="collapse">
                <div class="toggleCollapse"><div></div></div>
            </div>
        </div>
        <div id="sidebar">
            <div class="toggleCollapse"><h2>主菜单界面</h2><div>收缩</div></div>

            <div class="accordion" fillSpace="sidebar">
                <div class="accordionHeader">
                    <h2><span>Folder</span>导航列表</h2>
                </div>
                <div class="accordionContent">

                    <ul class="tree treeFolder">
                    <!-- 菜单开始 -->
                        <c:choose>
                            <c:when test="${listMenu.size()>0}">
                                    <c:forEach var="lstMenu" items="${listMenu}" varStatus="status">
                                        <c:if test="${lstMenu.parentId eq 10000}">
                                            <li><a href="${lstMenu.url}" target="navTab">${lstMenu.name}</a>

                                                <c:forEach var="menuChild" items="${listMenu}">
                                                    <c:if test="${menuChild.parentId eq lstMenu.id}">
                                                        <ul>
                                                            <li><a href="${menuChild.url}" target="navTab" rel="page1" fresh="false">${menuChild.name}</a></li>
                                                        </ul>
                                                    </c:if>
                                                </c:forEach>
                                            </li>
                                        </c:if>
                                    </c:forEach>
                            </c:when>
                            <c:otherwise>
                                <p>没有查询到菜单列表!</p>
                            </c:otherwise>
                        </c:choose>
                    <!-- 菜单结束 -->
                    </ul>
                </div>
            </div>
        </div>
    </div>
    <div id="container">
        <div id="navTab" class="tabsPage">
            <div class="tabsPageHeader">
                <div class="tabsPageHeaderContent"><!-- 显示左右控制时添加 class="tabsPageHeaderMargin" -->
                    <ul class="navTab-tab">
                        <li tabid="main" class="main"><a href="javascript:;"><span><span class="home_icon">我的主页</span></span></a></li>
                    </ul>
                </div>
                <div class="tabsLeft">left</div><!-- 禁用只需要添加一个样式 class="tabsLeft tabsLeftDisabled" -->
                <div class="tabsRight">right</div><!-- 禁用只需要添加一个样式 class="tabsRight tabsRightDisabled" -->
                <div class="tabsMore">more</div>
            </div>
            <ul class="tabsMoreList">
                <li><a href="javascript:;">我的主页</a></li>
            </ul>
            <div class="navTab-panel tabsPageContent layoutBox">
                <div class="page unitBox">

                    <div class="pageFormContent" layoutH="80" style="margin-right:230px">

                    </div>

<%--                    <div style="width:230px;position: absolute;top:60px;right:0" layoutH="80">
                        <iframe width="100%" height="430" class="share_self" frameborder="0" scrolling="no" src="//widget.weibo.com/weiboshow/index.php?width=0&height=430&fansRow=2&ptype=1&skin=1&isTitle=0&noborder=1&isWeibo=1&isFans=0&uid=1739071261&verifier=c683dfe7"></iframe>
                    </div>--%>
                </div>

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

</div>

<div id="footer">Copyright &copy; 2020 <a href="demo_page2.html" target="dialog">DWZ团队</a> 京ICP备15053290号-2</div>

</body>
</html>

主要引入JSP页面需要的标签库,修改所有dwz静态资源的访问路径。其它用不到的代码直接删除掉即可,如下图:

到此基本的主页修改完成,现在我们来动态显示后台请求到的菜单。将index.jsp页面的菜单部分多余代码删除,然后替换为下图代码:

动态菜单必须通过后台请求查询得到,所以此时我们修改spring-security.xml文件中登录成功后的处理类MyAuthenticationSuccessHandler 的逻辑,即保存登录用户信息后重定向到Controller的./system/index请求,代码如下:

另:注释掉spring-security.xml文件中/system/index请求路径的放行配置,即需要身份认证成功才能访问。

package com.wqbr.wqdemotwo.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wqbr.wqdemotwo.domain.SysUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Service;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 登录成功后的处理类
 * @author lv
 * @date 2024年1月16日
 */
@Service
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    // new 一个 jackson 的 对象
    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 此方法会在登录成功后进行回调
     *
     * @param authentication:表示认证成功后的信息
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        System.out.println("********* onAuthenticationSuccess");
        HttpSession session = request.getSession();
        System.out.println("session对象:"+session);
        System.out.println("----session.getId():"+session.getId());
        System.out.println("*****session.isNew():"+session.isNew());
        try {
            SysUser user = (SysUser) authentication.getPrincipal();
            session.setAttribute("loginInfo", user);
            response.sendRedirect("./system/index"); //重定向到Controller中指定的路径
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

​​​​​​​SystemController类中的index方法代码修改如下(即./system/index请求的方法):

    @RequestMapping(path = "/index")
    public ModelAndView index(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        System.out.println("session对象:" + session);
        System.out.println("----session.getId():" + session.getId());
        System.out.println("*****session.isNew():" + session.isNew());
        System.out.println("index 页面进入......");

        ModelAndView model = new ModelAndView("main/index");
        SysUser user = (SysUser) authentication.getPrincipal();
        String username = user.getUsername();
        if (username != null) {
            List<Menus> listMenu = new ArrayList<>();
            List<SysPermission> pList = systemService.findPermissionByUsername(username);
            System.out.println("=-----=大小为:" + pList.size());
            for (SysPermission permission : pList) {
                if (permission.getResource_type().equals("menu")) {
                    Menus menu = new Menus();
                    menu.setId(Long.parseLong(permission.getId()));
                    menu.setName(permission.getName());
                    menu.setParentId(Long.parseLong(permission.getParent_id()));
                    menu.setParentIds(Long.parseLong(permission.getParent_ids()));
                    menu.setUrl(permission.getUrl());
                    listMenu.add(menu);
                }
            }
            model.addObject("listMenu", listMenu);
        }
        return model;
    }

spring-security认证登录成功后获取菜单资源的实现可具体参考前言提到的第二篇文章。

到此已经可以实现登录后获取主页左边的动态菜单显示了,运行项目登录后显示效果如下:

好了,此文章的码字就到此结束了,再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA中Vue的安装和使用【window10】

一.准备工作 Vue是前端开发框架。搭建框架&#xff0c;首先要搭建环境。搭建Vue的环境工具&#xff1a;node.js&#xff08;JavaScript的运行环境&#xff09;&#xff0c;然后再用nodejs里面的npm&#xff08;包管理和分发工具&#xff09;来安装依赖包。二.安装node.js 下载…

【办公类-22-07】周计划系列(2)“主题知识” (2024年调整版本)

作品展示 调用原来的主题知识素材&#xff0c;制作下学期的19周的主题知识word 背景需求&#xff1a; 开学了&#xff0c;继续做周计划系列&#xff0c;在原有基础上&#xff0c;进行进一步代码优化 【办公类-22-02】周计划系列&#xff08;2&#xff09;-生成“主题知识”&…

【Android】View 与 ViewGroup

View 是 Android 所有控件的基类&#xff0c;我们平常所用的 TextView 和 ImageView 都是继承自 View 的&#xff0c;源码如下&#xff1a; public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {... }public class ImageView extends View {.…

升级加薪聊绩效过程中,如果我觉得自己受到了老板“不公正”的对待,该如何“怼”回去?...

老板与员工谈绩效 今天分享的主题是「职场的向上管理」 什么是向上管理&#xff1f; 向上管理是一种有自主意识的方法 通过与你的老板在目标上达成共识&#xff0c;并最终用这个目标满足你、你的老板、你的组织的最大利益 向上管理与你的老板无关&#xff0c;老板都没得选的&am…

Java JDK 下载和配置

Java JDK 下载 下载网址&#xff1a;https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html jdk文件夹的目录介绍 bin: 主要存放的是Java的编译器、解析器等工具。 jre&#xff1a;Java runtime environment, Java 运行时环境。 jre/bin:Java平台…

RuntimeError: CUDNN_STATUS_EXECUTION_FAILED

问题描述&#xff1a; 运行代码时候报错&#xff1a; 原因&#xff1a;pytorch与cuda版本不对&#xff0c;需要重新安装。不过我在复现代码的时候一般是要求特定的环境&#xff0c;不然会有其他错误&#xff0c;所以选择其他解决办法。 解决方案&#xff1a; 在train.py开头…

【图论】【堆优化的单源路径】LCP 20. 快速公交

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 LCP 20. 快速公交 小扣打算去秋日市集&#xff0c;由于游客较多&#xff0c;小扣的移动速度受到了人流影响&#xff1a; 小扣从 x 号站点移动至 x 1 号站点需要花费的时间为 inc&#xff1b; 小扣从 x 号站…

MySQL--索引结构

索引-索引结构 1. 概述2. 二叉树3. B-Tree4. BTree5. Hash 1. 概述 MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引擎有不同的索引结构&#xff0c;主要包含以下几种&#xff1a; 上述是MySQL中所支持的所有的索引结构&#xff0c;下面展示不同的存储引擎对于索引…

如何连接ACL认证的Redis

点击上方蓝字关注我 应用程序连接开启了ACL认证的Redis时与原先的方式有差别&#xff0c;本文介绍几种连接开启ACL认证的Redis的Redis的方法。 对于RedisACL认证相关内容&#xff0c;可以参考历史文章&#xff1a; Redis权限管理体系(一&#xff09;&#xff1a;客户端名及用户…

计算机网络-网络互联

文章目录 网络互联网络互联方法LAN-LAN&#xff1a;网桥及其互连原理使用网桥实现LAN-LAN使用交换机扩展局域网使用路由器连接局域网 LAN-WANWAN-WAN路由选择算法非自适应路由选择算法自适应路由选择算法广播路由选择算法&#xff1a;分层路由选择算法 网络互联 网络互联是指利…

设备树详解

设备树(Device Tree)基本概念及作用 设备树(Device Tree)基本概念 在内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录,对内核而言这些platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的…

神经网络系列---分类度量

文章目录 分类度量混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff1a;二分类问题二分类代码多分类问题多分类宏平均法:多分类代码多分类微平均法&#xff1a; 准确率&#xff08;Accuracy&#xff09;&#xff1a;精确率&#xff08;Precision&#xff09;&#xf…

EasyRecovery2024免费不要钱的电脑数据恢复软件下载

EasyRecovery 2024易恢复软件在数据恢复方面的表现评价&#xff0c;EasyRecovery 2024易恢复软件在数据恢复领域享有良好的声誉&#xff0c;它提供了全面的功能&#xff0c;易于使用的界面以及可靠的数据恢复效果。以下是对该软件在数据恢复方面的详细评价&#xff1a; EasyRec…

03|JOIN关联查询优化

1. mysql关联算法 1.1 嵌套循环连接 Nested-Loop Join(NLJ) 算法 先去t2表&#xff08;驱动表&#xff09;拿一行数据,然后去t1表&#xff08;被驱动表&#xff09;做关联, 关联之后把结果集存下来最后返回. 1.2 基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法 1.把 t…

森歌深化体育营销战略,揭晓2024奥运新代言人,携手共创影响力奇迹

2024年&#xff0c;奥运龙年的春节将将过去&#xff0c;各大高端品牌便纷纷开始激烈博弈。森歌有备而来&#xff01;布局早&#xff0c;积累深&#xff0c;以其深入骨髓的体育情怀和独具匠心的品牌策略&#xff0c;成为厨电行业的佼佼者。2月27日-2月28日&#xff0c;森歌将在杭…

电子器件系列64:稳压二极管ZM4728A

C143062_稳压二极管_ZM4728A-GS08_规格书_WJ481159 稳压管可以用于信号线路的旁路&#xff0c;用于过滤高频信号&#xff1f; 这种电路叫做限幅电路 从集成电路Al的①脚输出信号通过Rl加到集成电路A2的①脚。当集成电路Al的①脚输出信号幅度没有超过VD1稳压值时&#xff0c;这…

HDL FPGA 学习 - Avlon 总线,从端口传输、主端口传输,单周期、可变周期传输

目录 1.1 Avlon 总线 定制 外设 IP 核的框架 从端口传输 从端口信号类型 从端口传输模式列举 基本单周期读写传输 固定等待周期的读写传输 可变等待周期的读写传输&#xff08;推荐&#xff09; 具有建立时间和保持时间读写传输 主端口传输 主端口信号类型 主端口传…

Day04-流程控制语句_循环结构(while,do...while,关键字continue,关键字break,循环嵌套)

文章目录 Day04- 循环结构学习目标1 while循环2 do...while循环4 循环语句的区别5 关键字continue6 关键字break7 循环嵌套案例1&#xff1a;打印5行直角三角形案例2&#xff1a;break结束当层循环 Day04- 循环结构 学习目标 理解for语句的格式和执行流程 随机数公式 理解…

MES管理系统生产过程控制的核心要素

MES&#xff08;制造执行系统&#xff09;是为优化制造业生产过程和管理而设计的软件系统&#xff0c;其核心要素包括&#xff1a; 工单管理&#xff1a;工单管理是MES系统最基本的功能之一&#xff0c;它可以跟踪和管理各种类型的工单&#xff0c;如生产工单、维修工单和质量…

IO进程线程复习:进程线程、通信

1.进程的创建 #include<myhead.h>int main(int argc, const char *argv[]) {printf("hello world\n");//父进程执行的内容int num520;//在父进程中定义的变量pid_t pidfork();//创建子进程if(pid>0){while(1){printf("我是父进程&#xff0c;num%d\n&…