首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【尚筹网】四、管理员登录

【尚筹网】四、管理员登录

作者头像
用户11332765
发布2024-11-26 12:10:55
发布2024-11-26 12:10:55
3160
举报
文章被收录于专栏:编程编程

目标

识别操作系统的人的身份,控制它的行为

思路

image-20241124142847454
image-20241124142847454

代码

创建工具方法执行 MD5 加密

代码语言:javascript
复制
/**
	 * 对明文字符串进行 md5 加密
	 * @param source 明文字符串
	 * @return 加密结果
	 */
public static String md5(String source) {
    // 1.判断 source 是否有效
    if (source == null || source.length() == 0) {
        // 2.如果不是有效的字符串抛出异常
        throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
    }
    try {
        // 3.获取 MessageDigest 对象
        String algorithm = "md5";

        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

        // 4.将明文字符串转换为 byte 数组
        byte[] bytes = source.getBytes();

        // 5.调用 MessageDigest 对象的 digest() 方法,完成加密,返回加密后的 byte 数组
        byte[] output = messageDigest.digest(bytes);

        // 6.创建 BigInteger 对象
        int signum = 1;
        BigInteger bigInteger = new BigInteger(signum, output);

        // 7.按照 16 进制将 BigInteger 的值转化为字符串
        int radix = 16;
        String encoded = bigInteger.toString(radix).toUpperCase();
        return encoded;

    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

创建登录失败异常类

image-20241124143123515
image-20241124143123515
代码语言:javascript
复制
package com.atguigu.crowd.exception;

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc : 登录失败后抛出的异常
 * @Time : 2024/11/23 22:50
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : LoginFailedException
 * @IDE : IntelliJ IDEA
 */
public class LoginFailedException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public LoginFailedException() {
       super();
    }

    public LoginFailedException(String message) {
       super(message);
    }

    public LoginFailedException(String message, Throwable cause) {
       super(message, cause);
    }

    public LoginFailedException(Throwable cause) {
       super(cause);
    }

    public LoginFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
       super(message, cause, enableSuppression, writableStackTrace);
    }
}

在异常处理类中增加登录失败异常的处理

image-20241124143341178
image-20241124143341178
代码语言:javascript
复制
@ExceptionHandler(LoginFailedException.class)
public ModelAndView resolveLoginFailedException(
    LoginFailedException  exception,
    HttpServletRequest request,
    HttpServletResponse response) throws IOException {
    String viewName = "admin-login";
    return commonResolve(viewName, exception, request, response);
}

在登录页面显示异常消息

image-20241124144145723
image-20241124144145723
代码语言:javascript
复制
<h2 class="form-signin-heading">
    <i class="glyphicon glyphicon-log-in"></i>
    管理员登录
</h2>
<p>${requestScope.exception.message}</p>

handler 方法

image-20241124145418849
image-20241124145418849
代码语言:javascript
复制
package com.atguigu.crowd.mvc.handler;

import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.service.api.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc :
 * @Time : 2024/11/24 14:42
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : AdminHandler
 * @IDE : IntelliJ IDEA
 */
@Controller
public class AdminHandler {

    @Autowired
    private AdminService adminService;

    @RequestMapping("/admin/do/login.html")
    public String doLogin(
          @RequestParam("loginAcct") String loginAcct,
          @RequestParam("userPswd") String userPswd,
          HttpSession session
    ){
       // 调用Service方法执行登录检查
       // 这个方法如果能返回 Admin 对象说明登录成功,如果账号密码不正确则会抛出异常
       Admin admin = adminService.getAdminByLoginAcct(loginAcct, userPswd);
       // 将登录成功返回的 Admin 对象存入 Session 域
       session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, admin);
       return "admin-main";
    }
}

service 方法

image-20241124151212175
image-20241124151212175
代码语言:javascript
复制
package com.atguigu.crowd.service.impl;

