CH423S IO扩展芯片使用记录

组队学习(数列极限)

  返回  

springBoot+springDataJpa+Redis+JWT实现登录_ZL

2021/8/21 13:53:50 浏览:

前言

个人而言,我觉得现在主流 Spring BootSpring MVC 配置繁琐,只有一些比较老的项目在用,或者是政府机构之类会用到,而 Spring Boot 约定大于配置,现在微服务技术的普遍,而 Spring Cloud 的使用就是基于 Spring Boot

为什么要使用 JWT Token 而不是 Session

当用户第一次登陆成功的时候会向服务器传入 Session 并向客户端返回一个 SessionId,客户端将 SessionId 保存到 Cookie 中,用户再次请求服务器会带着 SessionId,服务器端拿着 SessionId 去寻找 Session。而 Session 是存储在内存当中,如果服务量大的话会占用很大的内存,Session 的拓展性也不强。

Token 就好比一个身份证,用户首次请求登陆服务器成功后会返回一个唯一的 Token 字符串,客户端保存到缓存当中,再次请求携带 Token,服务端解析 Token 获取用户信息到数据库查询。SSO 单点登陆同域或者跨域基本上都是通过 Token 实现的,拓展性强。正如刚刚说的 Token 每次解析完都要去查数据库,如果服务量特别大并发的话,会频繁访问数据库,容易造成数据库连接中断或者等待状态。这时候我们只需要把 Token 存放到 Redis 中,每次请求的时候都只会判断 Redis 中是否存在这个 TokenRedis 是单线程的可以有效地控制并发,并且 Redis 的处理级别都是毫秒级的。下面进入正题。

一、使用 IDEA 搭建 Spring Boot 项目集成 Spring Data JPA

 

1. 新建项目

这里注意,新建项目一定要勾选 Spring Web Spring Data JPA,如果是在现有项目做,可添加一下依赖。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Spring Data JPA 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

2. 引入 MySQL 依赖      

        <!--Mysql 依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--JSON 工具-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

我们的信息都是添加到数据库中的,所以这里我们添加 MySQL 阿里巴巴 Druid 连接池的依赖,JSON 工具下面会用到,这里我们提前添加进来。

3. application.properties 配置

# 端口号

server.port=8011

# mysql 驱动

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# mysql 地址

spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8

# mysql 用户名

spring.datasource.username=root

# mysql 密码

spring.datasource.password=123456

# JPA 连接 mysql

spring.jpa.database=mysql

# 运行显示 sql

spring.jpa.show-sql=true

spring.jpa.database 表示 JPA 要连接的数据库类型

二、介绍使用 Spring Data JPA

JPA Java Persistence API 的简称,中文名 Java 持久层 API,是 JDK 5.0 注解或 XML 描述对象关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun 引入新的 JPA ORM 规范出于两个原因:其一,简化现有 Java EE Java SE 应用开发工作;其二,Sun 希望整合 ORM 技术,实现天下归一。

1. 新建表 user

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,-- 主键ID
  `username` varchar(100) DEFAULT NULL,-- 用户名
  `password` varchar(100) DEFAULT NULL,-- 密码
  `realname` varchar(100) DEFAULT NULL,-- 真实姓名
  `create_time` datetime NOT NULL,-- 创建时间
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

2. 新建 UserEntity

/**
  * user
  * @date 2019/10/24 11:35
  */
@Entity
@Table(name = "user", schema = "test", catalog = "")
public class UserEntity {
    
    private int id;
    private String username;
    private String password;
    private String realname;
    private Date createTime;

    @Id
    @Column(name = "id")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "username")
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Basic
    @Column(name = "password")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Basic
    @Column(name = "realname")
    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    @Basic
    @Column(name = "create_time")
    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date date) {
        this.createTime = date;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserEntity that = (UserEntity) o;
        return id == that.id &&
                Objects.equals(username, that.username) &&
                Objects.equals(password, that.password) &&
                Objects.equals(realname, that.realname) &&
                Objects.equals(createTime, that.createTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, password, realname, createTime);
    }
}
  • @Entity:表示是一个实体,需要被 Spring 自动扫描。
  • @Table(name = "user", schema = "test", catalog = "")name 对应数据库中的表名,schema 表的架构,我们填库名就可以,catalog 表的目录,不填默认。一般情况下,我们直接使用 @Table(name = "user") 就可以。
  • @Column:对应的是数据库当中的字段名。
  • @Id:表示主键 ID

