SpringBoot+MyBatis+MySQL电脑商城项目(项目环境搭建和用户注册登录功能)

目录

第一阶段:

1.项目分析

2.项目的环境

3.搭建项目

第二阶段 用户注册功能实现 

1.创建用户表

2.创建用户实体类基类 

3.创建用户实体类

4.注册-持久层

4.1规划需要执行的SQL语句

4.2设计接口和抽象方法

4.3编写映射

5.注册-业务层

5.1 规划异常

5.2 设计接口和抽象方法

5.3 密码加密处理 

6.注册-控制层

6.1 创建响应(统一返回类)

 6.2 设计请求

6.3 处理请求

​编辑

6.4 控制层优化设计

7.注册-前端页面

 第三阶段 用户登录功能

1.登录-持久层

1.1规划需要执行的SQL语句

1.2接口设计和方法

2.登录-业务层

2.1 规划异常

2.2 设计业务层接口和抽象方法

2.3 抽象方法实现

3.登录-控制层

3.1 处理异常

3.2 设计请求

3.3 处理请求

4.登录-前端页面

用户会话Session

 登录拦截器


第一阶段:

1.项目分析

1.项目功能:登录、注册、热销商品、用户管理(密码、个人信息、头像、收货地址)、购物车(展示、增加、删除)、订单模块

2.开发顺序:注册、登录、用户管理、购物车、商品、订单模块

3.某一个模块的开发:

  • 持久层开发:依据前端页面的设置规划相关的SQL语句,以及进行配置
  • 业务层开发:核心功能控制、业务操作以及异常的处理
  • 控制层开发:接受请求、处理响应
  • 前端开发:(不从零开始,但会写一些简单的页面代码)JS、Query、AJAX连接后台

2.项目的环境

1.JDK:1.8以上版本

2.maven:3.8.4版本

3.数据库:MySQL 版本:8.0.27

4.开发平台: idea开发

3.搭建项目

1.项目名称: stores 

2.结构: com.chenxi.stores(下面为基础jar包)

3.资源文件目录:/resources/(static、templates)

4.单元测试:test. com.chenxi.store

5.数据库基本配置 

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/store?useUnicode=true&characterEncoding=utf-8&serverTimeZone=Asia/Shanghai
    username: root
    password: Yj0717

6.创建一个store数据库

7.测试运行

编写一个测试方法,测试springboot能否正常运行和数据库的正常连接

如若dataSource自动注入爆红,更换为@Resource

@Resource
DataSource dataSource;

@Test
    void getConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }

 若控制台输入如下,则运行正常,SpringBoot默认Hikar数据连接池。

8.访问项目静态资源,看能否正常加载,将静态资源复制到static目录下

注意!idea对JS代码兼容性较差,编写了js代码但有时不能去正常加载

1.idea缓存清理

2.clear - install

3.rebuild项目

4.重启idea

重新启动项目,打开浏览器访问静态资源localhost:8080/web/login.html 

 

无法找到,则按照上述步骤 。

1.清理maven

2.重新安装

 关闭浏览器,重新访问,访问成功!(原因为没有加载到maven的target目录下)

第二阶段 用户注册功能实现 

1.创建用户表