import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.entity.AdminExample;
import com.atguigu.crowd.exception.LoginFailedException;
import com.atguigu.crowd.mapper.AdminMapper;
import com.atguigu.crowd.service.api.AdminService;
import com.atguigu.crowd.util.CrowdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc :
 * @Time : 2024/11/17 21:03
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : AdminServiceImpl
 * @IDE : IntelliJ IDEA
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Override
    public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
       // 1.根据登录账号查询 Admin 对象
       // ①.创建 AdminExample 对象
       AdminExample adminExample = new AdminExample();
       // ②.创建 Criteria 对象
       AdminExample.Criteria criteria = adminExample.createCriteria();
       // ③.将条件封装到 Criteria 对象中
       criteria.andLoginAcctEqualTo(loginAcct);
       // ④.调用 MyBatis 的动态 SQL 底层代码
       List<Admin> lists = adminMapper.selectByExample(adminExample);
       // 2.判断 Admin 对象是否为 null
       if (lists == null || lists.size() == 0) {
          throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
       }
       if (lists.size() > 1) {
          throw new RuntimeException(CrowdConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);
       }
       Admin admin = lists.get(0);
       // 3.如果 Admin 对象为 null,则抛出 LoginFailedException 异常
       if (admin == null) {
          throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
       }
       // 4.如果 Admin 对象不为 null,则将 Admin 对象的 userPswd 属性取出
       String userPswdDB = admin.getUserPswd();
       // 5.将表单提交的明文密码 userPswd 进行 Md5 加密
       String userPswdForm = CrowdUtil.md5(userPswd);
       // 6.将加密后的密码与数据库中的密码比较
       if (!Objects.equals(userPswdDB, userPswdForm)) {
          // 7.如果比较结果不一致,则抛出 LoginFailedException 异常
          throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
       }
       // 8.如果比较结果一致,则返回 Admin 对象
       return admin;
    }
}

创建登录成功的临时主页面

image-20241124151411780
image-20241124151411780
代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
       <title>Title</title>
    </head>
    <body>
       <h1>临时主页面</h1>
       ${sessionScope.loginAdmin.userName}
    </body>
</html>

测试

image-20241124221054820
image-20241124221054820
image-20241124221351315
image-20241124221351315

