IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring boot jwt完整过程 -> 正文阅读

[Java知识库]spring boot jwt完整过程

首先源码https://gitee.com/mobile191llx/spring-boot-jwt.git

接着项目目录结构

在这里插入图片描述

项目开始

1.新建项目名称为demo、选择maven什么都不要勾选

2.依赖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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.73</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <!--  阿里镜像  -->
    <repositories>
        <repository>
            <id>aliyun</id>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>aliyun-plugin</id>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

3.新建数据库

create database store; # 新建数据库
use store; # 选中数据库
create table t_user(   # 新建数据表
	uid varchar(50) not null primary key,
    username varchar(20) not null unique,
    password char(50) not null,
    salt varchar(50),
    phone varchar(11) unique,
    email varchar(30) unique not null,
    gender int(1),
    avatar varchar(50),
    is_delete int(1) not null,
    created_user varchar(20) not null,
    created_time datetime not null,
    modified_user varchar(20) not null,
    modified_time datetime not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.配置项目application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver   # 驱动
    username: root     #数据库登录名
    password: 123456   #数据库密码
	# 数据库名为store,字符集为utf-8,时区为北京
    url: jdbc:mysql://localhost:3306/store?characterEncoding=utf-8&serverTimezone=GMT%2B8
mybatis:
  mapper-locations: classpath:mapper/*.xml  # mapper.xml扫描路径

5.主启动类、在java路径下创建com.example.demo目录、在demo目录下创建App类

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // 注册为springboot启动类
@MapperScan("com.example.demo.mapper") // 扫描mapper路径也就是dao层
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

6.在demo目录下新建mapper目录,在demo/mapper下新建UserMapper类

package com.example.demo.mapper;

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Param;

import java.util.Date;

public interface UserMapper {
    /**
     * 插入用户的数据
     *
     * @param user 用户的数据
     * @return 返回Integer
     */
    Integer insert(User user);

    /**
     * 根据用户名来查询用户的数据
     *
     * @param username 用户名
     * @return 返回User或者null
     */
    User findByUsername(String username);

    Integer updatePasswordByUid(@Param("uid") String uid,
                                @Param("password") String password,
                                @Param("modifiedUser") String modifiedUser,
                                @Param("modifiedTime") Date modifiedTime);

    /*** 根据用户id查询用户数据
     * @param uid 用户id
     * @return 匹配的用户数据,如果没有匹配的用户数据,则返回null
     */
    User findByUid(String uid);


}

7 .创建demo/service/ex目录、在ex目录下新建ServiceException异常类

package com.example.demo.Service.ex;

/**
 * 重写异常方法
 */
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);
    }
}

8.创建demo/service/ex目录、在ex目录下新建5个异常类-InsertException、PasswordNotMatchException、UpdateException、UsernameDuplicatedException、UserNotFoundException,这几个类全部继承上面创建的ServiceException类并且insert+alt选择Override Methods选择前4项,大概如下

package com.example.demo.Service.ex;

public class InsertException extends ServiceException {
    public InsertException() {
        super();
    }

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

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

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

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

9.在service目录下新建IUserService接口

package com.example.demo.Service;

import com.example.demo.entity.User;

public interface IUserService {
    /**
     * 用户注册方法
     * @param user
     */
    void reg(User user);

    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    User login(String username,String password);

    /**
     * 修改密码
     * @param uid 当前登录的id
     * @param username 用户名
     * @param oldPassword
     * @param newPassword
     */
    void changePassword(String uid, String username, String oldPassword, String newPassword);

