1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Javaを使ってSharePointへファイルをアップロードする

Posted at

はじめに

文中に出てくるMicrosoftのドキュメントを読めば何となく出来ると思いますが、若干躓いたのでメモします。

準備

Microsoft Graph Java SDK

今回はMicrosoft Graph Java SDKを使います。手順はMicrosoftのページに記載されています。
Microsoft Graph Java SDK をインストールする

クライアントID/クライアントシークレット生成(AzureAD)

この手順も既に色々な方が手順を記載しています。最近だと↓の記事が新しいでしょうか。
次世代のコラボレーション!Microsoft TeamsにChatGPTを組み込む方法

アクセス権は「file.readwrite.all」「sites.ReadWrite.all」が必要のようです。詳細はMicrosoftのページに記載されています。
DriveItem の内容をアップロードまたは置換する
https://learn.microsoft.com/ja-jp/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http

siteidの取得

ファイルをアップロードしたいサイトを一意に示すIDがsiteidのようです。siteidはSharePoint管理センターとかで、URLに表示されますが、Graph Explorerを使って取得することができます。

Graph Explorerにブラウザでアクセスしてログインします。
https://developer.microsoft.com/en-us/graph/graph-explorer

以下のURLをGETでリクエストします。

https://graph.microsoft.com/v1.0/sites/<hostname>.sharepoint.com:/sites/<sitename>

サイトのURLが以下の場合は、

https://XXXXX.sharepoint.com/sites/YYYYY

リクエストするURLは以下になります。

https://graph.microsoft.com/v1.0/sites/XXXXX.sharepoint.com:/sites/YYYYY

以下のJSONがレスポンスされます。

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites/$entity",
    "createdDateTime": "2017-11-10T00:57:10.92Z",
    "description": "*****",
    "id": "*****.sharepoint.com,16bc4df0-7e1a-4cec-9ade-86f56a8e9b6e,320ed486-518c-4495-8997-1af19888f3c6",
    "lastModifiedDateTime": "2023-05-02T08:38:46Z",
    "name": "zangyo",
    "webUrl": "https://*****.sharepoint.com/sites/*****",
    "displayName": "*****",
    "root": {},
    "siteCollection": {
        "hostname": "*****.sharepoint.com"
    }
}

上から5行目のIDにsiteidが含まれています。

"id": "*****.sharepoint.com,16bc4df0-7e1a-4cec-9ade-******,320ed486-518c-4495-8997-1a*****",

カンマ区切りの2つ目の「16bc〜」がsiteidになります。

実装

SDKにはファイルサイズが小さい用と大きい用の2つが用意されています。何をもって小さい大きいのかよく分からなかったです。

ファイルサイズが小さい場合

Microsoftのドキュメントにサンプルが載っていますが、サンプルでは自分のOneDriveにアップロードする場合なので、SharePointでは若干変更が必要です。

DriveItem の内容をアップロードまたは置換する
https://learn.microsoft.com/ja-jp/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=java

import java.io.FileInputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;

import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.requests.GraphServiceClient;

public class SharePointUploadTest {

	public static void main(String[] args) throws IOException {

		final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
		        .clientId("<クライアントID>")
		        .clientSecret("<クライアントシークレット>")
		        .tenantId("<テナントID>")
		        .build();

		final TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(clientSecretCredential);

		GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( tokenCredentialAuthProvider ).buildClient();

		FileInputStream inputStream = new FileInputStream("<アップロードするファイルパス>");
        byte[] stream = IOUtils.toByteArray(inputStream);

        String siteid = "<siteid>";
		graphClient.sites().byId(siteid).drive().root().itemWithPath("<アップロード先フォルダ&ファイル名>").content().buildRequest().put(stream);
	}
}

サイトの「Shared Documents」がルートになるようなので、以降のパスを指定します。
「/hoge/hoge1.png」この場合は「Shared Documents/hoge/hoge1.png」にアップロードされます。

  • 指定されたフォルダが存在しない場合は自動で作成される。
  • 同名ファイルが存在した場合は上書き

このサンプルソースで130MBのファイルをアップロードしたところ正常終了しました。Javaヒープサイズ次第なような気がしますが。

ファイルサイズが大きい場合

再開可能なAPI(UploadSession)が用意されており、ファイルサイズが大きい場合はこちらを使用します。Javaの場合は再開機能はサポートされていないようです。
UploadSessionを使うと、チャンクな感じでアップロードすることができます。

driveItem: createUploadSession
https://learn.microsoft.com/ja-jp/graph/api/driveitem-createuploadsession?view=graph-rest-1.0&preserve-view=true

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.models.DriveItem;
import com.microsoft.graph.models.DriveItemCreateUploadSessionParameterSet;
import com.microsoft.graph.models.DriveItemUploadableProperties;
import com.microsoft.graph.models.UploadSession;
import com.microsoft.graph.requests.GraphServiceClient;
import com.microsoft.graph.tasks.IProgressCallback;
import com.microsoft.graph.tasks.LargeFileUploadTask;

public class SharePointUploadTest2 {

	public static void main(String[] args) throws IOException {

		final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
		        .clientId("<クライアントID>")
		        .clientSecret("<クライアントシークレット>")
		        .tenantId("<テナントID>")
		        .build();

		final TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(clientSecretCredential);

		GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( tokenCredentialAuthProvider ).buildClient();

		File file = new File("<アップロードするファイルパス>");
		FileInputStream inputStream = new FileInputStream(file);

		IProgressCallback callback = new IProgressCallback() {
		    @Override
		    public void progress(final long current, final long max) {
		        System.out.println(
		            String.format("Uploaded %d bytes of %d total bytes", current, max)
		        );
		    }
		};

		DriveItemCreateUploadSessionParameterSet uploadParams =
			    DriveItemCreateUploadSessionParameterSet.newBuilder()
			        .withItem(new DriveItemUploadableProperties()).build();


		UploadSession uploadSession = graphClient.sites().byId("<siteid>").drive().root()
				.itemWithPath("<アップロード先フォルダ&ファイル名>")
				.createUploadSession(uploadParams)
				.buildRequest().post();

		LargeFileUploadTask<DriveItem> largeFileUploadTask =
			    new LargeFileUploadTask<DriveItem>
			        (uploadSession, graphClient, inputStream, file.length(), DriveItem.class);
		largeFileUploadTask.upload(0, null, callback);
	}
}

Microsoftのサンプルをサイト指定にしただけで、あとは殆ど変更していません。

終わりに

サンプルを見ればすぐ出来ますが、今回はsiteidの取得の仕方で大分悩みました。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?