CREATE TABLE t_user (
	uid INT AUTO_INCREMENT COMMENT '用户id',
	username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',
	PASSWORD CHAR(32) NOT NULL COMMENT '密码',
	salt CHAR(36) COMMENT '盐值',
	phone VARCHAR(20) COMMENT '电话号码',
	email VARCHAR(30) COMMENT '电子邮箱',
	gender INT COMMENT '性别:0-女,1-男',
	avatar VARCHAR(50) COMMENT '头像',
	is_delete INT COMMENT '是否删除:0-未删除,1-已删除',
	created_user VARCHAR(20) COMMENT '日志-创建人',
	created_time DATETIME COMMENT '日志-创建时间',
	modified_user VARCHAR(20) COMMENT '日志-最后修改执行人',
	modified_time DATETIME COMMENT '日志-最后修改时间',
	PRIMARY KEY (uid)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

2.创建用户实体类基类 

导入了lombok依赖

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseEntity implements Serializable {

    private String createdUser;
    private Date createdTime;
    private String modifiedUser;
    private String modifiedTime;
}

3.创建用户实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class User extends BaseEntity{
    private Integer uid;
    private String username;
    private String password;
    private String salt;
    private String phone;
    private String email;
    private Integer gender;
    private String avatar;
    private Integer isDelete;
}

4.注册-持久层

通过mybatis来操作数据库。即mybatis开发流程

4.1规划需要执行的SQL语句

1.用户的注册功能,即插入用户信息,一条插入语句

insert into t_user (username,password) values (?,?)

2.因设计表时将username设置成为了唯一属性,则不需担心相同用户名,可以写一条查询语句在控制层判断用户名是否被注册。

select * from t_user where username=?

4.2设计接口和抽象方法

定义mapper映射文件,因为注册功能,则为UserMapper,其中定义上述两个接口方法

package com.chenxi.stores.entity.mapper;

import com.chenxi.stores.entity.User;

public interface UserMapper {

    //插入用户数据,返回影响的行数
    Integer insertUser(User user);

    //根据用户名来查询用户数据,未找到则返回null
    User findUserByUserName(String name);

}

为方便后续不用每个mapper上写@Mapper注解,我们选择在启动类上加入 

@MapperScan("com.chenxi.stores.mapper")
@SpringBootApplication
@MapperScan("com.chenxi.stores.mapper")
public class StoresApplication {

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

}

4.3编写映射

定义xml映射文件,属于资源文件,放置在Resource目录下,创建一个mapper文件夹,存放mapper映射文件,也方便在yml配置文件中统一注册,映射文件头部可以在mybatis官网中找到。mybatis – MyBatis 3 | 简介

 为方便开发,在yml配置类中开启驼峰命名的转化和别名的设置

mybatis:
  type-aliases-package: com.chenxi.stores.entity
  configuration:
    map-underscore-to-camel-case: true

原本以为,开启了驼峰命名之后便可直接使用resultType加别名直接转化,但后面测试会报错,原因就在于驼峰命名转化是在查询等语句是将数据库的例如user_name转化为userName对对象赋值,而在插入时是无法进行userName转user_name的操作的,所以我们需要用到ResultMap结果集映射。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace属性:用于指定映射文件与哪个接口进行映射,需要指定接口的文件路径,需完整路径-->
<mapper namespace="com.chenxi.stores.mapper.UserMapper">
    
    
    <!--type:表示对哪个类进行结果集映射-->
    <resultMap id="UserEntityMap" type="User">
        <!--主键无论如何都不能省略-->
        <id column="uid" property="uid"></id>
        <!--column:数据库中的字段名     property:类中的字段名-->
        <result column="is_delete" property="isDelete"></result>
        <result column="created_user" property="createdUser"></result>
        <result column="created_time" property="createdTime"></result>
        <result column="modified_user" property="modifiedUser"></result>
        <result column="modified_time" property="modifiedTime"></result>
    </resultMap>
    
    <insert id="insertUser" parameterType="User">
        insert into store.t_user (
            username, password, salt, phone, email, gender, avatar, is_delete, created_user, created_time, modified_user, modified_time
        ) values (
            #{username}, #{password}, #{salt}, #{phone}, #{email}, #{gender}, #{avatar}, #{isDelete}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime}
        )
    </insert>
    
    <!--
        resultMap: 当表的资源与类的对象属性字段名字不一致时,用自定义结果集的映射规则
    -->
    <select id="findUserByUserName" resultMap="UserEntityMap">
        select * from t_user where username=#{username}
    </select>
    
    
</mapper>

4.4 单元测试(及时排查)

在test目录下创建mapper包,新建UserMapperTests,使用@Resource对UserMapper进行自动注入。

//@SpringBootTest 表示是一个测试类,不会随同代码打包发送
@SpringBootTest
//@RunWith 表示启动这个单元测试类,参数必须为SpringRunner的实例对象
//@RunWith(SpringRunner.class)
public class UserMapperTests {

    @Resource
    UserMapper userMapper;

    /**
     * 1.必须有@Test注解
     * 2.返回值必须为void
     * 3.参数列表不能指定类型
     * 4.修饰符必须为public
     */
    @Test
    public void MyTest() {
        User user = new User();
        user.setUsername("chenxi");
        user.setPassword("123");
        System.out.println(userMapper.insertUser(user));
    }

    @Test 
    public void findUserByName(){
        User chenxi = userMapper.findUserByUserName("chenxi");
        System.out.println(chenxi);
    }
}

5.注册-业务层

5.1 规划异常

1.定义一个ServiceException异常,继承RuntimeException,之后如有具体的异常可继承这个类并再自定义异常,即根据业务层不同的功能来详细定义具体的异常的类型,统一的去继承ServiceException类。

在service下创建两个包(ex:存放异常,impl存放继承接口的实现类)接口直接放在service目录

 

package com.chenxi.stores.service.ex;

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 业务层异常的基类
 */
//只有在运行时才有异常,顾继承RuntimeException。通过构造方法的重载抛出不同异常
public class ServiceException extends RuntimeException{
    public ServiceException() {
        super();
    }

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

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

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

    protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

2.用户名被占用异常。抛出UsernameDuplicateException异常

3.执行插入操作时,服务器、数据库宕机,抛出InsertException插入异常

5.2 设计接口和抽象方法

1.创建UserService接口,其中就是对mapper的调用

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 用户业务层接口
 */
public interface UserService {
    //插入用户数据,返回影响的行数
    Integer insertUser(User user);
}

 2.编写UserService实现类UserServiceImpl

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 用户业务层实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserMapper userMapper;

    @Override
    public Integer insertUser(User user) {
        User result = userMapper.findUserByUserName(user.getUsername());
        //如果用户名result不为空,则抛出被占用异常
        if (result != null) {
            throw new UsernameDuplicateException("用户名被占用!!");
        }
        //补全用户数据,如创建时间,和逻辑删除的值等等
        user.setIsDelete(0);
        user.setCreatedUser(user.getUsername() );
        user.setModifiedUser(user.getUsername());
        Date date = new Date();
        user.setCreatedTime(date);
        user.setModifiedTime(date);
        //执行注册插入功能
        Integer rows = userMapper.insertUser(user);
        if (rows != 1) {
            throw new InsertException("在注册过程中产生了未知的异常");
        }
        return rows;
    }
}

3.单元测试,创建步骤与之前雷同

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description UserMapper测试类
 */
//@SpringBootTest 表示是一个测试类,不会随同代码打包发送
@SpringBootTest
//@RunWith 表示启动这个单元测试类,参数必须为SpringRunner的实例对象
//@RunWith(SpringRunner.class)
public class UserServiceTests {
    @Resource
    UserService userService;

    @Test
    public void MyTest(){
        try {
            User user = new User();
            user.setUsername("yijiao");
            user.setPassword("456");
            Integer row = userService.insertUser(user);
            System.out.println(row);
        } catch (ServiceException e) {
            //获取异常的描述信息
            System.out.println(e.getMessage());;
        }
    }
}

 用户名被占用异常测试

5.3 密码加密处理 

1.密码加密处理的实现:md5算法,在UserServiceImpl编写一个加密方法,并在UserServiceImpl中实现加密。

//串 + password + 串) ---  进行加密,连续加载三次

//盐值 + password + 盐值 --- 盐值就是一个随机的字符串

        ...

        //加密算法
        //串 + password + 串) ---  进行加密,连续加载三次
        //盐值 + password + 盐值 --- 盐值就是一个随机的字符串
        String oldPassword = user.getPassword();
        //通过javaUtils工具类获取一个随机的盐值,一般为大写
        String salt = UUID.randomUUID().toString().toUpperCase();
        //该加密可以忽略用户密码的强度,但一定要记住保存盐值!!!
        String newPassword = getMd5Password(oldPassword, salt);
        user.setPassword(newPassword);

        ...


    public String getMd5Password(String password,String salt){
        for (int i = 0;i < 3; i++){
            password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()).toUpperCase();
        }
        return password;
    }