将临时主页面替换为真正的主页面

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
    <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1">
       <meta name="description" content="">
       <meta name="author" content="">
       <base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/" />
       <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
       <link rel="stylesheet" href="css/font-awesome.min.css">
       <link rel="stylesheet" href="css/main.css">
       <script src="jquery/jquery-2.1.1.min.js"></script>
       <script src="bootstrap/js/bootstrap.min.js"></script>
       <script src="script/docs.min.js"></script>
       <script type="text/javascript">
          $(function () {
             $(".list-group-item").click(function(){
                if ( $(this).find("ul") ) {
                   $(this).toggleClass("tree-closed");
                   if ( $(this).hasClass("tree-closed") ) {
                      $("ul", this).hide("fast");
                   } else {
                      $("ul", this).show("fast");
                   }
                }
             });
          });
       </script>
       <style>
          .tree li {
             list-style-type: none;
             cursor:pointer;
          }
          .tree-closed {
             height : 40px;
          }
          .tree-expanded {
             height : auto;
          }
       </style>
    </head>

    <body>

       <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
          <div class="container-fluid">
             <div class="navbar-header">
                <div><a class="navbar-brand" style="font-size:32px;" href="#">众筹平台 - 控制面板</a></div>
             </div>
             <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav navbar-right">
                   <li style="padding-top:8px;">
                      <div class="btn-group">
                         <button type="button" class="btn btn-default btn-success dropdown-toggle" data-toggle="dropdown">
                            <i class="glyphicon glyphicon-user"></i> ${sessionScope.loginAdmin.userName} <span class="caret"></span>
                         </button>
                         <ul class="dropdown-menu" role="menu">
                            <li><a href="#"><i class="glyphicon glyphicon-cog"></i> 个人设置</a></li>
                            <li><a href="#"><i class="glyphicon glyphicon-comment"></i> 消息</a></li>
                            <li class="divider"></li>
                            <li><a href="index.html"><i class="glyphicon glyphicon-off"></i> 退出系统</a></li>
                         </ul>
                      </div>
                   </li>
                   <li style="margin-left:10px;padding-top:8px;">
                      <button type="button" class="btn btn-default btn-danger">
                         <span class="glyphicon glyphicon-question-sign"></span> 帮助
                      </button>
                   </li>
                </ul>
                <form class="navbar-form navbar-right">
                   <input type="text" class="form-control" placeholder="查询">
                </form>
             </div>
          </div>
       </nav>
       <div class="container-fluid">
          <div class="row">
             <div class="col-sm-3 col-md-2 sidebar">
                <div class="tree">
                   <ul style="padding-left:0px;" class="list-group">
                      <li class="list-group-item tree-closed" >
                         <a href="main.html"><i class="glyphicon glyphicon-dashboard"></i> 控制面板</a>
                      </li>
                      <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon glyphicon-tasks"></i> 权限管理 <span class="badge" style="float:right">3</span></span>
                         <ul style="margin-top:10px;display:none;">
                            <li style="height:30px;">
                               <a href="user.html"><i class="glyphicon glyphicon-user"></i> 用户维护</a>
                            </li>
                            <li style="height:30px;">
                               <a href="role.html"><i class="glyphicon glyphicon-king"></i> 角色维护</a>
                            </li>
                            <li style="height:30px;">
                               <a href="permission.html"><i class="glyphicon glyphicon-lock"></i> 菜单维护</a>
                            </li>
                         </ul>
                      </li>
                      <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon-ok"></i> 业务审核 <span class="badge" style="float:right">3</span></span>
                         <ul style="margin-top:10px;display:none;">
                            <li style="height:30px;">
                               <a href="auth_cert.html"><i class="glyphicon glyphicon-check"></i> 实名认证审核</a>
                            </li>
                            <li style="height:30px;">
                               <a href="auth_adv.html"><i class="glyphicon glyphicon-check"></i> 广告审核</a>
                            </li>
                            <li style="height:30px;">
                               <a href="auth_project.html"><i class="glyphicon glyphicon-check"></i> 项目审核</a>
                            </li>
                         </ul>
                      </li>
                      <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon-th-large"></i> 业务管理 <span class="badge" style="float:right">7</span></span>
                         <ul style="margin-top:10px;display:none;">
                            <li style="height:30px;">
                               <a href="cert.html"><i class="glyphicon glyphicon-picture"></i> 资质维护</a>
                            </li>
                            <li style="height:30px;">
                               <a href="type.html"><i class="glyphicon glyphicon-equalizer"></i> 分类管理</a>
                            </li>
                            <li style="height:30px;">
                               <a href="process.html"><i class="glyphicon glyphicon-random"></i> 流程管理</a>
                            </li>
                            <li style="height:30px;">
                               <a href="advertisement.html"><i class="glyphicon glyphicon-hdd"></i> 广告管理</a>
                            </li>
                            <li style="height:30px;">
                               <a href="message.html"><i class="glyphicon glyphicon-comment"></i> 消息模板</a>
                            </li>
                            <li style="height:30px;">
                               <a href="project_type.html"><i class="glyphicon glyphicon-list"></i> 项目分类</a>
                            </li>
                            <li style="height:30px;">
                               <a href="tag.html"><i class="glyphicon glyphicon-tags"></i> 项目标签</a>
                            </li>
                         </ul>
                      </li>
                      <li class="list-group-item tree-closed" >
                         <a href="param.html"><i class="glyphicon glyphicon-list-alt"></i> 参数管理</a>
                      </li>
                   </ul>
                </div>
             </div>
             <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
                <h1 class="page-header">控制面板</h1>

                <div class="row placeholders">
                   <div class="col-xs-6 col-sm-3 placeholder">
                      <img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="Generic placeholder thumbnail">
                      <h4>Label</h4>
                      <span class="text-muted">Something else</span>
                   </div>
                   <div class="col-xs-6 col-sm-3 placeholder">
                      <img data-src="holder.js/200x200/auto/vine" class="img-responsive" alt="Generic placeholder thumbnail">
                      <h4>Label</h4>
                      <span class="text-muted">Something else</span>
                   </div>
                   <div class="col-xs-6 col-sm-3 placeholder">
                      <img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="Generic placeholder thumbnail">
                      <h4>Label</h4>
                      <span class="text-muted">Something else</span>
                   </div>
                   <div class="col-xs-6 col-sm-3 placeholder">
                      <img data-src="holder.js/200x200/auto/vine" class="img-responsive" alt="Generic placeholder thumbnail">
                      <h4>Label</h4>
                      <span class="text-muted">Something else</span>
                   </div>
                </div>
             </div>
          </div>
       </div>

    </body>
