Spring学习笔记(八)基于Spring mvc技术的简单后台登录验证系统

一、需求分析

本项目主要是对用户登录状态的验证,只有登录成功的用户才可以访问系统中的资源。为了保证后台系统的页面不能被客户直接请求访问,本案例中所有的页面都存放在项目的WEB-INF 文件夹下,客户需要访问相关页面时,需要在服务器端转发到相关页面。如果没有登录系统而直接访问系统首页,拦截器会将请求拦截,并转发到登录页面,同时在登录页面中给出提示信息。如果用户登录时提交的用户名或密码错误,也会在登录页面给出相应的提示信息。当已登录的用户在系统页面中单击“退出”链接时,系统同样会回到登录页面。

二、实现需求

本项目未涉及到与数据库的交互,只分析web层操作,对登录所需的验证部分用固定值进行验证操作

Controller层完成业务需求

页面跳转

登录功能

退出功能

Interceptor拦截器完成

拦截器校验登录状态

后台系统登录验证流程图

三、参考代码 

创建一个Spring MVC工程,导入相关依赖

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>

    <groupId>org.example</groupId>
    <artifactId>SpringMVCdemo01</artifactId>
    <version>1.0-SNAPSHOT</version>
<!--   声明当前是一个maven的web工程-->
    <packaging>war</packaging>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
        <!--        Spring的核心基本包 ioc相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.26</version>
        </dependency>
<!--        服务器相关配置-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        <!--依赖范围-->
            <scope>provided</scope>
        </dependency>
        <!--        jdbc相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.26</version>
        </dependency>
        <!--        spring事务相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.26</version>
        </dependency>
        <!--        springAOP相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>5.2.8.RELEASE</version>

        </dependency>
        <!-- Spring MVC相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.8.RELEASE</version> <!-- 版本号根据您的实际情况进行调整 -->
        </dependency>
<!--        jackson依赖,用于JSON数据绑定,因为它各个方面表现均非常优秀,是世界最流行、最好的JSON库-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.5</version>
        </dependency>

    </dependencies>
    <build>
    <!--          加入tomcat插件-->
    <plugins>

    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>

        <configuration>
<!--            解决get请求乱码问题-->
            <uriEncoding>utf-8</uriEncoding>
            <port>8080</port> <!-- 访问端口-->
         <!--虚拟项目名-->
            <path>/SpringMVCdemo01</path>    <!-- 访问路径,一般就是你的项目名注意前面有个‘/’-->
        </configuration>
    </plugin>
    </plugins>
    </build>
</project>

1、编写绑定数据的pojo的user类

创建User类,在User类中,声明username和password属性,分别表示用户名和密码,并定义了每个属性的getter/setter方法 

package com.yx.pojo;
//POJO用于数据绑定
public class User {
//    实体的属性名应该和页面提交的参数一致
    private String username;//用户名
    private String password;//用户密码

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

2、在cotroller层实现定义跳转到系统首页、跳转到登录页面、跳转到订单信息页面、用户登录和用户退出五个方法 

package com.yx.controller;
import com.yx.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;

@Controller
public class UserController {
    //    页面跳转
    @RequestMapping("/main")
    public String main(){
        return "main";//采用视图解析器进行操作
    }
    //    页面跳转
    @RequestMapping("/toLogin")
    public String toLogin(){

        return "login";//采用视图解析器进行操作
    }
    //    页面跳转
    @RequestMapping("/orderinfo")
    public String orderinfo(){
        return "orderinfo";//采用视图解析器进行操作
    }
//    登入
    @RequestMapping("/login")
    public String login(User user, Model model,HttpSession session){
     //判断用户名和密码
        String username = user.getUsername();
        String password=user.getPassword();
        if (username !=null&&"zhangsan".equals(username)&&password!=null&&"123456".equals(password)){
            //登入成功,跳转到首页并且保存用户信息
//            一定要保存信息要不然会无法跳转到查看页
            session.setAttribute("user",user);
            return "main";
        }else {
            //登入失败,给出失败信息,跳转到登入界面
            model.addAttribute("msg","用户名或密码错误");
            return "login";
        }

    }
//    退出成功需要跳转到登录页面
    @RequestMapping("/logout")
    public String logout(HttpSession session){
        //清空session,销毁当前登入的用户的信息
        session.invalidate();
        return "login";
    }
}

3、创建拦截器LoginInterceptor,在重写的preHandle()方法中对请求进行拦截。LoginInterceptor类中部分代码 

package com.yx.interceptor;
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;

//拦截器校验登入状态
public class Logininterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//       针对登入和跳转到登入页面的请求进行放行
        String requestURI=request.getRequestURI();
        if(requestURI.indexOf("/login")>0||requestURI.indexOf("/toLogin")>0){
         //直接放行
            return true;
        }
//        其他请求需要做登录权限拦截判断
        HttpSession session=request.getSession();
        if (session.getAttribute("user")!=null) { return true; }

