java代码--拦截器的实现

拦截器的实现

1.新建工程模块interceptor

准备:数据库数据

CREATE DATABASE admin_bd

USE admin_bd

DROP TABLE IF EXISTS `admin_user`;

CREATE TABLE `admin_user` (
  `admin_user_seq` INT(11) NOT NULL AUTO_INCREMENT,
  `admin_user_no` VARCHAR(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_user_name` VARCHAR(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_user_position` VARCHAR(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `admin_user_phone` VARCHAR(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_user_email` VARCHAR(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `admin_user_password` VARCHAR(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `smed_role_info_bd_seq` INT(11) NOT NULL,
  `role_info_name` VARCHAR(20) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_user_status_itype` TINYINT(2) NOT NULL,
  `create_by` BIGINT(20) NOT NULL,
  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_by` BIGINT(20) DEFAULT NULL,
  `update_time` TIMESTAMP NULL DEFAULT NULL,
  `active_flag` CHAR(1) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`admin_user_seq`),
  KEY `smed_boss_user_bd_ix1` (`admin_user_phone`),
  KEY `smed_boss_user_bd_ix2` (`admin_user_no`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;



INSERT  INTO `admin_user`(`admin_user_no`,`admin_user_name`,`admin_user_position`,`admin_user_phone`,`admin_user_email`,`admin_user_password`,`smed_role_info_bd_seq`,`role_info_name`,
`admin_user_status_itype`,`create_by`,`create_time`,`active_flag`) VALUES ('super','super','super','15177778888','56565@qq.com','9f95c68e7ceff25f65962a24e21b85c1',35,'最新',1,1,NOW(),'y')


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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo</groupId>
    <artifactId>interceptor</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--  统一版本管理-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!-- jdk版本 -->
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- web 启动器  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <!-- springboot集成单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <!-- mybatis启动器-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql连接器-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!-- swaggerUi接口文档的以来-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!--springboot集成redis启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <!-- commons包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!--json-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>
    </dependencies>

</project>
3.编写配置文件application.yml
spring.datasource:
  url: jdbc:mysql://127.0.0.1:3306/admin_bd?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&noAccessToProcedureBodies=true&zeroDateTimeBehavior=convertToNull
  username: root
  password: root
  type: com.zaxxer.hikari.HikariDataSource
  driver-class-name: com.mysql.jdbc.Driver
  hikari:
    connectionTimeout: 30000
    idleTimeout: 600000
    maxLifetime: 1800000
    maximumPoolSize: 50
    minimumIdle: 10
    validationTimeout: 5000
spring.redis:
  database: 0
  host: 127.0.0.1
  port: 6379
  password:
  pool:
    max-active: 8
    max-wait: -1
    max-idle: 8
    min-idle: 0
server:
  port: 10086
4.配置swagger接口文档

配置接口文档主要是为了测试方便,以及模拟项目中在请求头中获取token和userId

package com.demo.interceptor.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * @className: GenSwaggerUiConfig
 * @description: 接口文档配置类
 * @author: demo
 * @create: 2021-03-30 15:27
 **/
@Configuration
@EnableSwagger2
public class GenSwaggerUiConfig {

    @Bean
    public Docket createRestApi(){
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("interceptor api文档")
                .version("1.0")
                .description("测试拦截器 api文档").build();
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo).select()
                .apis(RequestHandlerSelectors.basePackage("com.demo.interceptor.controller"))
                .paths(PathSelectors.any()).build().globalOperationParameters(getParameter());

    }

    //添加全局操作的参数
    public List<Parameter> getParameter(){
        ParameterBuilder token = new ParameterBuilder();
        ParameterBuilder userId =  new ParameterBuilder();
        List<Parameter> params = new ArrayList<>();
        token.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header")
                .required(false).build();
        userId.name("userId").description("userId").modelRef(new ModelRef("integer")).parameterType("header")
                .required(false).build();
        params.add(token.build());
        params.add(userId.build());
        return params;
    }
}
5.编写加密的工具类

更好的模拟项目中登录时需要对密码进行加密解密

package com.demo.interceptor.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@Slf4j
public class EncryptUtil {

    /**
     * 定义一个字符串数组
     */
    private static final String[] hexDigits={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * 转换字节数组为16进制字串
     *
     * @param b 字节数组
     * @return 16进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");

            resultString = byteArrayToHexString(md.digest(origin.getBytes("utf-8")));
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        return resultString;
    }

    /**
     * 算法
     */
    private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";


    /**
     * aes解密
     * @param encrypt	内容
     * @return
     * @throws Exception
     */
    public static String aesDecrypt(String encrypt) {
        try{
            return aesDecrypt(encrypt, "1234567891234567");
        }catch (Exception ex){
            log.error(ex.getMessage());
            return null;
        }
    }

    /**
     * aes加密
     * @param content
     * @return
     * @throws Exception
     */
    public static String aesEncrypt(String content) {
        try{
            return aesEncrypt(content, "1234567891234567");
        }catch (Exception ex){
            log.error(ex.getMessage());
            return null;
        }
    }

    /**
     * 将byte[]转为各种进制的字符串
     * @param bytes byte[]
     * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
     * @return 转换后的字符串
     */
    public static String binary(byte[] bytes, int radix){
        // 这里的1代表正数
        return new BigInteger(1, bytes).toString(radix);
    }

    /**
     * base 64 encode
     * @param bytes 待编码的byte[]
     * @return 编码后的base 64 code
     */
    public static String base64Encode(byte[] bytes){
        return Base64.encodeBase64String(bytes);
    }

    /**
     * base 64 decode
     * @param base64Code 待解码的base 64 code
     * @return 解码后的byte[]
     * @throws Exception
     */
    public static byte[] base64Decode(String base64Code) throws Exception{
        return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
    }


    /**
     * AES加密
     * @param content 待加密的内容
     * @param encryptKey 加密密钥
     * @return 加密后的byte[]
     * @throws Exception
     */
    public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher jiami = Cipher.getInstance(ALGORITHMSTR);
        jiami.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(StandardCharsets.UTF_8.name()), "AES"));

        return jiami.doFinal(content.getBytes("utf-8"));
    }


    /**
     * AES加密为base 64 code
     * @param content 待加密的内容
     * @param encryptKey 加密密钥
     * @return 加密后的base 64 code
     * @throws Exception
     */
    public static String aesEncrypt(String content, String encryptKey) throws Exception {
        return base64Encode(aesEncryptToBytes(content, encryptKey));
    }

    /**
     * AES解密
     * @param encryptBytes 待解密的byte[]
     * @param decryptKey 解密密钥
     * @return 解密后的String
     * @throws Exception
     */
    public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);

        Cipher jiami = Cipher.getInstance(ALGORITHMSTR);
        jiami.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(StandardCharsets.UTF_8.name()), "AES"));
        byte[] decryptBytes = jiami.doFinal(encryptBytes);
        return new String(decryptBytes,"utf-8");
    }


    /**
     * 将base 64 code AES解密
     * @param encryptStr 待解密的base 64 code
     * @param decryptKey 解密密钥
     * @return 解密后的string
     * @throws Exception
     */
    public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
        return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
    }
}
6.编写启动类,启动,看是否能够正常启动
package com.demo.interceptor;

import com.demo.interceptor.config.InterceptorConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @className: AdminApplication
 * @description:
 * @author: demo
 * @create: 2021-03-30 15:09
 **/
@SpringBootApplication
@MapperScan("com.demo.interceptor.mapper")
public class AdminApplication  {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class,args);
    }
}

7.编写redisService
package com.demo.interceptor.service;

/**
 * @className: RedisService
 * @description: 缓存
 * @author: demo
 * @create: 2021-03-30 16:02
 **/

public interface RedisService {
    String get(String key);

    void setAndExpire(String key, String value, Integer second);

    int isValidTokenAndUserId(int userId,String token);
}

8.编写RedisServiceImpl
package com.demo.interceptor.service.impl;

import com.demo.interceptor.service.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @className: RedisServiceImpl
 * @description: 缓存实现类、
 * @author: demo
 * @create: 2021-03-30 16:05
 **/
@Service
public class RedisServiceImpl implements RedisService  {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public void setAndExpire(String key, String value, Integer second) {
        this.redisTemplate.opsForValue().set(key, value, second, TimeUnit.SECONDS);
    }

    @Override
    public int isValidTokenAndUserId(int userId, String token) {
        String redisToken = get("com:demo:interceptor:user:token:" + userId);
        //判断缓存中是否有这个token键,没有则证明登录信息已过期或者不存在
        if (StringUtils.isBlank(redisToken)){
            //token不存在或已过期
            return 400;
        }
        //如果缓存中有这个token键的值,则比对缓存中的值与前端传进来的值是否一致,一致则验证成功
        if (redisToken.equals(token)){
            //token验证成功
            return 200;
        }else {//若不一致,则判断缓存中的值是否是账号被冻结的值,如果都不是,那么证明账号正在其他设备上登录导致token值改变
            if (redisToken.equals("888888")){
                //账号已被冻结
                return 100;
            }else{
                //账号正在其他设备登录
                return 300;
            }
        }
    }
}
9.编写实现登录的代码以及返回登录用户信息
9.1编写需要的bean

Response

package com.demo.interceptor.entity.bean;

import lombok.Data;

/**
 * @className: Response
 * @description: 响应类
 * @author: demo
 * @create: 2021-03-30 15:47
 **/
@Data
public class Response {
    private Integer code;
    private Object data;
    private String msg;

    public static Response success(Object data){
        Response response = new Response();
        response.setCode(200);
        response.setData(data);
        response.setMsg("ok");
        return response;
    }

    public static Response successWithEmpty(){
        Response response = new Response();
        response.setCode(200);
        response.setMsg("ok");
        response.setData(new Response());
        return response;
    }

    public static Response error(String mes){
        Response response = new Response();
        response.setCode(300);
        response.setMsg(mes);
        return response;
    }

}

RestBase

package com.demo.interceptor.entity.bean;

import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @className: RestBase
 * @description:
 * @author: demo
 * @create: 2021-03-30 17:10
 **/

public class RestBase {
    @Autowired
    HttpServletRequest request;

    @Autowired
    HttpServletResponse response;

    /**
     *
     * @Title: getLoginUserID
     * @param:
     * @Description:
     * @return int
     */
    public Integer getLoginUserID() {
        if (null == request) {
            return 0;
        }
        Integer userId = 0;
        if (null != request) {
            String loginUserId = request.getHeader("userId");
            if (loginUserId != null) {
                userId = Integer.parseInt(loginUserId);
            }
        }
        return userId;
    }
}

AdminUser

package com.demo.interceptor.entity.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @className: AdminUser
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 16:43
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminUser  {
    //主键id
    private Integer adminUserId;
    //工号
    private String adminUserNo;
    //密码
    private String adminUserPassword;
    //姓名
    private String adminUserName;
    //职位
    private String adminUserPosition;
    //电话
    private String adminUserPhone;
    //邮箱
    private String adminUserEmail;
    //角色主键id
    private Integer roleId;
    //角色名称
    private String roleName;
    //状态,1正常,2冻结
    private Integer statusItype;
    //创建人
    private Long createBy;
    //创建时间
    private Date createTime;
    //修改人
    private Long updateBy;
    //修改时间
    private Date updateTime;
    //状态 y正常 d删除 n其他状态
    private String activeFlag;
}
9.2编写接收前端数据的对应实体类

AdminUserQo

package com.demo.interceptor.entity.qo;

import com.demo.interceptor.entity.bean.AdminUser;
import lombok.Data;

/**
 * @className: AdminUserQo
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 16:47
 **/
@Data
public class AdminUserQo extends AdminUser {
}

9.3编写返回前端数据的对应实体类

AdminUserDto

package com.demo.interceptor.entity.dto;

import com.demo.interceptor.entity.bean.AdminUser;
import lombok.Data;

/**
 * @className: AdminUserDto
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 16:48
 **/
@Data
public class AdminUserDto extends AdminUser {
    //token
    private String token;

}
9.4编写对应mapper

AdminUserMapper

package com.demo.interceptor.mapper;

import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.entity.dto.AdminUserDto;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.JdbcType;

import java.util.Date;

/**
 * @className: AdminUserMapper
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 16:49
 **/
@Mapper
public interface AdminUserMapper {

    /**
     * @Title: getAdminUserInfo
     * @Description: 获取后台管理员的详细信息
     * @param:
     * @return: AdminUserDto
     */
    @Select(" SELECT * FROM admin_user WHERE active_flag='y' AND admin_user_seq=#{adminUserId}")
    @Results(id = "adminUserResultMap", value = {
            @Result(property = "adminUserId", column = "admin_user_seq", javaType = Integer.class, jdbcType = JdbcType.INTEGER),
            @Result(property = "adminUserNo", column = "admin_user_no", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "adminUserPassword", column = "admin_user_password", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "adminUserName", column = "admin_user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "adminUserPosition", column = "admin_user_position", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "adminUserPhone", column = "admin_user_phone", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "adminUserEmail", column = "admin_user_email", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "roleId", column = "smed_role_info_bd_seq", javaType = Integer.class, jdbcType = JdbcType.INTEGER),
            @Result(property = "roleName", column = "role_info_name", javaType = String.class, jdbcType = JdbcType.VARCHAR),
            @Result(property = "statusItype", column = "admin_user_status_itype", javaType = Integer.class, jdbcType = JdbcType.TINYINT),
            @Result(property = "createBy", column = "create_by", javaType = Long.class, jdbcType = JdbcType.BIGINT),
            @Result(property = "createTime", column = "create_time", javaType = Date.class, jdbcType = JdbcType.TIMESTAMP)
    })
   AdminUserDto getAdminUserInfoById(Integer adminUserId);

    /**
     * @Title: getAdminUserInfoByNo
     * @Description: 获取后台管理员的详细信息
     * @param:
     * @return: AdminUserDto
     */
    @Select(" SELECT * FROM admin_user WHERE active_flag='y' AND admin_user_no=#{adminUserNo}")
    @ResultMap("adminUserResultMap")
    AdminUserDto getAdminUserInfoByNo(String adminUserNo);
}

9.5编写对应的service

AdminUserService

package com.demo.interceptor.service;

import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.entity.qo.AdminUserQo;

public interface AdminUserService {

    /**
     * @Title: getAdminUserInfo
     * @Description: 获取后台管理员的详细信息
     * @param:
     * @return: Response
     */
    Response getAdminUserInfoById(Integer adminUserId);

    /**
     * @Title: login
     * @Description:  登录后台管理系统
     * @param:  adminUserQo
     * @return:  Response
     */
    Response login(AdminUserQo adminUserQo);
}

9.6编写对应service的实现类

AdminUserServiceImpl

package com.demo.interceptor.service.impl;

import com.alibaba.fastjson.JSON;
import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.entity.dto.AdminUserDto;
import com.demo.interceptor.entity.qo.AdminUserQo;
import com.demo.interceptor.mapper.AdminUserMapper;
import com.demo.interceptor.service.AdminUserService;
import com.demo.interceptor.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * @className: AdminUserServiceImpl
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 17:05
 **/
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Autowired
    private AdminUserMapper adminUserMapper;
    @Autowired
    private RedisService redisService;

    /**
     * @Title: getAdminUserInfo
     * @Description: 获取后台管理员的详细信息
     * @param:
     * @return: Response
     */
    @Override
    public Response getAdminUserInfoById(Integer adminUserId) {
        return Response.success(adminUserMapper.getAdminUserInfoById(adminUserId));
    }

    /**
     * @Title: login
     * @Description: 登录后台管理系统
     * @param: adminUserQo
     * @return: Response
     */
    @Override
    public Response login(AdminUserQo adminUserQo) {
        //根据工号查找管理信息
        AdminUserDto info = this.adminUserMapper.getAdminUserInfoByNo(adminUserQo.getAdminUserNo());
        if (info == null){
            return Response.error("管理员账户不存在");
        }
        if (!info.getAdminUserPassword().equals(adminUserQo.getAdminUserPassword())){
            return Response.error("账号或密码不正确");
        }
        if (info.getStatusItype() == 2){
            return Response.error("账户已被冻结,请联系管理员");
        }
        String token= uuid();
        System.out.println(token);
        info.setAdminUserPassword(null);
        info.setToken(token);

        //设置15天有效期
        redisService.setAndExpire("user:token:"+token, JSON.toJSONString(info),60*60*24*15);
        //保存用户token
        redisService.setAndExpire("com:demo:interceptor:user:token:"+info.getAdminUserId(), token, 60*60*24*15);
        return Response.success(info);
    }
    /**
     * 生成uuid
     * @return uuid
     * */
    public static String uuid(){
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        return uuid;
    }
}
9.7编写对应的controller

AdminUserController

package com.demo.interceptor.controller;

import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.entity.bean.RestBase;
import com.demo.interceptor.entity.qo.AdminUserQo;
import com.demo.interceptor.service.AdminUserService;
import com.demo.interceptor.util.EncryptUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @className: AdminUserController
 * @description: 后台管理员
 * @author: demo
 * @create: 2021-03-30 17:07
 **/
@Slf4j
@RestController
@RequestMapping("adminUser")
public class AdminUserController extends RestBase {
    @Autowired
    private AdminUserService adminUserService;


    /**
    * @Title: getAdminUserInfo
    * @Description: 获取后台管理员的详细信息
    * @param:
    * @return: Response
    */
    @ApiOperation(httpMethod = "GET", value = "info", notes = "获取后台管理员的详细信息")
    @ResponseBody
    @RequestMapping(value = "info", method = RequestMethod.GET, produces = "application/json")
    public Response getAdminUserInfo() {
        log.info("userId:{}",super.getLoginUserID());
        return adminUserService.getAdminUserInfoById(super.getLoginUserID());
    }


    /**
    * @Title: login
    * @Description:  登录后台管理系统
    * @param:  adminUserQo
    * @return:  Response
    */
    @ApiOperation(httpMethod = "POST", value = "login", notes = "登录后台管理系统")
    @ResponseBody
    @RequestMapping(value = "login", method = RequestMethod.POST, produces = "application/json",consumes = "application/json")
    public Response login(final @RequestBody AdminUserQo adminUserQo) {
        log.info("adminUserQo:{}",adminUserQo);
        if (adminUserQo == null || StringUtils.isBlank(adminUserQo.getAdminUserNo()) || StringUtils.isBlank(adminUserQo.getAdminUserPassword())){
            return Response.error("传入参数不正确");
        }
        String userNo =adminUserQo.getAdminUserNo();
        String userPassword = EncryptUtil.MD5Encode(EncryptUtil.aesDecrypt(adminUserQo.getAdminUserPassword()));
        adminUserQo.setAdminUserNo(userNo);
        adminUserQo.setAdminUserPassword(userPassword);
        return  this.adminUserService.login(adminUserQo);

    }
}
9.8编写测试类,查看对应的密码进行编码后对应的密文
package com.demo.interceptor.controller;

import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.util.EncryptUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @className: TestController
 * @description:
 * @author: demo
 * @create: 2021-03-30 15:42
 **/
@RestController
@RequestMapping("test")
public class TestController {

    @ApiOperation(value = "hello",notes="测试",httpMethod = "GET")
    @ResponseBody
    @RequestMapping("hello")
    public Response test1(){
        System.out.println(EncryptUtil.aesEncrypt("abc123.."));
        return Response.success(EncryptUtil.aesEncrypt("abc123.."));
    }

    public static void main(String[] args) {
        System.out.println(EncryptUtil.aesEncrypt("123456.."));//加密
        System.out.println(EncryptUtil.aesDecrypt(EncryptUtil.aesEncrypt("123456..")));//解密
        System.out.println(EncryptUtil.MD5Encode("123456.."));//MD5加密
    }
}

在这里插入图片描述

9.9测试

1.启动项目
2.打开swagger-ui ,对应的链接http://localhost:10086/swagger-ui.html
3.据参数需求,传入对应的参数,(工号和加密后的密码)

在这里插入图片描述

4.根据返回的账号信息,获取到token和userId

在这里插入图片描述

5.根据返回的账号信息token和userId(adminUserId)查询账号信息

在这里插入图片描述

在这里插入图片描述

10.编写拦截器
package com.demo.interceptor.config;

import com.alibaba.fastjson.JSON;
import com.demo.interceptor.entity.bean.Response;
import com.demo.interceptor.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.regex.Pattern;



/**
 * @className: InterceptorConfig
 * @description: 拦截器
 * @author: demo
 * @create: 2021-03-30 15:59
 **/
@Slf4j
public class InterceptorConfig implements HandlerInterceptor {

    @Autowired
    private RedisService redisService;

    /**
     * 登录拦截器
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("=============start call obo =============");
        String requestUri = request.getRequestURI();
        String id = request.getHeader("userId");
        String token = request.getHeader("token");
        log.info("requestUri : {}, id : {}, token : {}", requestUri, id, token);
        int userId = 0;
        int tokenStatus = 0;
        if (!StringUtils.isBlank(id) && !StringUtils.isBlank(token) && isNumber(id)) {
            userId = Integer.parseInt(id);
            tokenStatus = redisService.isValidTokenAndUserId(userId, token);
        }
        // 过滤掉不需要验证的模块
        if (requestUri.indexOf("swagger") >= 0 ||
                requestUri.indexOf(".html") >= 0 ||
                requestUri.indexOf("login") >= 0 ||
                requestUri.indexOf("/common/upload") >= 0 ) {
            tokenStatus = 200;
        }
        if(tokenStatus != 200){
            String message = "";
            if (tokenStatus == 100){
                message = "您的账号已被冻结,请联系管理员";
            }else if (tokenStatus == 300){
                message = "您的账号已在另一台设备登录";
            }else if (tokenStatus == 400){
                message = "登录信息已过期,请重新登录";
            }else{
                message = "请登录后访问";
            }
            Response result = new Response();
            result.setCode(HttpStatus.UNAUTHORIZED.value());
            result.setMsg(message);
            writer(response, JSON.toJSONString(result));
            return false;
        }
        log.info("=============end call obo=============");
        response.addHeader("currentLoginUserId", String.valueOf(userId));
        response.addHeader("token", token);
        return true;
    }

    public void writer(HttpServletResponse response, String body){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        PrintWriter writer=null;
        try{
            writer=response.getWriter();
            writer.write(body);
            writer.flush();
            writer.close();
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    public static boolean isNumber(String str)
    {
        final Pattern pattern_number = Pattern.compile("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?$");
        Pattern pattern = pattern_number;
        return pattern.matcher(str).matches();
    }
}
11.在启动类中注册拦截器

1.启动类需要实现WebMvcConfigurer

2.需要重写WebMvcConfigurerddInterceptors方法

最后的启动类示例如下

package com.demo.interceptor;

import com.demo.interceptor.config.InterceptorConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @className: AdminApplication
 * @description:
 * @author: demo
 * @create: 2021-03-30 15:09
 **/
@SpringBootApplication
@MapperScan("com.demo.interceptor.mapper")
public class AdminApplication implements WebMvcConfigurer {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class,args);
    }


    @Bean
    public InterceptorConfig interceptorConfig(){
       return new InterceptorConfig();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptorConfig());
    }
}
12.测试拦截器功能

1.启动启动类

2.打开swagger-ui

3.使用获取用户详细信息来测试

3.1,如果token不一致,userId一致

测试结果如下

在这里插入图片描述

3.1,如果token一致,userId不一致

测试结果如下

在这里插入图片描述

3.1,如果token一致,userId一致

测试结果如下
(获取账户信息成功)

在这里插入图片描述

能够出现这些情况,证明拦截器功能实现

目录结构

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值