</html>

将登录成功后跳转到后台主页面的方式改为转发

为了避免跳转到后台主页面再刷新浏览器导致重复提交登录表单,需要重定向到目标页面。

handler 方法
image-20241124222751929
image-20241124222751929
代码语言:javascript
复制
package com.atguigu.crowd.mvc.handler;

import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.service.api.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc :
 * @Time : 2024/11/24 22:02
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : AdminHandler
 * @IDE : IntelliJ IDEA
 */
@Controller
public class AdminHandler {

    @Autowired
    private AdminService adminService;

    @RequestMapping("/admin/do/login.html")
    public String doLogin(
          @RequestParam("loginAcct") String loginAcct,
          @RequestParam("userPswd") String userPswd,
          HttpSession session
    ){
       // 调用Service方法执行登录检查
       // 这个方法如果能返回 Admin 对象说明登录成功,如果账号密码不正确则会抛出异常
       Admin admin = adminService.getAdminByLoginAcct(loginAcct, userPswd);
       // 将登录成功返回的 Admin 对象存入 Session 域
       session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, admin);
       return "redirect:/admin/to/main/page.html";
    }
}
配置跳转到后台主页面的 view-controller
image-20241124222957703
image-20241124222957703
代码语言:javascript
复制
<mvc:view-controller path="/admin/to/main/page.html" view-name="admin-main" />

退出登录

修改主页面
image-20241124223428649
image-20241124223428649
添加 handler 方法
代码语言:javascript
复制
@RequestMapping("/admin/do/logout.html")
public String doLogout(HttpSession session){
    // 强制 session 失效
    session.invalidate();
    return "redirect:/admin/to/login/page.html";
}

抽取后台主页面公共部分

include-head.jsp

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/" />
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="css/font-awesome.min.css">
    <link rel="stylesheet" href="css/main.css">
    <script src="jquery/jquery-2.1.1.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script src="script/docs.min.js"></script>
    <script src="layer/layer.js"></script>
    <script type="text/javascript">
       $(function () {
          $(".list-group-item").click(function(){
             if ( $(this).find("ul") ) {
                $(this).toggleClass("tree-closed");
                if ( $(this).hasClass("tree-closed") ) {
                   $("ul", this).hide("fast");
                } else {
                   $("ul", this).show("fast");
                }
             }
          });
       });
    </script>
    <style>
       .tree li {
          list-style-type: none;
          cursor:pointer;
       }
       .tree-closed {
          height : 40px;
       }
       .tree-expanded {
          height : auto;
       }
    </style>
</head>

include-nav.jsp

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container-fluid">
       <div class="navbar-header">
          <div><a class="navbar-brand" style="font-size:32px;" href="#">众筹平台 - 控制面板</a></div>
       </div>
       <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
             <li style="padding-top:8px;">
                <div class="btn-group">
                   <button type="button" class="btn btn-default btn-success dropdown-toggle"
                           data-toggle="dropdown">
                      <i class="glyphicon glyphicon-user"></i> ${sessionScope.loginAdmin.userName} <span
                         class="caret"></span>
                   </button>
                   <ul class="dropdown-menu" role="menu">
                      <li><a href="#"><i class="glyphicon glyphicon-cog"></i> 个人设置</a></li>
                      <li><a href="#"><i class="glyphicon glyphicon-comment"></i> 消息</a></li>
                      <li class="divider"></li>
                      <li><a href="admin/do/logout.html"><i class="glyphicon glyphicon-off"></i> 退出系统</a>
                      </li>
                   </ul>
                </div>
             </li>
             <li style="margin-left:10px;padding-top:8px;">
                <button type="button" class="btn btn-default btn-danger">
                   <span class="glyphicon glyphicon-question-sign"></span> 帮助
                </button>
             </li>
          </ul>
          <form class="navbar-form navbar-right">
             <input type="text" class="form-control" placeholder="查询">
          </form>
       </div>
    </div>
