基于 Spring Boot 博客系统开发(五)

基于 Spring Boot 博客系统开发(五)

本系统是简易的个人博客系统开发,为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。🌿🌿🌿
基于 Spring Boot 博客系统开发(四)👈👈

登录实现

本文使用拦截器(Interceptor)来实现登录功能。拦截器是Spring MVC提供的一种机制,它允许你在请求处理之前或之后执行一些逻辑,比如检查用户是否已登录。

1、创建拦截器类

首先,创建一个实现了HandlerInterceptor接口的类。在这个类中,你可以重写preHandle方法来执行登录检查。LoginInterceptor.java

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();Object loginUser = session.getAttribute("loginUser");if(loginUser == null){response.sendRedirect("/login");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

2、注册拦截器

接下来,你需要在Spring MVC的配置中注册这个拦截器。如果你使用的是Java配置,可以通过实现WebMvcConfigurer接口来完成。LoginInterceptor.java

import cn.qvtu.web.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class LoginConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);registration.addPathPatterns("/admin/**"); // 拦截/admin下的所有路径registration.excludePathPatterns(// 排除特定路径"/login");}}

3、创建登录控制器

这里需要一个密码加密的依赖 Spring Security Core

 		<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>5.7.6</version></dependency>

登录控制器代码:LoginController.java

import cn.qvtu.web.domain.User;
import cn.qvtu.web.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;@Controller
@Slf4j
public class LoginController {@Autowiredprivate IUserService userService;@GetMapping("/login")public String login(){return "client/login";}@PostMapping("/login")public String formLogin(String username, String password, HttpServletRequest request) {if(StringUtils.isBlank(username) || StringUtils.isBlank(password)){return "redirect:/login?error";}QueryWrapper<User> query = new QueryWrapper<>();query.eq("username",username);User user = userService.getOne(query);BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();String encode = encoder.encode(password);if(!encoder.matches(password,user.getPassword())){return "redirect:/login?error";}request.getSession().setAttribute("loginUser",user);log.info("登录成功:"+username);return "redirect:/";}@RequestMapping ("/logout")public String logout(HttpServletRequest request) {HttpSession session = request.getSession();session.invalidate();log.info("注销成功:");return "redirect:/";}}

登录前端代码: login.html
当账号或密码错误提示,${param.error} 从URL中获取参数。

<div class="am-u-lg-3 am-u-md-6 am-u-sm-8 am-u-sm-centered log-content"><h1 class="log-title am-animation-slide-top" style="color: black;">~欢迎登录博客~</h1><br><div style="color: red" th:if="${param.error}">账号或密码错误!</div><form class="am-form" id="loginForm" action="/login" method="post"><div class="am-input-group am-radius am-animation-slide-left"><input type="text" class="am-radius" placeholder="用户名" name="username" /><span class="am-input-group-label log-icon am-radius"><i class="am-icon-user am-icon-sm am-icon-fw"></i></span></div><br><div class="am-input-group am-animation-slide-left log-animation-delay"><input type="password" class="am-form-field am-radius log-input" placeholder="密码" name="password" /><span class="am-input-group-label log-icon am-radius"><i class="am-icon-lock am-icon-sm am-icon-fw"></i></span></div><div style="padding-top: 10px;"><input type="submit" value="登录"class="am-btn am-btn-primary am-btn-block am-btn-lg am-radius am-animation-slide-bottom log-animation-delay" /></div></form></div>

账号或密码错误提示效果:
在这里插入图片描述

测试登录账号:admin
测试登录密码:123456

4、后台首页控制器

登录成功可以访问后台首页,控制器AdminController.java。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/admin")
public class AdminController {@RequestMapping("/")public String home(){return "admin/index";}}

5、前台首页 header

修改 header 登录、退出、后台管理的访问 URL,这里需要工具类 LoginUtils 处理登录和退出是否显示。

LoginUtils.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;@Component
public class LoginUtils {@Autowiredpublic HttpServletRequest request;public boolean isLogin(){Object loginUser = request.getSession().getAttribute("loginUser");System.out.println(loginUser);return loginUser!=null;}}

