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/进行测试

相关推荐
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸5 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了6 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·6 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王7 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康7 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
qq_17448285757 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
转世成为计算机大神7 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式