</nav>

include-sidebar.jsp

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div class="col-sm-3 col-md-2 sidebar">
    <div class="tree">
       <ul style="padding-left:0px;" class="list-group">
          <li class="list-group-item tree-closed">
             <a href="main.html"><i class="glyphicon glyphicon-dashboard"></i> 控制面板</a>
          </li>
          <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon glyphicon-tasks"></i> 权限管理 <span class="badge"
                                                                                                  style="float:right">3</span></span>
             <ul style="margin-top:10px;display:none;">
                <li style="height:30px;">
                   <a href="user.html"><i class="glyphicon glyphicon-user"></i> 用户维护</a>
                </li>
                <li style="height:30px;">
                   <a href="role.html"><i class="glyphicon glyphicon-king"></i> 角色维护</a>
                </li>
                <li style="height:30px;">
                   <a href="permission.html"><i class="glyphicon glyphicon-lock"></i> 菜单维护</a>
                </li>
             </ul>
          </li>
          <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon-ok"></i> 业务审核 <span class="badge"
                                                                                     style="float:right">3</span></span>
             <ul style="margin-top:10px;display:none;">
                <li style="height:30px;">
                   <a href="auth_cert.html"><i class="glyphicon glyphicon-check"></i> 实名认证审核</a>
                </li>
                <li style="height:30px;">
                   <a href="auth_adv.html"><i class="glyphicon glyphicon-check"></i> 广告审核</a>
                </li>
                <li style="height:30px;">
                   <a href="auth_project.html"><i class="glyphicon glyphicon-check"></i>
                      项目审核</a>
                </li>
             </ul>
          </li>
          <li class="list-group-item tree-closed">
                         <span><i class="glyphicon glyphicon-th-large"></i> 业务管理 <span class="badge"
                                                                                           style="float:right">7</span></span>
             <ul style="margin-top:10px;display:none;">
                <li style="height:30px;">
                   <a href="cert.html"><i class="glyphicon glyphicon-picture"></i> 资质维护</a>
                </li>
                <li style="height:30px;">
                   <a href="type.html"><i class="glyphicon glyphicon-equalizer"></i> 分类管理</a>
                </li>
                <li style="height:30px;">
                   <a href="process.html"><i class="glyphicon glyphicon-random"></i> 流程管理</a>
                </li>
                <li style="height:30px;">
                   <a href="advertisement.html"><i class="glyphicon glyphicon-hdd"></i>
                      广告管理</a>
                </li>
                <li style="height:30px;">
                   <a href="message.html"><i class="glyphicon glyphicon-comment"></i> 消息模板</a>
                </li>
                <li style="height:30px;">
                   <a href="project_type.html"><i class="glyphicon glyphicon-list"></i>
                      项目分类</a>
                </li>
                <li style="height:30px;">
                   <a href="tag.html"><i class="glyphicon glyphicon-tags"></i> 项目标签</a>
                </li>
             </ul>
          </li>
          <li class="list-group-item tree-closed">
             <a href="param.html"><i class="glyphicon glyphicon-list-alt"></i> 参数管理</a>
          </li>
       </ul>
    </div>
</div>

修改主页面

image-20241124225657659
image-20241124225657659

登录状态检查

目标

将部分资源保护起来,让没有登录的请求不能访问

思路

image-20241125211549286
image-20241125211549286

代码

创建自定义异常
image-20241125212702395
image-20241125212702395
代码语言:javascript
复制
package com.atguigu.crowd.exception;

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc : 表示用户没有登录就访问受保护资源的异常
 * @Time : 2024/11/25 21:24
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : AccessForbiddenException
 * @IDE : IntelliJ IDEA
 */
