大事件Day04

文件上传的接口

实现这个接口,参数为文件

后端MultipartFile

String getOriginalFilename(); //获取原始文件名

void transferTo(File dest): 将接收的文件转存到磁盘文件中

long getSize(): //获取文件的大小

byte[] getBytes(); //获取文件内容的字节数组

InputStream getInputStream(); //获取接收到的文件内容的输入流

首先我们先存到本地磁盘上,首先我们现在桌面上创一个文件,然后复制地址,调用multipartfile的方法tranfer把文件存储到本地磁盘中,然后再用上文件名即可

但是我们会发现,两个相同的文件名上传,就会发生覆盖,但是现实中,一个人和另一个上传相同的文件不应该发生覆盖,所以我们需要调用UUID.randomUUID().tostring,去生成一个唯一的名字,这样就不会发生覆盖

但是存到本地磁盘有两个问题

1.就是传到到本地磁盘无法被访问

2.磁盘的内存有限

那么怎么解决呢,就是用云存储即可,这里使用阿里云的云存储

使用阿里云,就需要导入阿里云的坐标

那么之后就是怎么把它结合到应用,那就是类似于JWT令牌,定义一个AliOssUtil工具类,用的时候就是直接调用,那么问题又来了,怎么把改成一个工具类

复制代码
package com.itheima.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

import java.io.FileInputStream;
import java.io.InputStream;

public class AliOssUtil {

    // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
    private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";
    // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    //EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
    private static final String ACCESS_KEY_ID="LTAI5tKYCrJCKZCXae36CXL7";
    private static final String ACCESS_KEY_SECRET="xz85iw7sTBd7aA6dw3YTVeyxccbgta";
    // 填写Bucket名称,例如examplebucket。
    private static final String BUCKETNAME= "big-event99999";

    public static String uploadFile(String objectName, InputStream in) throws Exception {


        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-beijing";

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(ENDPOINT)
                .credentialsProvider(new DefaultCredentialProvider(ACCESS_KEY_ID, ACCESS_KEY_SECRET))
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        String url="https://"+BUCKETNAME+"."+region+".aliyuncs.com/"+objectName;
        try {
            // 填写字符串。
            String content = "Hello OSS,你好世界";



            // 创建PutObjectRequest对象。
            // 修正后(补全括号 + 直接使用FileInputStream)
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    BUCKETNAME,
                    objectName,
                    in
            );
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传字符串。
            PutObjectResult result = ossClient.putObject(putObjectRequest);


        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return url;
    }
}

结果如上,首先把那种固定不变的变成static,比如BuckerName,密钥账号和密码这种的,这些都是固定的,直接private static final,那么什么会变就变成参数,就是传入的图片objectName以及它的输入流,所以我们要把他们变成参数,同时名字变得更加符合参数

看我们Controller层

再次含UUID就是让存进去的图片的名字具有唯一性,避免覆盖这种情况,,然后在调用工具类,我们需要传的参数一个文件的名字,另一个就是本文件的输入流,这个参数直接调用multipartFile的方法 getInputStream()

接下来就是登录的时候是否又问题

首先,我们先进行登录之后

然后把这个JWT令牌记住,然后再次进行修改密码

再次登录之后

这次它再次给了我们一个JWT令牌,但是我们不用,我们依旧用上一个旧JWT令牌,然后就会惊奇的发现,我们用一个旧的JWT令牌依然能访问,那么就会出现问题,那怎么解决这个问题

redis解决这个问题

就相当于每次执行一些其他的请求的时候,用JWT令牌和Redis里的令牌进行比较,如果一样,则进行下一步,不一样则不通过,类似于古代的虎符

那么开始操作

先导入坐标,并且完成配置之后、

首先先进行登录之后,我们要把token存到Redis中,那么进行操作

首先先创建一个对象 StringRedisTemplate

复制代码
//把token存储到Redis中
ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
operations.set(token,token,1, TimeUnit.HOURS);

并且我们还把令牌设置有效的时间一样即可,然后就是拦截的时候,每次拦都需要Redis里有没有这些token,

如果Redis里面没有,那么就会报错

最后就是更新密码的时候,我们就需要把旧的令牌去掉,这里可以把获取token令牌的方式优化一下就是我们还记得不记得每次请求中都还有JWT令牌,所以我们科已从请求头中获取(这也是拦截器实现的机制)

完成即可

SpringBoot项目部署

为什么要进行项目部署呢,就是,我们要在自己的电脑开发,那么开发完怎么让别人正常使用呢,就是部署到服务器上

先打包

在本文件中运行cmd

运行之前先把本地的停了再用

相关推荐
kokunka几秒前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
C雨后彩虹4 分钟前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
云栖梦泽1 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言
java1234_小锋1 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
铅笔侠_小龙虾1 小时前
Flutter Demo
开发语言·javascript·flutter
2501_944525541 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐1 小时前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
福大大架构师每日一题2 小时前
ComfyUI v0.11.1正式发布:新增开发者专属节点支持、API节点强化、Python 3.14兼容性更新等全方位优化!
开发语言·python
wangdaoyin20102 小时前
若依vue2前后端分离集成flowable
开发语言·前端·javascript