网上有自动生成 JPAEntity 的方法,大家自行百度。

3. 新建 UserRepository 接口并继承 JpaRepository

public interface UserRepository extends JpaRepository<UserEntity, Integer> {

}

  • UserEntity:对应实体,如果你的是其他的则填你对应的实体,填写 Map 也可以。
  • Integer:数据库主键类型。

 

 

JpaRepository 继承了接口 PagingAndSortingRepository QueryByExampleExecutor,而 PagingAndSortingRepository 继承 CrudRepository,所以 JpaRepository 接口同时拥有了基本增删改查及分页。因此我们只需要继承 JpaRepository 就可以了。

4. 新建 UserController (这里我们为了方便不写 Service 层)并注入 UserRepository

详细代码如下:

@RestController
@RequestMapping("/api/system")
public class UserController {

    @Autowired
    private UserRepository userRepository;
}

@RestController 相当于 @Controller @ResponseBody 的结合,不能返回页面,视图解析器无法解析 JSP HTML 页面。

@RequestMapping 映射请求路径。

@Autowired 的使用规则:

  • 容器中有该类型的候选 Bean
  • 容器中可以含有多个该类型的候选 Bean
  • Spring 3.x 之前 Spring 容器中只能有一个 Bean,多个 Bean 报异常 BeanCreationException
  • Spring 3.x 以后,可以有多个 Bean,使用 @Autowired 时变量名一定要和该类型多个 Bean 的其中一个相同(即上文中的 @Autowired private Student student;student 就是多个 Bean 中其中一个 bean id
  • 若违反第 4 条规则,会抛出 BeanCreationException 异常

https://cloud.tencent.com/developer/article/1479065

5. 新建一个返回工具类 ResultUtils

/**
  * 定义返回工具类
  * @date 2019/10/24 11:58
  */
public class ResultUtils {

    /**
    * 成功返回
    * @param data
    * @param msg
    * @return
    */
    public static Object success(Object data,String msg){
        Result result = new Result();
        result.setState(true);
        result.setData(data);
        result.setMsg(msg);
        return result;
    }

    public static Object success(String msg){
        Result result = new Result();
        result.setState(true);
        result.setMsg(msg);
        return result;
    }

    public static Object success(Object data){
        Result result = new Result();
        result.setState(true);
        result.setData(data);
        return result;
    }

    public static Object success(){
        Result result = new Result();
        result.setState(true);
        return result;
    }

    /**
    * 错误返回
    * @return
    */
    public static Object error(){
        Result result = new Result();
        result.setState(false);
        return result;
    }

    public static Object error(String msg){
        Result result = new Result();
        result.setState(false);
        result.setMsg(msg);
        return result;
    }
}

public static class Result{
        private boolean state;//返回状态
        private Object data;//返回数据
        private String msg;//返回信息
        public boolean isState() {
            return state;
        }

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

        public Object getData() {
            return data;
        }

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

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
}

这是我的完整目录结构:

 

6.在启动类 LogindemoApplication 添加注解 @EntityScan("com.logindemo.logindemo.system.entity")

@EntityScan 是在 Spring 启动的时候扫描指定包下的 Entity,根据我的经验如果不添加可能回报注入异常。如果有很多业务,包都是分开的,可以使用 .* 来代替。

例:如果我们不止 system 这一个目录,还有其他很多的目录的话,使用 @EntityScan("com.logindemo.logindemo.*") 代表扫描 logindemo 下的所有 Entity

7. UserController 写一个新增用户方法 saveUser 代码如下:

    /**
     * 新增用户
     * @return
     */
    @RequestMapping("/saveUser")
    public Object saveUser(){
        UserEntity userEntity = new UserEntity();
        //用户名
        userEntity.setUsername("admin");
        //密码 注:使用 Spring Boot 自带加密 对密码进行加密
        userEntity.setPassword( DigestUtils.md5DigestAsHex("123456".getBytes()));
        //真实姓名
        userEntity.setRealname("管理员");
        //创建时间
        userEntity.setCreateTime(new Date());
        //新增用户 这里调用 Spring Data JPA 自带方法进行新增
        UserEntity save = userRepository.save(userEntity);
        //如果不等于 null 返回我们刚刚定义好的工具类
        if (save!=null){
            return ResultUtils.success("操作成功");
        }
        return ResultUtils.error("操作失败");
    }

使用浏览器请求 http://localhost:8011/api/system/saveUser,浏览器响应返回消息:

 

这里是简单的做一个演示,后面会在用到的时候会讲解自定义查询。

三、集成 JWT

1. 引入 JWT 依赖
 

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=pc

2. 什么是 Token

Token 的意思是令牌,是服务端生成的一串字符串,作为客户端进行请求的一个标识。

简单 Token 的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)。