public class AccessForbiddenException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public AccessForbiddenException() {
    }

    public AccessForbiddenException(String message) {
       super(message);
    }

    public AccessForbiddenException(String message, Throwable cause) {
       super(message, cause);
    }

    public AccessForbiddenException(Throwable cause) {
       super(cause);
    }

    public AccessForbiddenException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
       super(message, cause, enableSuppression, writableStackTrace);
    }
}
创建拦截器类
image-20241125211756375
image-20241125211756375
代码语言:javascript
复制
package com.atguigu.crowd.mvc.interceptor;

import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.exception.AccessForbiddenException;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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

/**
 * Copyright (C) 2024 - 2024 Jasonakeke, Inc. All Rights Reserved
 *
 * @Desc :
 * @Time : 2024/11/25 21:17
 * @Author : Code_By_Jasonakeke
 * @Email : 2284037977@qq.com
 * @Class : LoginInterceptor
 * @IDE : IntelliJ IDEA
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       // 1.通过 request 对象获取 session 对象
       HttpSession session = request.getSession();
       // 2.尝试从 session 对象中获取 Admin 对象
       Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);
       // 3.判断 admin 对象是否为 null
       if (admin == null) {
          // 4.抛出异常
          throw new AccessForbiddenException(CrowdConstant.MESSAGE_ACCESS_FORBIDDEN);
       }
       // 5.如果 admin 对象不为 null,则返回 true,继续向下执行
       return true;
    }

}
注册拦截器类
image-20241125213348549
image-20241125213348549
代码语言:javascript
复制
<!-- 注册拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
       <!-- mvc:mapping 配置要拦截的资源 -->
       <!-- /*  对应一层路径 -->
       <!-- /** 对应多层路径 -->
       <mvc:mapping path="/**" />
       <!-- mvc:exclude-mapping 配置不拦截的资源 -->
       <mvc:exclude-mapping path="/admin/to/login/page.html" />
       <mvc:exclude-mapping path="/admin/do/login.html" />
       <mvc:exclude-mapping path="/admin/do/logout.html" />
       <!-- 配置拦截器类 -->
       <bean class="com.atguigu.crowd.mvc.interceptor.LoginInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

完善配套的异常映射

基于 XML 的异常映射
image-20241125215308210
image-20241125215308210
代码语言:javascript
复制
<!-- 配置基于XML的异常映射 -->
<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 配置异常类型和具体视图页面的对应关系 -->
    <property name="exceptionMappings">
       <props>
          <!-- key属性指定异常的全类名   标签体中写对应的视图(去掉前后缀) -->
          <prop key="java.lang.Exception">system-error</prop>
          <prop key="com.atguigu.crowd.exception.AccessForbiddenException">admin-login</prop>
       </props>
    </property>
</bean>
基于注解的异常映射
image-20241125215704772
image-20241125215704772
代码语言:javascript
复制
@ExceptionHandler(value = AccessForbiddenException.class)
public ModelAndView resolveAccessForbiddenException(AccessForbiddenException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
    String viewName = "admin-login";
    return commonResolve(viewName, exception, request, response);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目标
  • 思路
  • 代码
    • 创建工具方法执行 MD5 加密
    • 创建登录失败异常类
    • 在异常处理类中增加登录失败异常的处理
    • 在登录页面显示异常消息
    • handler 方法
    • service 方法
    • 创建登录成功的临时主页面
    • 测试
    • 将临时主页面替换为真正的主页面
    • 将登录成功后跳转到后台主页面的方式改为转发
      • handler 方法
      • 配置跳转到后台主页面的 view-controller
    • 退出登录
      • 修改主页面
      • 添加 handler 方法
  • 抽取后台主页面公共部分
    • include-head.jsp
    • include-nav.jsp
    • include-sidebar.jsp
    • 修改主页面
  • 登录状态检查
    • 目标
    • 思路
    • 代码
      • 创建自定义异常
      • 创建拦截器类
      • 注册拦截器类
    • 完善配套的异常映射
      • 基于 XML 的异常映射
      • 基于注解的异常映射
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档