                // 其他情况都直接跳转到登录页面
        request.setAttribute("msg", "您还没有登录,请先登录!");
       //此处视图解析器不生效,使用的时Javaweb原生技术
        request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request,response);
        return false;
    }
//以下暂时不做操作
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

4、在Spring MVC配置文件spring-mvc.xml中配置包扫描、注解驱动、视图解析器、拦截器和静态资源访问映射

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tool="http://www.springframework.org/schema/mvc" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--      注解扫描-->
    <context:component-scan base-package="com.yx.controller"/>
  <!--    视图解析器-->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <!--       后缀-->
       <property name="suffix" value=".jsp"/>
     <!--       前缀-->
       <property name="prefix" value="/WEB-INF/pages/"/>
   </bean>

    <!-- 装载转换器:支持JSON的-->
  <tool:annotation-driven></tool:annotation-driven>
    <!--释放静态资源,配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 如:jq的访问-->
<!--    <mvc:resources mapping="/js/**" location="/js/" />-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
  <mvc:interceptors>


<!--    配置局部单个的拦截器-->
<!--      <mvc:interceptor>-->
<!--&lt;!&ndash;          这里只针对demo1方法执行时进行了拦截操作&ndash;&gt;-->
<!--          <tool:mapping path="/demo1"/>-->
<!--          <bean class="com.yx.interceptor.CustomInterceptor"></bean>-->
<!--      </mvc:interceptor>-->
<!--    配置 MyIntrceptor拦截器 -->
<!--    <bean class="com.yx.interceptor.MyIntrceptor"></bean>-->
      <!--    配置 Logininterceptor拦截器 -->
      <bean class="com.yx.interceptor.Logininterceptor"></bean>
  </mvc:interceptors>
</beans>

5、在pages文件夹中创建名称为main.jsp文件作为系统首页。在main.jsp中展示当前登录的用户名、用户退出页面的超链接和订单信息页面的超链接

注意:jsp代码的位置在webapp/WEB-INF/pages里面

 

Main.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2024/3/10
  Time: 17:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<html><head><title>后台系统</title></head>
<body>
<li>您好:${ user.username }</li>
<li> <a href="${ pageContext.request.contextPath }/logout">退出</a></li>
<li><a href="${ pageContext.request.contextPath }/orderinfo">订单信息</a></li>
</body></html>

Login.jsp

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2024/3/10
  Time: 16:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登入</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login"
      method="post">
    <div>${msg}</div>
    用户名:<input type="text" name="username" /><br />
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password" /><br />
    <input type="submit" value="登录"/>
</form>
</body>
</html>

