SpringBoot实现OneDrive文件上传

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就是刚刚获取到的code,grant_type就填authorization_code即可!

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

代码实现步骤

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

2. 引入相关依赖

XML 复制代码
        <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

java 复制代码
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.编写认证回调接口类

java 复制代码
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配置文件

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

6.编写启动类

java 复制代码
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目录中

html 复制代码
<!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/进行测试

相关推荐
钱栈up8 分钟前
VSCode 调试多模块 Maven + Spring Boot 后端:从启动失败到一次跑通
java·spring boot·maven
uoKent9 分钟前
c++中new和malloc的区别
java·jvm·c++
超超不吵吵10 分钟前
Java AI转型实战(十):Agent 智能体初探
后端
十五喵源码网19 分钟前
基于springboot2+vue2的疾病防控综合系统
java·毕业设计·springboot·论文笔记
步行cgn23 分钟前
@AllArgsConstructor 是 Lombok 提供的注解
后端
砚底藏山河25 分钟前
【量化纯GET实战 #11】移动均线 MA:5 日 20 日 60 日怎么算怎么用
java·python·金融·maven
柠檬味拥抱26 分钟前
鸿蒙原生 AI 应用开发实战:用蓝耘 MaaS 给纪念日 App 装上「大模型大脑」
后端
步行cgn29 分钟前
Lombok 详解:通过注解消除样板代码
后端
用户411800341534129 分钟前
MySql 事务和锁
后端
一只小闪闪37 分钟前
easy-trans java数据通用翻译框架v2.3.0
java·后端·架构