springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)

简介: 该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。

前言

本文将深入探讨 JWT(JSON Web Token)的组成与使用,以及 Redis 的依赖配置和文件操作功能。此外,我们还将列举一些常见的 HTTP 请求错误代码,并详细解释 @RequestParam 与 @PathVariable 等参数注解的区别与用法。

jwt

组成

一个token 有 3 部分
头部 (header)
载荷 (plyload)
签证 (signature)
三部分 之间 用 . 号 分隔

依赖

<!--jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>

创建工具类

@Component
public class TokenUtils {
    /**
     * 返回的 则为生成的token
     */
    public static String genToken(String userId, String sign) {
        return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面,作为载荷
                .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小时后token过期
                .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
    }
}
String token = TokenUtils.genToken(one.getId().toString(), one.getPassword());
            userDTO.setToken(token);

拦截器

package com.example.springboot.utils.intercepter;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.springboot.common.Constants;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.pojo.User;
import com.example.springboot.server.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 前端的 token
        String token = request.getHeader("token");
//         如果 不是 映射方法  则 直接 通过
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
//         执行 认证
        if(StrUtil.isBlank(token)){
            throw new ServiceException(Constants.CODE_401,"无token,请重新登录");
        }
//         获取 token 的 user id
         String userId;
        try{
            userId= JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录");
        }
        User user = userService.getById(userId);
        if(user == null){
            throw new ServiceException(Constants.CODE_401,"用户不存在,请重新登录");
        }
//      用户密码 加 签   验证 token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try{
            jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录");
        }
        return true;
    }
}

配置类

package com.example.springboot.config;
import com.example.springboot.utils.intercepter.JwtInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//          需要通过 注入  的 方式
        registry.addInterceptor(jwtInterceptor2())
                .addPathPatterns("/**")  // 拦截所有请求,通过判断token是否合法来决定是否需要登录
                .excludePathPatterns("/user/login", "/user/register", "/**/export", "/**/import","/echarts/example");
    }
//     创建一个bean
    @Bean
    public JwtInterceptor jwtInterceptor2(){
        return new JwtInterceptor();
    }
}

redis

依赖

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

在yaml 里面 使用

spring: 
redis:
    host: 127.0.0.1
    password: 123456
    port: 6379
    database: 1


文件操作


fileMapper


package com.example.springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot.pojo.Files;
public interface FileMapper extends BaseMapper<Files> {
}

upload

yaml

编辑 储存 文件 的 路径

files:
  upload:
    path: E:/springBootLearn/sys_file/

导入路径

@Value("${files.upload.path}")
    private  String fileUploadPath;

使用

@PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws IOException {
//          文件  名字
        String originFileName = file.getOriginalFilename();
//          类型
        String type = FileUtil.extName(originFileName);
//        大小
        long size = file.getSize();
//         判断 配置的文件 路径 是否 存在  不存在则 新建
        File uploadParentFile = new File(fileUploadPath);
        if(!uploadParentFile.exists()){
            uploadParentFile.mkdirs();
        }
//         定义 一个 文件  唯一 的 标识码
        String uuid = IdUtil.fastSimpleUUID();
        File uploadFile = new File(fileUploadPath + uuid + StrUtil.DOT + type);
//          把 获取  到 的文件 存到 磁盘
        file.transferTo(uploadFile);
        return "成功";
    }

hutool

<!--        hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

优化 使用上 MD5 来 判断 文件 唯一性

//          通过文件的MD5 查询文件
     private  Files getFileByMd5(String md5){
//         查询数据库中 的 md5
         QueryWrapper<Files> queryWrapper =  new QueryWrapper<>();
         queryWrapper.eq("md5", md5);
         List<Files> filesList = fileMapper.selectList(queryWrapper);
         return filesList.size() == 0 ? null : filesList.get(0);
     }


down

//     文件下载 路径 和 对应的接口是一样 的
//    String url = "http://localhost:8081/file/"+fileUUID;
//     uuid  id
        @GetMapping("/{fileUUID}")
    public  void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
//         设置 文件 唯一 标识码  获取文件
            File uploadFile = new File(fileUploadPath + fileUUID);
            //             设置文件 输出 流 格式
            ServletOutputStream out=response.getOutputStream();
            response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileUUID, StandardCharsets.UTF_8));
            response.setContentType("application/octet-stream");
//             读取文件 字节 流
            out.write(FileUtil.readBytes(uploadFile));
            out.flush();
            out.close();
        }
}

删除和批量删除

//  删除
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id){
       // 在 类中找到 唯一的 id
        Files files= fileMapper.selectById(id);
        // 将文件删除 设置为 true
        files.setIsDelete(true);
      //  更新 数据  
        fileMapper.updateById(files);
        return Result.success();
    }


//   批量删除
    @PostMapping("/del/batch")