测试

6.注册-控制层

6.1 创建响应(统一返回类)

状态码、状态描述信息 、数据,这些信息封装在一个类中,作为返回值汉回给前端浏览器

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description Json格式的数据响应
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JsonResult<E> implements Serializable {
    //状态码
    private Integer state;
    //描述信息
    private String message;
    //数据类型,使用泛型定义,要在class上表明
    private E data;
}

 6.2 设计请求

依据当前的业务功能模块进行请求的设计。

请求路径: /users/reg

请求参数: User user

请求类型: POST

响应结果: JsonResult<void>

6.3 处理请求

创建UserController,我这使用的RestFul风格,注意加上注解和异常的抛出

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 用户控制器
 */
//表示该Controller下方法返回的为json数据响应给前端
@RestController
public class UserController {

    @Resource
    UserService userService;

    @RequestMapping("/users/reg/{username}/{password}")
    public JsonResult<Integer> reg(@PathVariable("username") String username,@PathVariable("password") String password){
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        //创建响应结果对象
        JsonResult<Integer> result = new JsonResult<>();
        try {
            Integer rows = userService.insertUser(user);
            result.setState(200);
            result.setMessage("用户注册成功!");
            result.setData(rows);
        } catch (UserDeclinedException e) {
            result.setState(400);
            result.setMessage("用户名被占用1");
        }catch (InsertException e){
            result.setState(500);
            result.setMessage("用户名注册异常");
        }
        return result;
    }
}