3. 编写生成 Token 工具类,新建一个 JwtUtils 工具类,如下:

package com.logindemo.logindemo.utils;

import com.logindemo.logindemo.system.entity.UserEntity;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
/**
 * jwt 工具类
 * @date 2019/10/24 9:38
 */
public class JwtUtils {
    public static final String SUBJECT="test";//签名发行者
    public static final String APPSECRET="logindemo";//签名

    /**
     * 生成token
     * @param userEntity
     * @return
     */
    public static String genJsonWebToken(UserEntity userEntity){
        String token="";
        if (userEntity!=null){
            token=Jwts.builder().setSubject(SUBJECT)//发行者
                    .claim("username",userEntity.getUsername())
                    .claim("realName",userEntity.getRealname())
                    .setIssuedAt(new Date())//发行日期
                    .signWith(SignatureAlgorithm.HS256,APPSECRET).compact();//签名
        } else {
            token="";
        }
        return token;
    }
}





后边我们会使用 Redis 校验 Token,不使用 JWT 自带校验方式。

4. 测试生成 Token

public static void main(String[] args) {
    UserEntity userEntity = new UserEntity();
    userEntity.setUsername("admin");
    userEntity.setRealname("管理员");
    System.out.println(genJsonWebToken(userEntity));
    //输入内容:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwidXNlcm5hbWUiOiJhZG1pbiIsInJlYWxOYW1lIjoi566h55CG5ZGYIiwiaWF0IjoxNTcxODkyNDU0fQ.S7pMyYZ_D_MSa-JcSKNRTc08bbAsEc8y7vSwgMktp2s
}

Token

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwidXNlcm5hbWUiOiJhZG1pbiIsInJlYWxOYW1lIjoi566h55CG5ZGYIiwiaWF0IjoxNTcxODkyNDU0fQ.S7pMyYZ_D_MSa-JcSKNRTc08bbAsEc8y7vSwgMktp2s

以上就是我们生成的 Token

Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次带上用户名和密码。

四、集成 Redis(Redis 服务需要自己搭建)

Windows 下安装 Redis 参考:

https://www.cnblogs.com/W-Yentl/p/7831671.html

Linux 下安装 Redis 参考:

https://www.cnblogs.com/zuidongfeng/p/8032505.html

1. 引入 Redis 依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. application.properties 配置 Redis

#Redis

#Redis 地址

spring.redis.host=39.96.167.196

#Redis 端口

spring.redis.port=6379

#Redis 密码(没有设置可以不写)

spring.redis.password=******

#Redis 超时时间

spring.redis.timeout=10000

#Redis 数据库索引(默认为0

spring.redis.database=0

3. 编写 Redis 工具类


package com.logindemo.logindemo.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * Redis 工具类
 * @date 2019/10/24 12:58
 */
@Component
public class RedisUtils {

    @Autowired
    public StringRedisTemplate redisTemplate;

    public static RedisUtils redisUtils;

    /**
     * 此方法只在 Spring启动时 加载一次
     */
    @PostConstruct
    public void init(){
        redisUtils=this;
        redisUtils.redisTemplate=this.redisTemplate;
    }

    /**
     *redis存入数据和设置缓存时间
     * @param key 键
     * @param value 值
     * @param time 秒
     */
    public void set(String key,String value,long time){
        redisUtils.redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    }