	/**
     * 根据用户id查询用户信息,有token时才可访问
     * @param uid 当前登录的id
     * @param username 用户名
     * @param oldPassword
     * @param newPassword
     */
    User findByUid(String uid);
}

10.在service目录下创建UserServiceImpl

package com.example.demo.Service.impl;

import com.example.demo.Service.IUserService;
import com.example.demo.Service.ex.PasswordNotMatchException;
import com.example.demo.Service.ex.UpdateException;
import com.example.demo.Service.ex.UserNotFoundException;
import com.example.demo.Service.ex.UsernameDuplicatedException;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.UUID;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public void reg(User user) { // 用户注册
        // 查重
        User result = userMapper.findByUsername(user.getUsername());
        if (result != null) {
            throw new UsernameDuplicatedException("用户名被占用");
        }
        // 设置id
        user.setUid(UUID.randomUUID().toString().toUpperCase());
        //  设置初始值
        user.setIsDelete(0);
        user.setCreatedUser(user.getUsername());
        user.setModifiedUser(user.getUsername());
        // 时间
        Date date = new Date();
        user.setModifiedTime(date);
        user.setCreatedTime(date);
        // 密码加密
        String oldPassword = user.getPassword();
        String salt = UUID.randomUUID().toString().toUpperCase();
        String md5Password = getMd5Pw(oldPassword, salt);
        // 保存密码
        user.setPassword(md5Password);
        // 保存盐值
        user.setSalt(salt);
        // 注册
        Integer rows = userMapper.insert(user);
        if (rows != 1) {
            throw new UsernameDuplicatedException("在用户注册过程中发生了未知的异常");
        }
    }

    @Override
    public User login(String username, String password) { // 登录
        User result = userMapper.findByUsername(username);
        if (result == null) {
            throw new UserNotFoundException("用户数据不存在的异常");
        }
        if (result.getIsDelete() == 1) {
            throw new UserNotFoundException("用户数据不存在的错误");
        }
        // 获取盐值
        String salt = result.getSalt();
        String md5Pw = getMd5Pw(password, salt);
        if (!result.getPassword().equals(md5Pw)) {
            throw new PasswordNotMatchException("密码验证失败的错误");
        }
        result.setPassword("");
        return result;
    }

    @Override
    public void changePassword(String uid, String username, String oldPassword, String newPassword) { // 修改密码
        User result = userMapper.findByUid(uid);
        if (result == null) {
            throw new UserNotFoundException("用户数据不存在");
        }
        if (result.getIsDelete().equals(1)) {
            throw new UserNotFoundException("用户数据不存在");
        }
        String salt = result.getSalt();
        // 比较密码
        String oldMd5Pw = getMd5Pw(oldPassword, salt);
        if (!result.getPassword().contentEquals(oldMd5Pw)) {
            throw new PasswordNotMatchException("原密码错误");
        }
        // 新密码
        String newMd5Pw = getMd5Pw(newPassword, salt);
        Date now = new Date();
        Integer rows = userMapper.updatePasswordByUid(uid, newMd5Pw, username, now);
        if (rows != 1) {
            throw new UpdateException("更新用户数据时出现未知错误,请联系统管理员");
        }
    }

    @Override
    public User findByUid(String uid) { // 根据uid查询用户资料
        return userMapper.findByUid(uid);
    }


    /**
     * 密码通过md5算法加密
     */
    private String getMd5Pw(String password, String salt) {
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((salt + password).getBytes()).toUpperCase();
        }
        return password;
    }
}

10.在demo目录下新建controller目录,在controller目录下新建BaseController类用于返回异常结果

package com.example.demo.controll;

import com.example.demo.Service.ex.*;
import com.example.demo.util.JsonResult;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 控制层基类
 */
public class BaseController {
    // 成功状态码
    public static final int OK = 200;


    // 请求处理方法,这个方法的返回值就是需要传递给前端的数据
    @ExceptionHandler(ServiceException.class)  // 统一处理抛出的异常
    public JsonResult<Void> handlerException(Throwable e) {
        JsonResult<Void> result = new JsonResult<>(e);
        if(e instanceof UsernameDuplicatedException){
            result.setState(400);
            result.setMessage("用户名已经被占用");
        }else if(e instanceof UserNotFoundException){
            result.setState(500);
            result.setMessage("用户不存在");
        }else if(e instanceof PasswordNotMatchException){
            result.setState(600);
            result.setMessage("密码错误");
        }else if(e instanceof InsertException){
            result.setMessage("注册失败");
            result.setState(700);
        }else if(e instanceof UpdateException){
            result.setState(800);
            result.setMessage("修改密码失败");
        }
        return result;
    }
}

