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里面

相关文章
|
1天前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
8天前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
103 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
4天前
|
消息中间件 Java 大数据
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
24 2
|
6天前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
74 2
|
4天前
|
SQL JSON 缓存
你了解 SpringBoot 在一次 http 请求中耗费了多少内存吗?
在工作中常需进行全链路压测并优化JVM参数。通过实验可精确计算特定并发下所需的堆内存,并结合JVM新生代大小估算GC频率,进而优化系统。实验基于SpringBoot应用,利用JMeter模拟并发请求,分析GC日志得出:单次HTTP请求平均消耗约34KB堆内存。复杂环境下,如公司线上环境,单次RPC请求内存消耗可达0.5MB至1MB,揭示了高并发场景下的内存管理挑战。
|
5天前
|
消息中间件 存储 NoSQL
python 使用redis实现支持优先级的消息队列详细说明和代码
python 使用redis实现支持优先级的消息队列详细说明和代码
16 0
|
2月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
164 0
|
5月前
|
安全 数据安全/隐私保护
Springboot+Spring security +jwt认证+动态授权
Springboot+Spring security +jwt认证+动态授权
192 0
|
3月前
|
JSON 安全 Java
使用Spring Boot和JWT实现用户认证
使用Spring Boot和JWT实现用户认证