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

相关文章
|
11天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
29 0
|
18天前
|
缓存 监控 Java
|
18天前
|
缓存 监控 Java
|
19天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
34 1
|
14天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
11 0
|
17天前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
32 0
|
26天前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
46 0
|
安全 Java Android开发
SpringBoot 代码混淆方案 ProGuard
在软件开发中,代码混淆是故意创建人类难以理解的源代码或机器代码的行为。代码混淆处理修改了可部署的文件,因此黑客很难从中读取信息,但仍然保持完整的功能。这最初是为 android 平台引入的。它现在能够支持 SpringBoot 2。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
148 1
|
21天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
96 62