11.在controller目录下新建UserController类

package com.example.demo.controll;

import com.example.demo.Service.IUserService;
import com.example.demo.entity.User;
import com.example.demo.util.JWTUtils;
import com.example.demo.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("users")
public class UserController extends BaseController {
    @Autowired
    private IUserService userService;

    // 用户注册
    @RequestMapping("/reg")
    public JsonResult<Void> reg(User user) {
        userService.reg(user);
        return new JsonResult<>(OK, "用户注册成功");
    }

    // 用户登录
    @RequestMapping("/login")
    public JsonResult<User> login(String username, String password) {
        User user = userService.login(username, password);
        if (user != null) {
            Map<String,String> map = new HashMap<>();
            map.put("username",user.getUsername());
            map.put("uid",user.getUid());
            String token = JWTUtils.getToken(map);
            user.setToken(token);
        }
        return new JsonResult<>(OK, "登录成功", user);
    }

    // 修改密码
    @RequestMapping("/change_password")
    public JsonResult<Void> changePassword(String uid, String username, String oldPassword, String newPassword) {
        userService.changePassword(uid, username, oldPassword, newPassword);
        return new JsonResult<>(OK, "修改成功");
    }

    // 获取用户信息
    @RequestMapping("/list")
    public JsonResult<User> list(String uid) {
        User user = userService.findByUid(uid);
        return new JsonResult<>(OK,"获取成功",user);
    }

}

12.在demo下新建utils目录,在utils下新建JWTUtils类

package com.example.demo.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Map;

public class JWTUtils {


	// 秘钥
    private static final String  SING = "!Q@W3e4r%T^Y";

    /**
     * 生成token  header.payload.sing
     */
    public static String getToken(Map<String,String> map){

        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,7);//默认7天过期

        //创建jwt builder
        JWTCreator.Builder builder = JWT.create();

        // 将传进来的用户信息加入到token再生成
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        // 得到token
        String token = builder.withExpiresAt(instance.getTime())//指定令牌过期时间
                .sign(Algorithm.HMAC256(SING));// 机密方式为HMAC256,SING秘钥
        return token;
    }

    /**
     * 验证token 合法性
     *
     */
    public static DecodedJWT verify(String token){
        return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
    }

}

13.在utils目录下新建JsonResult类用于封装返回结果集

package com.example.demo.util;

import java.io.Serializable;

public class JsonResult<E> implements Serializable {
    // 状态码
    private Integer state;
    // 描述信息
    private String message;
    // 数据
    private E data;

    public JsonResult() {
    }

    public JsonResult(Integer state) {
        this.state = state;
    }

    public JsonResult(Throwable e) {
        this.message = e.getMessage();
    }

    public JsonResult(Integer state, E data) {
        this.state = state;
        this.data = data;
    }

    public Integer getState() {
        return state;
    }

    public void setState(Integer state) {
        this.state = state;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public JsonResult(Integer state, String message) {
        this.state = state;
        this.message = message;
    }

    public JsonResult(Integer state, String message, E data) {
        this.state = state;
        this.message = message;
        this.data = data;
    }
}

14.忘了还有两个实体类、在demo下创建entity目录,在entity下创建BaseEntity类

package com.example.demo.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

public class BaseEntity implements Serializable {
    private String createdUser;
    private Date createdTime;
    private String modifiedUser;
    private Date modifiedTime;

    public String getCreatedUser() {
        return createdUser;
    }

    public void setCreatedUser(String createdUser) {
        this.createdUser = createdUser;
    }

    public Date getCreatedTime() {
        return createdTime;
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }

    public String getModifiedUser() {
        return modifiedUser;
    }

    public void setModifiedUser(String modifiedUser) {
        this.modifiedUser = modifiedUser;
    }