    /**
     * redis存入数据
     * @param key 键
     * @param value 值
     */
    public void set(String key,String value){
        redisUtils.redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 根据 key 获取过期时间
     * @param key
     * @return
     */
    public Long getExpire(String key){
        return redisUtils.redisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * 判断 key 是否存在
     * @param key
     * @return
     */
    public Boolean hasKey(String key){
        return redisUtils.redisTemplate.hasKey(key);
    }

    /**
     * 根据 key 设置过期时间
     * @param key key
     * @param time 秒
     * @return
     */
    public Boolean expire(String key,long time){
        return redisUtils.redisTemplate.expire(key,time , TimeUnit.SECONDS);
    }
}

五、在 UserController 编写登录接口

1. UserController 注入 RedisUtils

    @Autowired
    private RedisUtils redisUtils;

这里我们直接使用 @Autowired 自动注入即可。

2. UserRepository 方法

    /**
     * 根据用户名查询是否存在该用户
     * @param username
     * @return
     */
    int countByUsername(String username);

    /**
     * 根据用户名查询密码
     * @param username
     * @return
     */
    @Query(value = "select * from user where username=?1",nativeQuery = true)
    UserEntity getPassword(String username);

自定义写法介绍:

  • countByUsername 这个方法是 Spring Data JPA 的动态 SQL 查询。
  • count 代表数量,ByUsername 是根据用户名查询,需要注意的是条件首字母必须大写,整体意思就是根据用户名查询数量。
  • countByUsername  select count (1) from user where username='admin' 一样。

示例:根据用户名与密码查询用户数量

int countByUsernameAndPassword(String username,String password);

-m如果还有条件可以继续往后边拼接 And 如果用到的关系 Or 的首字母也必须大写

  • 如果需要查询用户需要用到 find,与 count 类似,只需要把 count 替换成 find 就可以了

使用 @Query 注解写法介绍:

@Query(value = “select * from user where username=?1”,nativeQuery = true)
UserEntity getPassword(String username);
  • nativeQuery = true` 表示使用原生 SQL 查询
  • ?1 代表第一个参数,假如除了 username 以外还有一个 password,那么写法如下:
@Query(value = “select * from user where username=?1 and password=?2”,nativeQuery = true)
UserEntity getPassword(String username,String password);

使用 @Param 写法如下:

@Query(value = “select * from user where username=:username and password=:password”,nativeQuery = true)

UserEntity getPassword(@Param(“username”) String username,@Param(“password”) String password);

以上两种写法,看个人喜好。

Spring Data JPA 方法命名规则可以参考:

https://blog.csdn.net/qq8057656qq/article/details/86744132

3. 登录接口代码

    /**
     * 登录接口
     * @param request
     * @return
     */
    @PostMapping("/login")
    public Object login(@RequestBody String request){
        JSONObject jsonObject = JSON.parseObject(request);//转 JSON 对象
        if (jsonObject.get("username")==null&&"".equals(jsonObject.get("username").toString())){
            return ResultUtils.error("用户名不能为空");
        }
        if (jsonObject.get("password")==null&&"".equals(jsonObject.get("password").toString())){
            return ResultUtils.error("用户名不能为空");
        }
        String username = jsonObject.get("username").toString();
        String password = jsonObject.get("password").toString();
        if (userRepository.countByUsername(username)>0){//判断用户是否存在
            UserEntity userEntity = userRepository.getPassword(username);//数据库中的密码
            if (DigestUtils.md5DigestAsHex(password.getBytes()).equals(userEntity.getPassword())){//校验密码是否一致
                String token = JwtUtils.genJsonWebToken(userEntity);//得到 Token
                redisUtils.set(token,userEntity.getRealname(),60);//登录成功后 把token放到Redis Key 存 token ,value 存用户真实姓名
                //登陆成功后 把token和真实姓名返回
                Map<String,Object> map = new HashMap<>();
                map.put("realname",userEntity.getRealname());
                map.put("token",token);
                return ResultUtils.success(map,"登录成功");//登录成功
            }
            return ResultUtils.error("密码错误,请重新输入");
        } else {
            return ResultUtils.error("用户名不存在");
        }

    }

因为我们使用的是 @PostMapping 注解,在后边的测试中就不能使用浏览器直接请求了(浏览器请求使用的是 GET 请求)。

@RequestBody 注解不理解的可以参考

https://www.jianshu.com/p/c1b8315c5a03

JSON 字符串转 JSON 对象有多种工具,这里我们使用阿里巴巴的。

大致流程:

 

4. 使用 Postman 请求地址

http://localhost:8011/api/system/login

请求 JSON

{

“username”:”admin”,

“password”:”123456”

}

返回数据:

{

“state”: true,

“data”: “登录成功”,

“msg”: “管理员

}

六、编写 Spring Boot 拦截

1. 新建包 config 并新建类 WebSecurityConfig 继承 WebMvcConfigurationSupport

2. WebSecurityConfig 增加 @Configuration 注解

@Configuration 标注在类上,相当于把该类作为 Spring XML 配置文件中的作用为:配置 Spring 容器(应用上下文)。

3. 实现 addInterceptors 方法,配置自定义拦截

    /**
     * 配置自定义拦截拦截器
     * @param registry
     */
    public void  addInterceptors(InterceptorRegistry registry){
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
        List<String> list = new ArrayList<>();
        list.add("/api/system/saveUser");//放行新增用户接口地址
        list.add("/api/system/login");//放行登陆接口地址
        addInterceptor.excludePathPatterns(list);
        addInterceptor.addPathPatterns("/**");//拦截所有请求
    }

4. WebSecurityConfig 中新建内部类 SecurityInterceptor,并继承 HandlerInterceptorAdapter 实现 preHandle 方法

  • preHandle 调用时间:Controller 方法处理之前,返回 truefalse 两种形式,如果返回 false 则中断执行,反之则继续执行。 除了 preHandle 还有 postHandleafterCompletion 方法。postHandle Controller 方法处理完之后对视图进行渲染前被调用。
  • afterCompletion 是对视图渲染后调用。

这里我们只实现 preHandle 方法。

5. WebSecurityConfig 中注入 SecurityInterceptor,方法增加注解 @Bean

注意:@Bean 要与 @Configuration 配合使用(在启动类使用不需要增加 @Configuration )。

6. WebSecurityConfig 类中注入 RedisUtils 工具类并完善 preHandle 方法

整体代码如下:


package com.logindemo.logindemo.config;

import com.logindemo.logindemo.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.WebMvcConfigurationSupport;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 登录拦截配置
 */
@Configuration
public class WebSecurityConfig extends WebMvcConfigurationSupport {

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 注入Bean 让 Spring 扫描 SecurityInterceptor
     * 不然过滤器不起作用
     * @return
     */
    @Bean
    public SecurityInterceptor getSecurityInterceptor(){
        return new SecurityInterceptor();
    }

    /**
     * 配置自定义拦截拦截器
     * @param registry
     */
    public void  addInterceptors(InterceptorRegistry registry){
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
        List<String> list = new ArrayList<>();
        list.add("/api/system/saveUser");//放行新增用户接口地址
        list.add("/api/system/login");//放行登陆接口地址
        addInterceptor.excludePathPatterns(list);
        addInterceptor.addPathPatterns("/**");//拦截所有请求
    }

    private class SecurityInterceptor extends HandlerInterceptorAdapter {

        /**
         * 在业务处理器处理请求之前被调用

         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
            ServletOutputStream out = response.getOutputStream();//创建一个输出流
            OutputStreamWriter ow=new OutputStreamWriter(out,"utf-8");//设置编码格式,防止汉字乱码
            String token = request.getHeader("token");//获取 Token
            if(token!=null){//判断 Token 是否为空
                if (redisUtils.hasKey(token)){//判断 Token 是否存在
                    redisUtils.expire(token,60); //如果 Token 存在 重新赋予过期时间 并放行
                    return true;
                }
                ow.write("token错误,请重新登录");//要返回的信息
                ow.flush();//冲刷出流,将所有缓冲的数据发送到目的地
                ow.close();//关闭流
                return false;//拦截
            }
            ow.write("token为空,请重新登录");//要返回的信息
            ow.flush();//冲刷出流,将所有缓冲的数据发送到目的地
            ow.close();//关闭流
            return false;//拦截
        }
    }
}

用户发送请求首先会进入 addInterceptors 方法,如果有需要拦截的路径则进入 preHandle 方法。在 preHandle 方法中通过 request.getHeader ("token") 获取 Token(测试的时候会把 Token 放入请求头中)。如果没有 addInterceptors 中直接放行请求路径不会进入 preHandle 方法。

这里我们可以通过输出流把错误信息回显给用户。

7. 为了方便查看效果,在 UserController 中新增 findAll 方法返回所有用户

    /**
     * 获取所有用户
     * @return
     */
    @RequestMapping("/findAll")
    public Object findAll(){
        List<UserEntity> all = userRepository.findAll();
        for (UserEntity temp:all) {
            temp.setPassword(null);//对密码进行过滤
        }
        return all;
    }

我们这里把所有用户密码循环置空,不管是什么业务,只要回显给用户的信息,密码一般都不显示

七、使用 Postman 测试

1. 首先我们直接访问 findAll 的方法

 

提示 Token 为空,请重新登录。

2. 调用登陆接口登陆

 

 

3. 把返回的 Token 填入到 findAll 地址的 Headers

 

4. 重新请求 findAll 方法

 

可以看到我们已经请求成功了!

  

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号