include.html

<div th:fragment="header" ><!--[if lt IE 8]><div class="browsehappy" role="dialog">当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/" target="_blank">升级你的浏览器</a>。</div><![endif]--><header id="header" class="header bg-white"><div class="navbar-container"><a href="/static" class="navbar-logo">CrazyStone个人博客小站</a><div class="navbar-menu"><a class="header-info" th:if="${@loginUtils.isLogin()}" href="/logout" >退出</a><a class="header-info" th:if="${!@loginUtils.isLogin()}" href="/login" >登录</a><a  class="header-info" href="/admin/">后台管理</a></div><div class="navbar-search" onclick=""><span class="icon-search"></span><form role="search" onsubmit="return false;"><span class="search-box"><input type="text" id="search-inp" class="input" placeholder="搜索..." maxlength="30"autocomplete="off"/></span></form></div></div></header>
</div>

6、实现效果:

登录成功显示:
在这里插入图片描述
没有登录显示:
在这里插入图片描述

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

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

相关文章

计算机视觉(CV)是什么以及应用场景

计算机视觉&#xff08;Computer Vision, CV&#xff09;是指计算机利用摄像机、图像传感器等设备获取图像或视频&#xff0c;并对它们进行处理和分析&#xff0c;以实现对图像或视频中的物体、场景以及其属性的理解和识别的技术领域。CV的目标是让计算机能够像人类一样“看”和…

go-mysql-transfer 同步数据到es

同步数据需要注意的事项 前提条件 1 要同步的mysql 表必须包含主键 2 mysql binlog 必须是row 模式 3 不支持程序运行过程中修改表结构 4 要赋予连接mysql 账号的权限 reload, replication super 权限 如果是root 权限则不需要 安装 go-mysql-transfer ​ git clone…

Python IDE(集成开发环境)有很多,以下是一些常用的选项

Python IDE&#xff08;集成开发环境&#xff09;有很多&#xff0c;以下是一些常用的选项&#xff1a; PyCharm&#xff1a;PyCharm被认为是普及率和使用率最高的一款Python IDE集成开发环境工具。它功能强大&#xff0c;支持多种开发模式&#xff0c;如科学计算、Web开发、数…

【leetcode】缓存淘汰策略题目总结

146. LRU 缓存 我们使用了一个双向链表cache来存储数据&#xff0c;同时使用一个哈希表hash_map来映射键和链表节点的迭代器。当调用get(key)函数时&#xff0c;我们首先检查hash_map中是否存在该key&#xff0c;如果存在则将之前位置移到链表头部并返回值&#xff1b;当调用p…

每日OJ题_DFS爆搜深搜回溯剪枝⑧_力扣980. 不同路径 III

目录 力扣980. 不同路径 III 解析代码 力扣980. 不同路径 III 980. 不同路径 III 难度 困难 在二维网格 grid 上&#xff0c;有 4 种类型的方格&#xff1a; 1 表示起始方格。且只有一个起始方格。2 表示结束方格&#xff0c;且只有一个结束方格。0 表示我们可以走过的空…

React 第十五章 Ref

React ref 是 React 中一个用于访问组件中 DOM 元素或者类实例的方式。它允许我们直接操作 DOM&#xff0c;而不需要通过 state 或 props 来更新组件。 过时 API&#xff1a;String 类型的 Refs 在最最早期的时候&#xff0c;React 中 Ref 的用法非常简单&#xff0c;类似于 …

Docker consul 的容器服务更新与发现

目录 一. consul 的相关知识 1 什么是注册与发现 2. 什么是 consul 3. zookeeper 和 consul 的区别 二. consul 部署 1. consul 服务器 2. registrator 服务器 三. consul-template 1. consul-template 的作用 2. consul-template 的具体部署运用 2.1 准备 templa…

Deep Learning Part Five RNNLM的学习和评价-24.4.30

准备好RNNLM所需要的层&#xff0c;我们现在来实现RNNLM&#xff0c;并对其进行训练&#xff0c;然后再评价一下它的结果的。 5.5.1 RNNLM的实现 这里我们将RNNLM使用的网络实现为SimpleRnnlm类&#xff0c;其层结构如下&#xff1a; 如图 5-30 所示&#xff0c;SimpleRnnlm …

