SpringBoot实现OneDrive文件上传

news2025/6/27 10:25:43

SpringBoot实现OneDrive文件上传

源码

OneDriveUpload: SpringBoot实现OneDrive文件上传

获取accessToken步骤

参考文档:针对 OneDrive API 的 Microsoft 帐户授权 - OneDrive dev center | Microsoft Learn

1.访问Azure创建应用Microsoft Azure,使用微软账号进行登录即可!

2.进入应用创建密码

3.获取code

通过访问(必须用浏览器,通过地址栏输入的方式):https://login.live.com/oauth20_authorize.srf?client_id=你的应用程序(客户端) ID&scope=files.readwrite offline_access&response_type=code&redirect_uri=http://localhost:8080/redirectUri

以上步骤都正确的情况下,会在地址栏返回一个code,也就是M.C105.........

4.获取accessToken

拿到code后就可以拿token了,通过对https://login.live.com/oauth20_token.srf 发起POST请求并传递相关参数,这一步需要用接口调试工具完成!

其中client_id和redirect_uri与上面相同,client_secret填刚刚创建的密钥,code就是刚刚获取到的codegrant_type就填authorization_code即可!

正常情况下访问后就能得到access_token,然后把access_token放在springboot的配置文件中!

代码实现步骤

1. 新建一个springBoot项目,选择web依赖即可!

 2. 引入相关依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.0</version>
        </dependency>

3.编写文件上传接口类

参考文档:上传小文件 - OneDrive API - OneDrive dev center | Microsoft Learn

import com.alibaba.fastjson.JSONObject;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * 文件上传到OneDrive并将文件信息存储到Excel文件中
 */
@Controller
public class FileSyncController {
    private static final Logger logger = LoggerFactory.getLogger(FileSyncController.class);
    private static final String ONE_DRIVE_BASE_URL = "https://graph.microsoft.com/v1.0/me/drive/root:/uploadfile/";

    @Value("${onedrive.access-token}")
    private String ACCESS_TOKEN;