orderinfo.jsp

 

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2024/3/10
  Time: 17:01
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><title>订单信息</title></head><body>
您好:${ user.username }
<a href="${ pageContext.request.contextPath }/logout">退出</a>
<table border="1" width="80%">
    <tr align="center"><td colspan="2" >${ user.username }订单id:D001</td></tr>
    <tr align="center"><td>商品Id</td><td>商品名称</td></tr>
    <tr align="center"><td>P001</td><td>九江鱼块</td></tr>
    <tr align="center"><td>P002</td><td>南昌拌粉</td></tr>
</table>
</body></html>

6、 效果

 未登录时:

输入用户名:zhangsan,密码:12345(错误密码)提示用户名或密码有误

输入用户名:zhangsan,密码:123456(正确密码)

 

点击订单信息

 

点击退出(回到登录页)

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[BJDCTF2020]----EzPHP

文章目录 pass-1pass-2pass-3pass-4pass-5pass-6pass-7 查看题目&#xff0c;右键源代码&#xff0c;发现GFXEIM3YFZYGQ4A&#xff0c;base64解码&#xff1a;1nD3x.php 访问1nD3x.php&#xff0c;代码审计&#xff0c;一步一步分析 <?php highlight_file(__FILE__); error…

HarmonyOS通过 axios发送HTTP请求

我之前的文章 HarmonyOS 发送http网络请求 那么今天 我们就来说说axios 这个第三方工具 想必所有的前端开发者都不会陌生 axios 本身也属于 HTTP请求 所以鸿蒙开发中也支持它 但首先 想在HarmonyOS中 使用第三方工具库 就要先下载安装 ohpm 具体可以参考我的文章 HarmonyOS 下…

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】探究二叉树的奥秘

目录 1 -> 树的概念及结构 1.1 -> 树的概念 1.2 -> 树的相关概念 1.3 -> 树的表示 1.4 -> 树在实际中的运用(表示文件系统的目录树结构) 2 -> 二叉树概念及结构 2.1 -> 二叉树的概念 2.2 -> 现实中的二叉树 2.3 -> 特殊的二叉树 2.4 ->…

SpringBoot项目没有启动按键

问题一&#xff1a; pom文件正常&#xff0c;但是springboot包报红&#xff0c;同时Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found报红 解决办法&#xff1a; 无法识别使用哪个版本的 spring-boot-maven-plugin 包 <build><plugins>&…

【深度学习笔记】7_2 梯度下降和随机梯度下降

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 7.2 梯度下降和随机梯度下降 在本节中&#xff0c;我们将介绍梯度下降&#xff08;gradient descent&#xff09;的工作原理。虽然梯度…

2024年【G2电站锅炉司炉】考试题及G2电站锅炉司炉证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【G2电站锅炉司炉】考试题及G2电站锅炉司炉证考试&#xff0c;包含G2电站锅炉司炉考试题答案和解析及G2电站锅炉司炉证考试练习。安全生产模拟考试一点通结合国家G2电站锅炉司炉考试最新大纲及G2电站锅炉司炉考…

std::function模板类性能问题

背景 题目&#xff1a;最近发现记忆化搜索真的很好用&#xff0c;于是在做力扣上记忆化搜索相关的题目时&#xff0c;用这种方法重做了一下买卖股票问题。 问题来源 在写递归代码的时候&#xff0c;我学习了一种匿名函数的写法&#xff0c;直接在函数体内写function<int(…

Learn OpenGL 06 坐标系统

概述 局部坐标是对象相对于局部原点的坐标&#xff0c;也是物体起始的坐标。下一步是将局部坐标变换为世界空间坐标&#xff0c;世界空间坐标是处于一个更大的空间范围的。这些坐标相对于世界的全局原点&#xff0c;它们会和其它物体一起相对于世界的原点进行摆放。接下来我们…

Java - 探究Java优雅退出的两种机制

文章目录 概述Java优雅停机_ ShutdownHook 机制步骤Code Java优雅停机_ 信号量机制SignalHandler 工作原理使用步骤Linux支持的信号量根据操作系统选择信号量Code 注意事项 概述 在Linux上通过kill -9 pid方式强制终止进程的副作用&#xff0c;这种方式虽然简单高效&#xff0…