//    select * from  sys_file  where id in (id,id,id)
    public Result deleteBatch(@RequestBody List<Integer>ids){ //[1,2,3]
//          实例化一个 查函数的方法
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
//         id in id   查 找 选择的 id
        queryWrapper.in("id",ids);
//          查找函数   一个 列表
        List<Files> files = fileMapper.selectList(queryWrapper);
        for (Files file : files)
        {
//             选中 的 都 设置 为 true
            file.setIsDelete(true);
//              将 选中 的 id  都 更新
            fileMapper.updateById(file);
        }
            return Result.success();
    }

取用或 不取用

//  更新enable 字段
    @PostMapping("/update")
    public Result update(@RequestBody Files files){
//         新增或则 更新 都在里面
        return Result.success(fileMapper.updateById(files));
    }

常见请求错误代码

400  请求无效,服务器无法处理 
401  未经  授权,无身份验证
403  服务器 拒绝请求,没有权限
404  请求资源 不存在 
405  请求 方法不允许,使用了错误的请求方式
408  请求超时
500  服务器错误
503  服务器暂时无法处理 请求
也可以自定义

参数注解

@RequestParam@PathVariable 注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是@RequestParam 是从request里面拿取值,而 @PathVariable 是从一个URI模板里面来填充

@RequestParam
看下面一段代码:
http://localhost:8080/springmvc/hello/101?param1=10&param2=20
根据上面的这个URL,你可以用这样的方式来进行获取
public String getDetails(
    @RequestParam(value="param1", required=true) String param1,
        @RequestParam(value="param2", required=false) String param2){}
@RequestParam 支持下面四种参数
defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
name 绑定本次参数的名称,要跟URL上面的一样
required 这个参数是不是必须的
value 跟name一样的作用,是name属性的一个别名
@PathVariable
这个注解能够识别URL里面的一个模板,我们看下面的一个URL
http://localhost:8080/springmvc/hello/101?param1=10&param2=20
1
上面的一个url你可以这样写:
@RequestMapping("/hello/{id}")
    public String getDetails(@PathVariable(value="id") String id,
    @RequestParam(value="param1", required=true) String param1,
    @RequestParam(value="param2", required=false) String param2){}
@PathParam
这个注解是和spring的pathVariable是一样的,也是基于模板的,但是这个是jboss包下面的一个实现,上面的是spring的一个实现,都要导包
@QueryParam
@QueryParam 是 JAX-RS 本来就提供的,和Spring的RequestParam作用一致
@ResponseBody
responseBody表示服务器返回的时候以一种什么样的方式进行返回, 将内容或对象作为 HTTP 响应正文返回,值有很多,一般设定为json
@RequestBody
一般是post请求的时候才会使用这个请求,把参数丢在requestbody里面

相关文章
|
6月前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
235 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
6月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
437 79
|
7月前
|
NoSQL Java Redis
Springboot使用Redis实现分布式锁
通过这些步骤和示例,您可以系统地了解如何在Spring Boot中使用Redis实现分布式锁,并在实际项目中应用。希望这些内容对您的学习和工作有所帮助。
605 83
|
3月前
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
216 0
|
6月前
|
存储 人工智能 NoSQL
SpringBoot整合Redis、ApacheSolr和SpringSession
本文介绍了如何使用SpringBoot整合Redis、ApacheSolr和SpringSession。SpringBoot以其便捷的配置方式受到开发者青睐,通过引入对应的starter依赖,可轻松实现功能整合。对于Redis,可通过配置RedisSentinel实现高可用;SpringSession则提供集群Session管理,支持多种存储方式如Redis;整合ApacheSolr时,借助Zookeeper搭建SolrCloud提高可用性。文中详细说明了各组件的配置步骤与代码示例,方便开发者快速上手。
103 11
|
6月前
|
Java 测试技术 Spring
SpringBoot+@Async注解一起用,速度提升
本文介绍了异步调用在高并发Web应用性能优化中的重要性,对比了同步与异步调用的区别。同步调用按顺序执行,每一步需等待上一步完成;而异步调用无需等待,可提升效率。通过Spring Boot示例,使用@Async注解实现异步任务,并借助Future对象处理异步回调,有效减少程序运行时间。
158 3
|
7月前
|
监控 Java Spring
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
212 16
|
6月前
|
NoSQL Java API
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Spring Boot 集成 Redis
本文介绍了在Spring Boot中集成Redis的方法,包括依赖导入、Redis配置及常用API的使用。通过导入`spring-boot-starter-data-redis`依赖和配置`application.yml`文件,可轻松实现Redis集成。文中详细讲解了StringRedisTemplate的使用,适用于字符串操作,并结合FastJSON将实体类转换为JSON存储。还展示了Redis的string、hash和list类型的操作示例。最后总结了Redis在缓存和高并发场景中的应用价值,并提供课程源代码下载链接。
1480 0
|
6月前
|
NoSQL Java Redis
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 安装
本教程介绍在 VMware 虚拟机(CentOS 7)或阿里云服务器中安装 Redis 的过程,包括安装 gcc 编译环境、下载 Redis(官网或 wget)、解压安装、修改配置文件(如 bind、daemonize、requirepass 等设置)、启动 Redis 服务及测试客户端连接。通过 set 和 get 命令验证安装是否成功。适用于初学者快速上手 Redis 部署。
121 0