设计模式: 工厂模式

工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 工厂模式属于创建型…

我的毕业实习经历

我的毕业实习经历 前言求职之路成为社畜重获自由结语 前言 这篇博客原本我想以实习生找工作踩坑指南&#xff1a;我的毕业实习经历为文章标题的&#xff0c;原因是跟我前面发布的一篇博客《实习生找工作踩坑指南&#xff1a;租房篇》做一个呼应收尾&#xff0c;奈何标题略显臃肿…

【Oracle】常用命令汇总

本文基于黑马程序员文档做的二次总结&#xff0c;如有侵权&#xff0c;请联系本人删除。 文章目录 字段定义创建表空间创建用户用户赋权创建表表增加字段表更改字段类型表字段重命名表删除字段删除表 记录的增删改表插入记录表修改记录表删除记录 导入导出数据库导出数据库全部…

MongoDB聚合运算符:$sum

MongoDB聚合运算符&#xff1a;$sum 文章目录 MongoDB聚合运算符&#xff1a;$sum语法使用返回的数据类型非数值或缺失字段的处理数组操作数 举例应用于$group阶段应用于$project阶段应用于$setWindowFields阶段 $sum聚合运算符返回数值的合计值&#xff0c;计算式 $sum会忽略…

免费分享一套SpringBoot+Vue在线考试系统(优质版),帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue在线考试系统(优质版)&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue在线考试系统(优质版) Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue在线考试系统(优质版) Java毕…

C++奇迹之旅:C++内存管理的机制(进阶篇)

文章目录 &#x1f4dd;new和delete操作自定义类型&#x1f320; operator new与operator delete函数&#x1f309;operator new与operator delete函数 &#x1f320;new和delete的实现原理&#x1f309;内置类型&#x1f309;自定义类型 &#x1f320;定位new表达式(placement…

KCF算法的优缺点是什么

KCF算法&#xff08;Kernelized Correlation Filters&#xff09;是一种用于目标跟踪的算法&#xff0c;它结合了核技巧和相关滤波器的思想&#xff0c;可以在视频中跟踪运动目标。以下是KCF算法的主要优缺点&#xff1a; 优点&#xff1a; 速度快&#xff1a;KCF算法使用离散…

Python 全栈体系【四阶】(三十八)

第五章 深度学习 八、目标检测 3. 目标检测模型 3.2 YOLO 系列 3.2.1 YOLOv1&#xff08;2016&#xff09; 3.2.1.1 基本思想 YOLO&#xff08;You Only Look Once &#xff09;是继 RCNN&#xff0c;fast-RCNN 和 faster-RCNN 之后&#xff0c;Ross Girshick 针对 DL 目…

【牛客网】值周

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 差分。 因为l<100000000,所以数组开1e8。 唯一需要注意的点就是前面给b[0]单独赋值为1&#xff08;因为如果在循环中给b[0]赋值&…

Json高效处理方法

一、参考我之前的博客,Delphi可以很方便的把类和结构体转换成JSON数据,但是数据量大了,就会非常之慢,1万条数据需要20秒左右。如果引用Serializers单元,那么100万数据只需要4秒左右,每秒处理20万+,速度还是很快的。 二、写一个简单的类  TPeople = class private …

Docker Compose如何安装

Docker Compose的安装通常依赖于你的操作系统。以下是在不同操作系统中安装Docker Compose的方法&#xff1a; Linux 系统 //下载最新版本的Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.5.1/docker-compose-$(uname -s)-$(un…

算法训练营第十天 | LeetCode 232 用栈实现队列、LeetCode 225 用队列实现栈

栈的实现有顺序表和链式表两种&#xff0c;也就是数组和链表实现。 其中抽象栈类的私有成员函数有operator的重载函数和stack的构造函数&#xff0c;为了保护栈的构造和拷贝被保护。公有成员函数有Stack()&#xff0c;~Stack()&#xff0c;clear()&#xff0c;push()&#xff…