6.4 控制层优化设计

因为每一个异常都去捕获相对麻烦,抽离一个父类BaseController,去统一的处理异常 

/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 控制层基类,主要用来捕获异常
 */
public class BaseController {
//    成功的状态码
    public static final int OK = 200;

    //当前项目中产生的ServiceException异常会被统一的拦截到此方法中
    @ExceptionHandler(ServiceException.class)//用于处理统一抛出的异常
    public JsonResult<Void> handleException(Throwable e){
        JsonResult<Void> result = new JsonResult<>();
        if (e instanceof UsernameDuplicateException){
            result.setState(400);
            result.setMessage("用户名被占用!");
        }else if (e instanceof InsertException){
            result.setState(500);
            result.setMessage("用户名注册异常!");
        }
        return result;
    }
}
/**
 * @author chenxi
 * @Date 2022/10/8
 * @Description 用户控制器
 */
//表示该Controller下方法返回的为json数据响应给前端
@RestController
public class UserController extends BaseController {

    @Resource
    UserService userService;

    @RequestMapping("/users/reg/{username}/{password}")
    public JsonResult<Integer> reg(@PathVariable("username") String username,@PathVariable("password") String password){
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        //创建响应结果对象
        JsonResult<Integer> result = new JsonResult<>();
        Integer rows = userService.insertUser(user);
        result.setState(OK);
        result.setMessage("用户注册成功!");
        result.setData(rows);
        return result;
    }
}

一样可以抛出异常。 

7.注册-前端页面

1.在register.html中编写发送请求的方法,添加点击事件。

2.JQuery中封装了$.ajax函数,通过对象调用ajax函数,异步加载请求,实现局部刷新。 

3.ajax()使用方式。需要传递一个方法体作为方法的参数来使用,一对大括号称之为方法体。ajaxj接收多个参数,参数与参数之间要求使用","进行分割,每一组参数之间使用"∵"进行分割,参数的组成部分一个是参数的名称(不能随意的定义),语法结构:

$.ajax(i
    ur1: ”,
    type:,
    data: ""
    dataType: "".
    success : function( {
    },
    error : function( {
    }
});

下面是袁庭新老师项目实战中写的解析,非常的通俗易懂。

在register.html页面中body标签内部的最后,添加script标签用于编写JavaScript程序。请求的url中需 要添加项目的访问名称。因为更新了js代码,重复一下3.8中的操作

	<script type="text/javascript">
		// 1.监听按钮点击事件。
		$("#btn-reg").click(function () {
			//动态获取表单中的数据(不适用与数据量多的情况。)
			// let username = $("#username").val();
			// let password = $("password").val();
			console.log($("#form-reg").serialize())
			//发送ajax异步请求完成注册。
			$.ajax({
				url: "/users/reg",
				type: "POST",
				//序列化,将表单中控件的值自动拼接例如username=...&password=...
				data: $("#form-reg").serialize(),
				dataType: "JSON",
				success: function (json) {
					if (json.state == 200) {
						alert("注册成功!");
					} else {
						alert("注册失败!")
					}
				},
				error: function (xhr) {
					alert("注册时出现错误!" + xhr.status);
				}
			})
		})
	</script>

 完成后启动项目,打开浏览器访问http://localhost:8080/web/register.html页面并进行注册。

 注意!!!一定要将我前面使用的RestFul风格相关的去掉!!!!

 第三阶段 用户登录功能

当用户输入用户名和密码则将数据提交至后端查询验证,若验证成功则登跳转至系统首页index.html,跳转使用jquery完成

1.登录-持久层

1.1规划需要执行的SQL语句

根据用户名密码进行select查询,而我们在注册功能中已经实现了这个方法。

select * from t_user where username = ?

说明:如果在分析过程发现某个功能模块已经被开发完成,所以就可以省略当前的开发步骤,这个分析过程不能够省略。 

1.2接口设计和方法

不用重复开发。单元测试也是无需单独执行了。

2.登录-业务层

2.1 规划异常

1.用户名对应的密码错误,密码匹配失败的异常:PasswordNotMatchException异常,运行时异常,业务异常。  
⒉.用户名没有被找到的,抛出异常: UsernameNotFoundException。,运行时异常,业务异常。
3.异常的编写:

  • 业务层异常需要继承ServiceException异常类。
  • 在具体的异常类中定义构造方法(可以使用快捷键来生成,有5个构造方法)。

由于继承ServiceException实现方法就行,具体步骤和注册相同,就不贴上代码了

2.2 设计业务层接口和抽象方法

1.可以直接在UserService中编写抽象方法,login(String username,String password)

注意:返回类型不为空,为查询到的用户对象,方便后续跳转页面后进行复用(例如跳转首页后的用户信息获取)即将当前登录成功的用户数据以当前用户对象的形式进行返回。状态管理:可以将数据保仔仕cookie或者session中,可以避免重复度很高的数据多次频繁操作数据进行获取(用户名、用户id存放在session中,用户头像保存在cookie中)。

2.3 抽象方法实现

1.在实现类中实现抽象方法(具体作用写在注释中)

    @Override
    public User login(String username, String password) {
        //查询对象是否存在,没有则抛出异常
        User result = userMapper.findUserByUserName(username);
        //判断是不是被逻辑删除,即is_delete是否为1
        if (result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在!");
        }

        if (result == null) {
            throw new UsernameNotFoundException("用户数据不存在!");
        }
        //检测用户密码是否匹配
        String oldPassword = result.getPassword();
        //1.先获取用户加密之后的密码,即获取盐值
        String salt = result.getSalt();
        //2.将用户输入的密码用相同的算法进行加密,判断是否相同
        String newPassword = Md5Utils.getMd5Password(password, salt);
        if (newPassword.equals(oldPassword)) {
            throw new PasswordNotMatchException("用户密码错误!");
        }
        //将返回的user中冗余的字段去掉,在数据交互中,传输的数据大小越小性能越好!
        User user = new User();
        user.setUsername(result.getUsername());
        user.setUid(result.getUid());
        user.setAvatar(result.getAvatar());
        return user;
    }

2.单元测试

    @Test
    public void loginTest(){
        User chenxi = userService.login("chenxi", "456");
        System.out.println(chenxi);
    }

3.登录-控制层

3.1 处理异常

观察业务层会抛出哪些异常,在统一处理类中进行捕获处理,相同异常不需重复添加。

else if (e instanceof UsernameNotFoundException){
     result.setState(5001);
     result.setMessage("用户数据异常!");
}else if (e instanceof PasswordNotMatchException){
     result.setState(5002);
     result.setMessage("用户密码异常!");

3.2 设计请求

请求路径: /users/login

请求参数: String username, String password,HttpSession session

请求类型: POST

响应结果: JsonResult<User>

3.3 处理请求

    @RequestMapping("/users/login")
    public JsonResult<User> login(String username,String password){
        User user = userService.login(username, password);
        JsonResult<User> result = new JsonResult<>();
        result.setState(OK);
        result.setMessage("用户注册成功!");
        result.setData(user);
        return result;
    }

4.登录-前端页面

1.在login.html页面中依据前面所设置的请求来发送ajax请求。
 

<script type="text/javascript">
		$("#btn-login").click(function () {
			$.ajax({
				url: "/users/login",
				type: "POST",
				data: $("#form-login").serialize(),
				dataType: "JSON",
				success: function (json) {
					if (json.state == 200) {
						alert("登录成功!");
						location.href = "index.html"
					} else {
						alert("登录失败!");
					}
				},
				error: function (xhr) {
					alert("登录时产生的位置异常:" + xhr.message);
				}
			})
		})
	</script>

启动项目,访问http://localhost:8080/web/login.html,输入账号密码,成功访问首页!

用户会话Session

 session对象主要存在服务器端,可以用于保存服务器的临时数据的对象,所保存的数据可以在整个项目中都可以通过访问来获取,把session的数据看做一个共享的数据。首次登录的时候所获取的用户的数据,转移到session对象即可。我们可以将获取session中的数据这种行为进行封装,封装在BaseController类中。
1.封装session对象中数据的获取(封装父类中)、数据的设置(当用户登录成功后进行数据的设置,设置到全局的session对象)。
2.在父类中封装两个数据:获取uid和获取username对应的两个方法。用户头像暂时不考虑,将来封装cookie中来使用。|

/**
     * 获取Session对象中的uid
     * @param session
     * @return 当前登录对象的uid
     */
    public final Integer getUidFromSession(HttpSession session){
        return Integer.valueOf(session.getAttribute("uid").toString());
    }
    /**
     * 获取Session对象中的username
     * @param session
     * @return 当前登录对象的username
     */
    public final String getUsernameFromSession(HttpSession session){
        return session.getAttribute("username").toString();
    }

并在我们处理登录请求的方法中加入:

session.setAttribute("uid",user.getUid());
session.setAttribute("username",user.getUsername());

 登录拦截器

1.分析:项目中很多操作都是需要先登录才可以执行的,如果在每个请求处理之前都编写代码检查 Session中有没有登录信息,是不现实的。所以应使用拦截器解决该问题。 2.创建拦截器类com.cy.store.interceptor.LoginInterceptor,并实现 org.springframework.web.servlet.HandlerInterceptor接口。

/**
 * @author chenxi
 * @Date 2022/10/9
 * @Description 用户登录拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        if (session.getAttribute("uid") == null) {
            request.setAttribute("msg","请先登录在访问!");
            response.sendRedirect("/web/login.html");
            return false;
        } else {
            return true;
        }
    }
}

 2.创建LoginInterceptorConfigurer拦截器的配置类并实现(不要忘记加@Configuration注解!)

/**
 * @author chenxi
 * @Date 2022/10/9
 * @Description LoginInterceptorConfigurer拦截器的配置类
 */
@Configuration
public class LoginInterceptorConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 创建拦截器对象
        LoginInterceptor loginInterceptor = new LoginInterceptor();
        // 白名单
        List<String> patterns = new ArrayList<String>();
        patterns.add("/bootstrap3/**");
        patterns.add("/css/**");
        patterns.add("/images/**");
        patterns.add("/js/**");
        patterns.add("/web/login.html");
        patterns.add("/web/register.html");
        patterns.add("/web/product.html");
        patterns.add("/users/login");
        patterns.add("/users/reg");

        // 通过注册工具添加拦截器
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns(patterns);
    }
}


 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值