    @PostMapping("/upload")
    public void uploadFileToDrive(@RequestParam("file") MultipartFile file, HttpServletResponse httpServletResponse) throws IOException {
        if (file.isEmpty()) {
            throw new RuntimeException("文件为空!");
        }

        String fileName = file.getOriginalFilename();
        String oneDriveUploadUrl = ONE_DRIVE_BASE_URL + fileName + ":/content";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setBearerAuth(ACCESS_TOKEN);

        HttpEntity<byte[]> requestEntity;
        try {
            byte[] fileBytes = file.getBytes();
            requestEntity = new HttpEntity<>(fileBytes, headers);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.exchange(oneDriveUploadUrl, HttpMethod.PUT, requestEntity, String.class);

        if (response.getStatusCode() == HttpStatus.CREATED) {
            //解析返回的JSON字符串,获取文件路径
            String downloadUrl = JSONObject.parseObject(response.getBody()).getString("@microsoft.graph.downloadUrl");
            storeFileInfoToExcel(fileName, downloadUrl);
            logger.info("文件上传成功,OneDrive 文件路径:" + downloadUrl);
            httpServletResponse.setCharacterEncoding("utf-8");
            httpServletResponse.setContentType("text/html;charset=utf-8");
            PrintWriter out = httpServletResponse.getWriter();
            out.print("<script> alert('" + fileName + "已上传成功!');window.location.href='file_info.xlsx';</script>");
        } else {
            throw new RuntimeException("文件上传失败!");
        }
    }

    /**
     * 将文件信息存储到Excel文件中
     *
     * @param filename 文件名称
     * @param filepath 文件路径
     */
    private void storeFileInfoToExcel(String filename, String filepath) {
        try {
            File file = new File(ResourceUtils.getURL("classpath:").getPath() + "/static/file_info.xlsx");

            XSSFWorkbook excel;
            XSSFSheet sheet;
            FileOutputStream out;

            // 如果文件存在,则读取已有数据
            if (file.exists()) {
                FileInputStream fis = new FileInputStream(file);
                excel = new XSSFWorkbook(fis);
                sheet = excel.getSheetAt(0);
                fis.close();
            } else {
                // 如果文件不存在,则创建一个新的工作簿和工作表
                excel = new XSSFWorkbook();
                sheet = excel.createSheet("file_info");
                // 创建表头
                XSSFRow headerRow = sheet.createRow(0);
                headerRow.createCell(0).setCellValue("文件名称");
                headerRow.createCell(1).setCellValue("文件路径");
            }

            // 获取下一个行号
            int rowNum = sheet.getLastRowNum() + 1;
            // 创建新行
            XSSFRow newRow = sheet.createRow(rowNum);
            newRow.createCell(0).setCellValue(filename);
            newRow.createCell(1).setCellValue(filepath);

            // 将数据写入到文件
            out = new FileOutputStream(file);
            excel.write(out);

            // 关闭资源
            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

4.编写认证回调接口类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedirectController {

    /**
     * 回调地址
     * http://localhost:8080/redirectUri?code=M.C105_BL2.2.127d6530-7077-3bcd-081e-49be3abc3b45
     *
     * @param code
     * @return
     */
    @GetMapping("/redirectUri")
    public String redirectUri(String code) {
        return code;
    }
}

5.编写application.properties配置文件

# 应用服务 WEB 访问端口
server.port=8080
#OneDrive的ACCESS_TOKEN
onedrive.access-token=你的ACCESS_TOKEN

6.编写启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OneDriveUploadApplication {

    public static void main(String[] args) {
        SpringApplication.run(OneDriveUploadApplication.class, args);
    }

}

7.编写上传页面,放在resources的static目录中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<div align="center">
    <h1>文件上传</h1>
    <form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file"><br><br>
        <input type="submit" value="提交">
    </form>
</div>
</body>
</html>

8.启动项目,访问http://localhost:8080/进行测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1453592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt的安装

下载安装包 我们选择Open Source的版本。 可以从https://www.qt.io/download-open-source直接下载最新版本&#xff0c;对于想要选择特定版本&#xff0c;或者尝试beta版功能的用户&#xff0c;也可以从https://download.qt.io选择自己需要的版本。 如果你的网速可以的话&am…

语音唤醒——

文章目录 配置主代码 参考文档&#xff1a;https://picovoice.ai/docs/quick-start/porcupine-python/ 配置 pip install pvporcupine主代码 ACCESS_KEY&#xff1a;需要将该参数填入即可 # # Copyright 2018-2023 Picovoice Inc. # # You may not use this file except in …

前端开发,Vue的双向数据绑定的原理

目录 一、什么是前端 二、Vue.JS框架 三、双向数据绑定 四、Vue的双向数据绑定的原理 一、什么是前端 前端通常指的是网页或应用程序中用户直接交互和感知的部分&#xff0c;也称为客户端。前端开发涉及使用HTML、CSS和JavaScript等技术来构建用户界面和交互功能。前端开发…

个人 AI 的革命:Nvidia‘s Chat with RTX 深度探索

个人 AI 的革命&#xff1a;Nvidias Chat with RTX 深度探索 Nvidia 推出的 Chat with RTX 预示着个人 AI 新时代的到来。2 月 13 日&#xff0c;Nvidia 官宣了自家的 AI 聊天机器人&#xff0c;这不仅是人工智能交互的渐进式改进&#xff1b;更代表了个人如何利用自己的数据进…

ubuntu 22.04.3 live server安装JDK21与远程编程环境

ubuntu 22.04.3 live server安装JDK21与远程编程环境 一、安装jdk21 解压jdk压缩包&#xff0c;命令&#xff1a; tar -zxvf jdk-21_linux-x64_bin.tar.gz打开环境变量&#xff0c;命令&#xff1a; sudo vim /etc/profile配置环境变量 export JAVA_HOME/root/jdk-21.0.2 …

javaweb学习day03(JS+DOM)

一、javascript入门 1 官方文档 地址: https://www.w3school.com.cn/js/index.asp离线文档: W3School 离线手册(2017.03.11 版).chm 2 基本说明 JavaScript 能改变 HTML 内容&#xff0c;能改变 HTML 属性&#xff0c;能改变 HTML 样式 (CSS)&#xff0c;能完成 页面的数据…

18-k8s控制器资源-cronjob控制器

job控制器是执行完一次任务&#xff0c;就结束&#xff1b; cronjob控制器&#xff0c;是基于job控制器&#xff0c;定期频率性执行任务&#xff1b;等同于linux系统中的crontab一样&#xff1b; 1&#xff0c;编辑cronjob资源清单 [rootk8s231 pi]# vim cronjob.yaml apiVers…

Dynamo之视图过滤器介绍

你好&#xff0c;这里是BIM的乐趣&#xff0c;我是九哥~ 今天简单整理一篇&#xff0c;源于最近很多人给我留言&#xff0c;问如何添加过滤器&#xff0c;那么我就简单把视图过滤器这块的节点及其用法整理下&#xff0c;基本上自带的节点就够用了。 获取项目中的所有视图过滤器…

《剑指 Offer》专项突破版 - 面试题 48 : 序列化和反序列化二叉树(C++ 实现)

目录 前言 一、序列化二叉树 二、反序列化二叉树 前言 题目链接&#xff1a;LCR 048. 二叉树的序列化与反序列化 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 请设计一个算法将二叉树序列化成一个字符串&#xff0c;并能将该字符串反序列化出原来的二叉树。…

【c++】const引用

Hello everybody!今天给大家讲讲有关const引用部分的知识&#xff0c;因为这部分知识涉及到const与引用直接如何灵活的运用&#xff0c;且不太好理解。所以我认为讲一下这里的知识还是很有必要的&#xff01; 1.权限可缩小 首先&#xff0c;当我们定义了a&#xff0c;在给a取别…

JAVA面试题并发篇

1. 线程状态 要求 掌握 Java 线程六种状态 掌握 Java 线程状态转换 能理解五种状态与六种状态两种说法的区别 六种状态及转换 分别是 新建 当一个线程对象被创建&#xff0c;但还未调用 start 方法时处于新建状态 此时未与操作系统底层线程关联 可运行 调用了 start 方法…

Vue2:组件间通信框架Vuex

一、原理图及作用 功能介绍&#xff1a; 简单说就是Vue项目中&#xff0c;各个组件间通信的一种框架 相较于之前的全局事件总线&#xff0c;该框架更实用&#xff01; 提高了代码的复用率&#xff0c;把核心业务代码&#xff0c;集中到store中&#xff0c;这样&#xff0c;一处…

【机器学习笔记】 6 机器学习库Scikit-learn

Scikit-learn概述 Scikit-learn是基于NumPy、 SciPy和 Matplotlib的开源Python机器学习包,它封装了一系列数据预处理、机器学习算法、模型选择等工具,是数据分析师首选的机器学习工具包。 自2007年发布以来&#xff0c;scikit-learn已经成为Python重要的机器学习库了&#xff…

由斐波那契数列探究递推与递归

斐波那契数列定义&#xff1a; 斐波那契数列大家都非常熟悉。它的定义是&#xff1a; 对于给定的整数 x &#xff0c;我们希望求出&#xff1a; f ( 1 ) f ( 2 ) … f ( x ) f(1)f(2)…f(x) f(1)f(2)…f(x) 的值。 有两种方法,分别是递推(迭代)与递归 具体解释如下图 备注…

Linux学习——静态库与动态库的打包

目录 ​编辑 一&#xff0c;动静态库介绍 1&#xff0c;动静态库的特点 二&#xff0c;静态库的打包 计算器示例 编译&#xff1a; 1&#xff0c;直接编译 2&#xff0c;打包 三&#xff0c;动态库打包 计算器示例&#xff1a;同上 编译&#xff1a; 1&#xff0c;直…

模拟算法.

1.什么是模拟 在信息奥赛中,有一类问题是模拟一个游戏的对弈过程或者模拟一项任务的操作过程.比如乒乓球在比赛中模拟统计记分最终判断输赢的过程等等,这些问题通常很难通过建立数学模型用特定的算法来解决因为它没有一种固定的解法,需要深刻理解出题者对过程的解释一般只能采…

蓝桥杯备赛_python_BFS搜索算法_刷题学习笔记

1 bfs广度优先搜索 1.1 是什么 1.2怎么实现 2案例学习 2.1.走迷宫 2.2.P1443 马的遍历 2.3. 九宫重排&#xff08;看答案学的&#xff0c;实在写不来&#xff09; 2.4.青蛙跳杯子&#xff08;学完九宫重排再做bingo&#xff09; 2.5. 长草 3.总结 1 bfs广度优先搜索 【P…

六、Spring/Spring Boot整合ActiveMQ

Spring/Spring Boot整合ActiveMQ 一、Spring整合ActiveMQ1.pom.xml2.Queue - 队列2.1 applicationContext.xml2.2 生产者2.3 消费者 3.Topic - 主题3.1 applicationContext.xml3.2 生产者3.3 消费者 4.消费者 - 监听器4.1 编写监听器类4.2 配置监听器4.3 生产者消费者一体 二、…

基于PPNSA+扰动算子的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于PPNSA扰动算子的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图和优化收敛曲线。 2.测试软件版本以及运行结果展示 MATLAB2022a版本运行…

Java毕业设计-基于ssm的网上餐厅管理系统-第72期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于ssm的网上餐厅管理系统&#xff1a;前端jsp、jquery、bootstrap&#xff0c;后端 maven、springmvc、spring、mybatis&#xff0c;集成类名管理、菜品管理、订单管理…