    public Date getModifiedTime() {
        return modifiedTime;
    }

    public void setModifiedTime(Date modifiedTime) {
        this.modifiedTime = modifiedTime;
    }

    @Override
    public String toString() {
        return "BaseEntity{" +
                "createdUser='" + createdUser + '\'' +
                ", createdTime=" + createdTime +
                ", modifiedUser='" + modifiedUser + '\'' +
                ", modifiedTime=" + modifiedTime +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BaseEntity)) return false;
        BaseEntity that = (BaseEntity) o;
        return Objects.equals(getCreatedUser(), that.getCreatedUser()) &&
                Objects.equals(getCreatedTime(), that.getCreatedTime()) &&
                Objects.equals(getModifiedUser(), that.getModifiedUser()) &&
                Objects.equals(getModifiedTime(), that.getModifiedTime());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getCreatedUser(), getCreatedTime(), getModifiedUser(), getModifiedTime());
    }
}

15.entity目录下继续新建User类

package com.example.demo.entity;

import java.util.Objects;

public class User extends BaseEntity {
    private String 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;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    private String token;

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    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;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public Integer getIsDelete() {
        return isDelete;
    }

    public void setIsDelete(Integer isDelete) {
        this.isDelete = isDelete;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid='" + uid + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + gender +
                ", avatar='" + avatar + '\'' +
                ", isDelete=" + isDelete +
                ", token='" + token + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        if (!super.equals(o)) return false;
        User user = (User) o;
        return Objects.equals(getUid(), user.getUid()) &&
                Objects.equals(getUsername(), user.getUsername()) &&
                Objects.equals(getPassword(), user.getPassword()) &&
                Objects.equals(getSalt(), user.getSalt()) &&
                Objects.equals(getPhone(), user.getPhone()) &&
                Objects.equals(getEmail(), user.getEmail()) &&
                Objects.equals(getGender(), user.getGender()) &&
                Objects.equals(getAvatar(), user.getAvatar()) &&
                Objects.equals(getIsDelete(), user.getIsDelete()) &&
                Objects.equals(getToken(), user.getToken());
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), getUid(), getUsername(), getPassword(), getSalt(), getPhone(), getEmail(), getGender(), getAvatar(), getIsDelete(), getToken());
    }
}

16.配置拦截规则、在demo下新建interceptor目录,在interceptor新建JWTinterceptor类

package com.example.demo.interceptor;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.example.demo.util.JWTUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;


public class JWTInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //获取请求头中令牌
        String token = request.getHeader("token");
        try {
            JWTUtils.verify(token);//验证令牌
            return true;//放行请求
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            map.put("msg","无效签名!");
        }catch (TokenExpiredException e){
            e.printStackTrace();
            map.put("msg","token过期!");
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();
            map.put("msg","token算法不一致!");
        }catch (Exception e){
            e.printStackTrace();
            map.put("msg","token无效!!");
        }
        map.put("state",false);//设置状态
        //将map 专为json  jackson
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

17.在demo下新建config,在config目录下新建InterceptorConfig

package com.example.demo.config;

import com.example.demo.interceptor.JWTInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/users/list")         //其他接口token验证
                .excludePathPatterns("/users/login");  //所有用户都放行
    }

    // 最大30线程,外加30列队;【拒绝策略AbortPolicy(默认):丢弃并抛出异常】
    private static ExecutorService executorService = new ThreadPoolExecutor(
            1, 30, 60L,
            TimeUnit.SECONDS, new ArrayBlockingQueue<>(3)
    );


    /**
     * 线程限制
     *
     * @param configurer
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(new ConcurrentTaskExecutor(executorService));
        configurer.setDefaultTimeout(30000);
    }
}

18.运行app、获取users/list不带token在这里插入图片描述

19.登录一下、返回token和用户信息

在这里插入图片描述

20.在访问users/list

在这里插入图片描述

Ok,到这里就结束了

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:29:56  更:2022-08-06 10:33:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:23:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码