使用Windows API实现一个简单的串口助手

使用Windows API实现一个简单的串口助手 目录 使用window API开发一个具有字符串收发功能的串口助手 开发环境串口设备相关的API步骤实现代码收发测试图 使用window API开发一个具有字符串收发功能的串口助手 开发环境 Visual Studio 2015 串口设备相关的API CreateFile 参…

【MySQL | 第四篇】区分SQL语句的书写和执行顺序

文章目录 4.区分SQL语句的书写和执行顺序4.1书写顺序4.2执行顺序4.3总结4.4扩充&#xff1a;辨别having与where的异同&#xff1f;4.5聚合查询 4.区分SQL语句的书写和执行顺序 注意&#xff1a;SQL 语句的书写顺序与执行顺序不是一致的 4.1书写顺序 SELECT <字段名> …

Nwatch在stm32上的移植

目录 Nwatch在stm32上的移植前言实验目的移植game1_task任务相关代码片段结果本文中使用的工程 Nwatch在stm32上的移植 本文目标&#xff1a;Nwatch在stm32上的移植 按照本文的描述&#xff0c;应该可以跑通实验并举一反三。 先决条件&#xff1a;装有编译和集成的开发环境&…

不允许你不知道Python作用域

在Python中&#xff0c;变量的作用域限制非常重要。根据作用域分类&#xff0c;有局部、全局、函数和内建作用域。无作用域限制的变量可以在分支语句和循环中定义&#xff0c;并在外部直接访问。不同的作用域决定了变量的可访问范围&#xff0c;访问权限取决于变量的位置。 1.…

力扣中档题:旋转链表

思路&#xff1a;将链表数据放到数组中&#xff0c;将数组旋转&#xff0c;然后再赋值给链表 struct ListNode* rotateRight(struct ListNode* head, int k) {if(headNULL){return NULL;}int count0;struct ListNode*goodhead;while(good){count;goodgood->next;}int round…

解锁网络数据:入门级IP代理使用教程

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

10 vector的使用

文档介绍 文档介绍 1.vector是表示可变大小数组的容器 2.就像数组一样&#xff0c;vecotr也采用的连续存储空间来存储元素&#xff0c;也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;大小是可以动态改变的&#xff…

【Web】浅聊Java反序列化之C3P0——URLClassLoader利用

目录 前言 C3P0介绍 回归本源——序列化的条件 利用链 利用链分析 入口——PoolBackedDataSourceBase#readObject 拨云见日——PoolBackedDataSourceBase#writeObject 综合分析 EXP 前言 这条链最让我眼前一亮的就是对Serializable接口的有无进行了一个玩&#xff0c…

权限管理系统-0.2.0

三、菜单管理接口 3.1 创建SysMenu类及相关类 首先创建sys_menu表&#xff1a; CREATE TABLE sys_menu (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 编号,parent_id bigint(20) NOT NULL DEFAULT 0 COMMENT 所属上级,name varchar(20) NOT NULL DEFAULT COMMENT 名称,…

【脚本玩漆黑的魅影】寂雨镇全自动练级

文章目录 原理全部代码 原理 老样子。 治疗路径&#xff0c;练级路径。 def zhi_liao(): # 去治疗walk(RIGHT)walk(RIGHT)press(UP, 0.4)for i in [1, 2, 3, 4]:press(A)for i in [1, 2, 3, 4]:press(B)press(DOWN, 0.4)press(LEFT) def chu_qu(): # 右逛c.press(B)press(…

力扣同类题:重排链表

很明显做过一次 class Solution { public:void reorderList(ListNode* head) {if(!head||!head->next)return;ListNode *fasthead,*lowhead;ListNode *prenullptr,*curnullptr,*nextnullptr;while(fast->next!nullptr){fastfast->next;if(fast->next)fastfast->…