すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:アップロードコールバック

最終更新日:Jun 27, 2025

オブジェクトがアップロードされた後、Object Storage Service (OSS) はアプリケーションサーバーにコールバックリクエストを送信できます。コールバックを実装するには、関連するコールバックパラメーターを含むリクエストを OSS に送信するだけです。

使用上の注意

  • このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントが使用されています。同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスするには、内部エンドポイントを使用します。サポートされているリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。

  • このトピックでは、アクセス認証情報は環境変数から取得されます。アクセス認証情報を設定する方法の詳細については、「アクセス認証情報を設定する」をご参照ください。

  • このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスが作成されます。カスタムドメイン名または Security Token Service (STS) を使用して OSSClient インスタンスを作成する場合は、「一般的なシナリオの設定例」をご参照ください。

サンプルコード

単純なアップロードタスクのアップロードコールバックを設定する

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.Callback;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

import java.io.ByteArrayInputStream;

public class Demo {

    public static void main(String[] args) throws Exception{
        // リージョンのエンドポイントを指定します。この例では、中国 (杭州) リージョンのエンドポイントが使用されています。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // バケットの名前を指定します。例: examplebucket。
        String bucketName = "examplebucket";
        // オブジェクトの完全なパスを指定します。例: exampledir/exampleobject.txt。完全なパスにバケット名を含めないでください。
        String objectName = "exampledir/exampleobject.txt";
        // コールバックリクエストの送信先サーバーのアドレスを指定します。例: https://example.com:23450。
        String callbackUrl = "yourCallbackServerUrl";
        // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
        String region = "cn-hangzhou";

        // OSSClient インスタンスを作成します。
        // OSSClient が不要になったら、shutdown メソッドを呼び出して関連付けられているリソースを解放します。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();
        
        try {
            String content = "Hello OSS";
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName,new ByteArrayInputStream(content.getBytes()));

            // アップロードコールバックパラメーターを設定します。
            Callback callback = new Callback();
            callback.setCallbackUrl(callbackUrl);
            // (オプション) コールバックリクエストヘッダーの CallbackHost フィールドを指定します。
            // callback.setCallbackHost("yourCallbackHost");
            
            // コールバックリクエストの本文を JSON 形式で設定し、その中にプレースホルダー変数を定義します。
            callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
            callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");

            // コールバックリクエストのカスタムパラメーターを設定します。各カスタムパラメーターはキーと値で構成されます。キーは x: で始まる必要があります。
            callback.addCallbackVar("x:var1", "value1");
            callback.addCallbackVar("x:var2", "value2");
            putObjectRequest.setCallback(callback);

            // アップロード操作を実行します。
            PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);

            // アップロードコールバックから返されたメッセージコンテンツを読み取ります。
            byte[] buffer = new byte[1024];
            putObjectResult.getResponse().getContent().read(buffer);
            // データを読み取った後、取得したストリームを閉じる必要があります。そうしないと、接続リークが発生する可能性があります。その結果、接続が利用できなくなり、例外が発生します。
            putObjectResult.getResponse().getContent().close();
        } 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 (Throwable 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();
            }
        }
    }
}

マルチパートアップロードタスクのアップロードコールバックを設定する

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main(String[] args) throws Exception {
        // この例では、中国 (杭州) リージョンのエンドポイントが使用されています。実際のエンドポイントを指定してください。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // バケットの名前を指定します。例: examplebucket。
        String bucketName = "examplebucket";
        // オブジェクトの完全なパスを指定します。例: exampledir/exampleobject.txt。完全なパスにバケット名を含めないでください。
        String objectName = "exampledir/exampleobject.txt";
        // アップロードするローカルファイルの完全なパスを指定します。
        String filePath = "D:\\localpath\\examplefile.txt";
        // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
        String region = "cn-hangzhou";
        // コールバックリクエストの送信先サーバーのアドレスを指定します。例: https://example.com:23450。
        String callbackUrl = "https://example.com:23450";

        // OSSClient インスタンスを作成します。
        // OSSClient が不要になったら、shutdown メソッドを呼び出して関連付けられているリソースを解放します。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // InitiateMultipartUploadRequest オブジェクトを作成します。
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);

            // オブジェクトメタデータを設定し、オブジェクトの Content-Type を取得します。
            ObjectMetadata metadata = new ObjectMetadata();
            if (metadata.getContentType() == null) {
                metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
            }
            System.out.println("Content-Type: " + metadata.getContentType());

            // アップロードリクエストにメタデータを含めます。
            request.setObjectMetadata(metadata);

            // マルチパートアップロードタスクを初期化します。
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            // アップロード ID を取得します。
            String uploadId = upresult.getUploadId();

            // partETags は PartETag のセットです。パートの PartETag は、パートのパート番号と ETag 値で構成されます。
            List<PartETag> partETags = new ArrayList<PartETag>();
            // 各パートのサイズを指定します。これは、オブジェクトのパート数を計算するために使用されます。単位: バイト。
            // 各パートのサイズは 100 KB から 5 GB までです。最後のパートのサイズは 100 KB 未満にすることができます。
            // パートサイズをバイト単位で設定します。この例では、パートサイズは 1 MB に設定されています。
            final long partSize = 1 * 1024 * 1024L;

            // アップロードされるデータのサイズに基づいてパート数を計算します。次のサンプルコードでは、ローカルファイルを例として、File.length() メソッドを使用してアップロードされるデータのサイズを取得する方法を説明します。
            final File sampleFile = new File(filePath);
            long fileLength = sampleFile.length();
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }
            // オブジェクトのすべてのパートをアップロードします。
            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ?  (fileLength - startPos) : partSize;
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);

                // マルチパートアップロードタスクの入力ストリームを指定します。
                // 次のサンプルコードでは、ローカルファイルを例として、FileInputStream オブジェクトを作成し、InputStream.skip() メソッドを使用して指定されたデータをスキップする方法を説明します。
                InputStream instream = new FileInputStream(sampleFile);
                instream.skip(startPos);
                uploadPartRequest.setInputStream(instream);
                // 各パートで使用可能なサイズを指定します。
                uploadPartRequest.setPartSize(curPartSize);
                // パート番号を指定します。各パートには、1 から 10,000 までのパート番号があります。指定したパート番号が指定された範囲内にない場合、InvalidArgument エラーコードが返されます。
                uploadPartRequest.setPartNumber(i + 1);
                // パートは必ずしも順番にアップロードされるわけではなく、異なる OSS クライアントからアップロードできます。OSS はパート番号に基づいてパートをソートし、パートを結合して完全なオブジェクトを作成します。
                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                // パートがアップロードされると、OSS は PartETag を含む結果を返します。PartETag は partETags に格納されます。
                partETags.add(uploadPartResult.getPartETag());

                // 入力ストリームを無効にします。
                instream.close();
            }

            // CompleteMultipartUploadRequest オブジェクトを作成します。
            // CompleteMultipartUpload 操作を呼び出すときは、すべての有効な PartETag を指定する必要があります。OSS は PartETag を受信した後、すべてのパートを 1 つずつ検証します。すべてのパートが検証されると、OSS はこれらのパートを結合して完全なオブジェクトを作成します。
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

            // アップロードコールバックパラメーターを指定します。
            Callback callback = new Callback();
            callback.setCallbackUrl(callbackUrl);
            // (オプション) コールバックリクエストヘッダーの CallbackHost フィールドを指定します。
            // callback.setCallbackHost("yourCallbackHost");

            // コールバックリクエストの本文を JSON 形式で設定し、その中にプレースホルダー変数を定義します。
            callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
            callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");

            // コールバックリクエストのカスタムパラメーターを設定します。各カスタムパラメーターはキーと値で構成されます。キーは x: で始まる必要があります。
            callback.addCallbackVar("x:var1", "value1");
            callback.addCallbackVar("x:var2", "value2");
            completeMultipartUploadRequest.setCallback(callback);

            // マルチパートアップロードタスクを完了します。
            CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            System.out.println("Upload successful,ETag:" + completeMultipartUploadResult.getETag());

        } 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 a 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();
            }
        }
    }
}

フォームを使用してオブジェクトをアップロードし、アップロードコールバック設定を行う

import com.aliyun.oss.ClientException;
import com.aliyun.oss.common.auth.ServiceSignature;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.StringUtils;
import com.aliyun.oss.internal.OSSUtils;
import com.aliyun.oss.model.Callback;
import org.apache.commons.codec.binary.Base64;
import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class PostObjectCallbackV4Demo {
    // アップロードするローカルファイルの完全なパスを指定します。
    private static final String localFilePath = "D:\\localpath\\examplefile.txt";
    // この例では、中国 (杭州) リージョンのエンドポイントが使用されています。実際のエンドポイントを指定してください。
    private static final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    // Alibaba Cloud アカウントの AccessKey ペアは、すべての API 操作に対する権限を持っています。これらの認証情報を使用して OSS で操作を実行すると、重大なセキュリティリスクが発生します。API 操作の呼び出しまたは日常的な O&M は、Resource Access Management (RAM) ユーザーとして実行することをお勧めします。RAM ユーザーを作成するには、RAM コンソールにログインします。
    private static final String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
    private static final String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
    // バケットの名前を指定します。例: examplebucket。
    private static final String bucketName = "examplebucket";
    // オブジェクトの完全なパスを指定します。例: exampledir/exampleobject.txt。完全なパスにバケット名を含めないでください。
    private static final String objectName = "exampledir/exampleobject.txt";
    // コールバックリクエストを送信するサーバーの URL を指定します。例: http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450 または http://127.0.0.1:9090。
    private static final String callbackServerUrl = "http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450";
    // コールバックリクエストの Host ヘッダーを指定します。例: oss-cn-hangzhou.aliyuncs.com。
    private static final String callbackServerHost = "";
    // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
    private static final String region = "cn-hangzhou";
    private static Date requestDateTime = new Date();


    /**
     * フォームアップロードを実行します。
     * @throws Exception
     */
    private void PostObject() throws Exception {

        // URL にバケット名を追加します。URL 形式は http://yourBucketName.oss-cn-hangzhou.aliyuncs.com です。
        String urlStr = endpoint.replace("http://", "http://" + bucketName+ ".");
        // フォームパラメーターを構築します。
        Map<String, String> formFields = new LinkedHashMap<String, String>();
        formFields.put("key", objectName);
        formFields.put("Content-Disposition", "attachment;filename="
                + localFilePath);
        // コールバックパラメーターを指定します。
        Callback callback = new Callback();
        // コールバックリクエストを送信するサーバーの URL を指定します。例: http://oss-demo.oss-cn-hangzhou.aliyuncs.com:23450 または http://127.0.0.1:9090。
        callback.setCallbackUrl(callbackServerUrl);
        // コールバックリクエストの Host ヘッダーを指定します。例: oss-cn-hangzhou.aliyuncs.com。
        callback.setCallbackHost(callbackServerHost);

        // コールバックリクエストの本文を JSON 形式で設定し、その中にプレースホルダー変数を定義します。
        callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
        callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");

        // コールバックリクエストのカスタムパラメーターを指定します。各カスタムパラメーターはキーと値のペアで構成されます。キーは x: で始まり、小文字である必要があります。
        callback.addCallbackVar("x:var1", "value1");
        callback.addCallbackVar("x:var2", "value2");
        // フォームの Map にコールバックパラメーターを指定します。
        setCallBack(formFields, callback);

        // OSSAccessKeyId を指定します。
        formFields.put("OSSAccessKeyId", accessKeyId);
        String policy = "{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [" +
                "  {\"x-oss-signature-version\": \"OSS4-HMAC-SHA256\"},\n" +
                "  {\"x-oss-credential\": \""+accessKeyId+"/"+getDate()+"/"+region+"/oss/aliyun_v4_request\"},\n" +
                "  {\"x-oss-date\": \""+getDateTime()+"\"},\n" +
                "  [\"content-length-range\", 0, 104857600]" +
                "]}";
        String encodePolicy = new String(Base64.encodeBase64(policy.getBytes()));
        // ポリシーを設定します。
        formFields.put("policy", encodePolicy);
        System.out.println("policy:" + policy);
        // 署名を生成します。
        formFields.put("x-oss-signature-version", "OSS4-HMAC-SHA256");
        formFields.put("x-oss-credential", accessKeyId+"/"+getDate()+"/"+region+"/oss/aliyun_v4_request");
        formFields.put("x-oss-date", getDateTime());

        String stringToSign = new String(Base64.encodeBase64(policy.getBytes()));
        System.out.println("stringToSign:" + stringToSign);
        byte[] signingKey = buildSigningKey();
        String signature = buildSignature(signingKey, stringToSign);
        formFields.put("x-oss-signature", signature);
        System.out.println("Signature:" + signature);

        // アップロード操作を実行します。
        String ret = formUpload(urlStr, formFields);
        System.out.println("Post Object [" + objectName + "] to bucket [" + bucketName + "]");
        System.out.println("post reponse:" + ret);
    }

    private static String formUpload(String urlStr, Map<String, String> formFields)
            throws Exception {
        String res = "";
        HttpURLConnection conn = null;
        String boundary = "9431149156168";
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary);

            // フォームフィールドを処理します。
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            // フォームのすべての Map データを再帰的に読み取り、出力ストリームに書き込みます。
            if (formFields != null) {
                StringBuilder strBuf = new StringBuilder();
                Iterator<Map.Entry<String, String>> iter = formFields.entrySet().iterator();
                int i = 0;
                while (iter.hasNext()) {
                    Map.Entry<String, String> entry = iter.next();
                    String inputName = entry.getKey();
                    String inputValue = entry.getValue();
                    if (inputValue == null) {
                        continue;
                    }
                    if (i == 0) {
                        strBuf.append("--").append(boundary).append("\r\n");
                        strBuf.append("Content-Disposition: form-data; name=\"").append(inputName).append("\"\r\n\r\n");
                        strBuf.append(inputValue);
                    } else {
                        strBuf.append("\r\n").append("--").append(boundary).append("\r\n");
                        strBuf.append("Content-Disposition: form-data; name=\""
                                + inputName + "\"\r\n\r\n");
                        strBuf.append(inputValue);
                    }
                    i++;
                }
                out.write(strBuf.toString().getBytes());
            }
            // ファイルを読み取り、出力ストリームに書き込みます。
            File file = new File(localFilePath);
            String filename = file.getName();
            String contentType = new MimetypesFileTypeMap().getContentType(file);
            if (contentType == null || contentType.equals("")) {
                contentType = "application/octet-stream";
            }
            StringBuffer strBuf = new StringBuffer();
            strBuf.append("\r\n").append("--").append(boundary)
                    .append("\r\n");
            strBuf.append("Content-Disposition: form-data; name=\"file\"; "
                    + "filename=\"" + filename + "\"\r\n");
            strBuf.append("Content-Type: " + contentType + "\r\n\r\n");
            out.write(strBuf.toString().getBytes());
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes();
            out.write(endData);
            out.flush();
            out.close();
            // 返されたデータを読み取ります。
            strBuf = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != -1) {
                strBuf.append(line).append("\n");
            }
            res = strBuf.toString();
            reader.close();
            reader = null;
        } catch (ClientException e) {
            System.err.println("Send post request exception: " + e);
            System.err.println(e.getErrorCode()+" msg="+e.getMessage());
            throw e;
        } finally {
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return res;
    }
    private static void setCallBack(Map<String, String> formFields, Callback callback) {
        if (callback != null) {
            String jsonCb = OSSUtils.jsonizeCallback(callback);
            String base64Cb = BinaryUtil.toBase64String(jsonCb.getBytes());
            formFields.put("callback", base64Cb);
            if (callback.hasCallbackVar()) {
                Map<String, String> varMap = callback.getCallbackVar();
                for (Map.Entry<String, String> entry : varMap.entrySet()) {
                    formFields.put(entry.getKey(), entry.getValue());
                }
            }
        }
    }

    private static String getDateTime() {
        return getIso8601DateTimeFormat().format(requestDateTime);
    }

    private static DateFormat getIso8601DateTimeFormat() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US);
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df;
    }

    private static DateFormat getIso8601DateFormat() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", Locale.US);
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df;
    }

    private static String getDate() {
        return getIso8601DateFormat().format(requestDateTime);
    }

    private String buildSignature(byte[] signingKey, String stringToSign) {
        byte[] result = ServiceSignature.create("HmacSHA256").computeHash(signingKey, stringToSign.getBytes(StringUtils.UTF8));
        return BinaryUtil.toHex(result);
    }

    private byte[] buildSigningKey() {
        ServiceSignature signature = ServiceSignature.create("HmacSHA256");
        byte[] signingSecret = ("aliyun_v4" + accessKeySecret).getBytes(StringUtils.UTF8);
        byte[] signingDate = signature.computeHash(signingSecret, getDate().getBytes(StringUtils.UTF8));
        byte[] signingRegion = signature.computeHash(signingDate, region.getBytes(StringUtils.UTF8));
        byte[] signingService = signature.computeHash(signingRegion, "oss".getBytes(StringUtils.UTF8));
        /*System.out.println("signingSecret:\n" + BinaryUtil.toHex(signingSecret));
        System.out.println("signingDate:\n" + BinaryUtil.toHex(signingDate));
        System.out.println("signingRegion:\n" + BinaryUtil.toHex(signingRegion));
        System.out.println("signingService:\n" + BinaryUtil.toHex(signingService));*/
        return signature.computeHash(signingService, "aliyun_v4_request".getBytes(StringUtils.UTF8));
    }

    public static void main(String[] args) throws Exception {
        PostObjectCallbackV4Demo ossPostObject = new PostObjectCallbackV4Demo();
        ossPostObject.PostObject();
    }
}

レジューム可能なアップロードタスクのアップロードコールバックを設定する

package Callback;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
import com.aliyun.oss.model.*;

import java.io.File;

public class Demo {
    public static void main(String[] args) throws Exception {
        // この例では、中国 (杭州) リージョンのエンドポイントが使用されています。実際のエンドポイントを指定してください。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // バケットの名前を指定します。例: examplebucket。
        String bucketName = "examplebucket";
        // オブジェクトの完全なパスを指定します。例: exampledir/exampleobject.txt。完全なパスにバケット名を含めないでください。
        String objectName = "exampledir/exampleobject.txt";
        // ローカルファイルの完全なパスを指定します。例: D:\\localpath\\examplefile.txt。
        String filePath = "D:\\localpath\\examplefile.txt";
        // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
        String region = "cn-hangzhou";
        // コールバックリクエストの送信先サーバーのアドレスを指定します。例: https://example.com:23450。
        String callbackUrl = "http://example.com:23450/callback";

        // OSSClient インスタンスを作成します。
        // OSSClient が不要になったら、shutdown メソッドを呼び出して関連付けられているリソースを解放します。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // オブジェクトメタデータを設定し、オブジェクトの Content-Type を取得します。
            ObjectMetadata metadata = new ObjectMetadata();
            if (metadata.getContentType() == null) {
                metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
            }
            System.out.println("Content-Type: " + metadata.getContentType());

            // UploadFileRequest を使用して複数のパラメーターを設定します。
            // バケット名 (examplebucket など) とオブジェクトの完全なパス (exampledir/exampleobject.txt など) を指定します。完全なパスにバケット名を含めないでください。
            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName,objectName);

            // UploadFileRequest を使用して単一のパラメーターを設定します。
            // ローカルファイルの完全なパスを指定します。例: D:\\localpath\\examplefile.txt。デフォルトでは、ローカルファイルのパスを指定しない場合、サンプルプログラムが属するプロジェクトのローカルパスからファイルがアップロードされます。
            uploadFileRequest.setUploadFile(filePath);
            // アップロードタスクの同時スレッド数を指定します。デフォルト値: 1。
            uploadFileRequest.setTaskNum(5);
            // パートサイズを指定します。単位: バイト。有効な値: 100 KB から 5 GB。デフォルト値: 100 KB。
            uploadFileRequest.setPartSize(1 * 1024 * 1024);
            // レジューム可能なアップロードを有効にするかどうかを指定します。デフォルトでは、レジューム可能なアップロードは無効になっています。
            uploadFileRequest.setEnableCheckpoint(true);
            // 各パートのアップロードの進捗状況を記録するチェックポイントファイルを指定します。このファイルには、アップロードの進捗状況に関する情報が格納されます。パートのアップロードに失敗した場合、チェックポイントファイルに記録されている進捗状況に基づいてタスクを続行できます。オブジェクトがアップロードされると、チェックポイントファイルは削除されます。
            // デフォルトでは、このパラメーターを指定しない場合、このチェックポイントファイルは、アップロードするオブジェクトと同じディレクトリを共有します。ディレクトリ名は ${uploadFile}.ucp です。
            uploadFileRequest.setCheckpointFile("yourCheckpointFile");
            // オブジェクトメタデータを設定します。
            uploadFileRequest.setObjectMetadata(metadata);

            // アップロードコールバックパラメーターを設定します。
            Callback callback = new Callback();
            callback.setCallbackUrl(callbackUrl);
            // (オプション) コールバックリクエストヘッダーの CallbackHost フィールドを指定します。
            // callback.setCallbackHost("yourCallbackHost");

            // コールバックリクエストの本文を JSON 形式で設定し、その中にプレースホルダー変数を定義します。
            callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
            callback.setCallbackBody("{\\\"bucket\\\":${bucket},\\\"object\\\":${object},\\\"mimeType\\\":${mimeType},\\\"size\\\":${size},\\\"my_var1\\\":${x:var1},\\\"my_var2\\\":${x:var2}}");

            // コールバックリクエストのカスタムパラメーターを設定します。各カスタムパラメーターはキーと値で構成されます。キーは x: で始まる必要があります。
            callback.addCallbackVar("x:var1", "value1");
            callback.addCallbackVar("x:var2", "value2");
            // アップロードコールバックを設定します。パラメータータイプは Callback です。
            uploadFileRequest.setCallback(callback);

            // レジューム可能なアップロードを開始します。
            ossClient.uploadFile(uploadFileRequest);

        } 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 (Throwable 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 {
            // OSSClient インスタンスをシャットダウンします。
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

署名付き URL を使用してオブジェクトをアップロードし、アップロードコールバックパラメーターを設定する

  1. HTTP PUT リクエストを使用してアップロードを有効にするために、アップロードコールバックパラメーターを含む署名付き URL を生成します。

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.CredentialsProviderFactory;
    import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.internal.OSSHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    
    import java.net.URL;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    public class OssPresignExample {
        public static void main(String[] args) throws Throwable {
            // この例では、中国 (杭州) リージョンのエンドポイントが使用されています。実際のエンドポイントを指定してください。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // バケットの名前を指定します。例: examplebucket。
            String bucketName = "examplebucket";
            // オブジェクトの完全なパスを指定します。例: exampleobject.txt。完全なパスにバケット名を含めないでください。
            String objectName = "exampleobject.txt";
            // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
            String region = "cn-hangzhou";
    
            // OSSClient インスタンスを作成します。
            // OSSClient が不要になったら、shutdown メソッドを呼び出して関連付けられているリソースを解放します。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint(endpoint)
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region(region)
                    .build();
    
            URL signedUrl = null;
            try {
                // コールバックパラメーターを構築します。
                String callbackUrl = "http://www.example.com/callback";
                String callbackBody = "{\"callbackUrl\":\"" + callbackUrl + "\",\"callbackBody\":\"bucket=${bucket}&object=${object}&my_var_1=${x:var1}&my_var_2=${x:var2}\"}";
                String callbackBase64 = Base64.getEncoder().encodeToString(callbackBody.getBytes());
    
                String callbackVarJson = "{\"x:var1\":\"value1\",\"x:var2\":\"value2\"}";
                String callbackVarBase64 = Base64.getEncoder().encodeToString(callbackVarJson.getBytes());
                // リクエストヘッダーを指定します。
                Map<String, String> headers = new HashMap<String, String>();
                // コールバックパラメーターを指定します。
                headers.put(OSSHeaders.OSS_HEADER_CALLBACK, callbackBase64);
                // callback-var パラメーターを指定します。
                headers.put(OSSHeaders.OSS_HEADER_CALLBACK_VAR, callbackVarBase64);
    
                // 有効期限を 3600 秒に設定します。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
    
                // 有効期限をフォーマットします。
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                String expirationStr = dateFormat.format(expiration);
    
                // リクエストを構築します。
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName);
                request.setMethod(HttpMethod.PUT);
                request.setExpiration(expiration);
                // リクエストにヘッダーを追加します。
                request.setHeaders(headers);
    
                // callback および callback-var パラメーターの値を出力します。
                System.out.println("callback:"+callbackBase64);
                System.out.println("callback-var:"+callbackVarBase64);
    
                // 署名付き URL を生成します。
                URL url = ossClient.generatePresignedUrl(request);
    
                // 結果を出力します。
                System.out.println("method: PUT,");
                System.out.println(" expiration: " + expirationStr + ",");
                System.out.println(" url: " + url);
    
            } 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());
            }
        }
    }
  2. 署名付き URL を使用してオブジェクトをアップロードします。

    curl

    curl -X PUT \
         -H "x-oss-callback: eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9" \
         -H "x-oss-callback-var: eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==" \
         -T "C:\\Users\\demo.txt" \
         "https://exampleobject.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T083238Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241112%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Python

    import requests
    
    def upload_file(signed_url, file_path, headers=None):
        """
        署名付き URL を使用してオブジェクトを OSS にアップロードします。
    
        :param signed_url: 署名付き URL。
        :param file_path: アップロードするローカルファイルの完全なパス。
        :param headers: リクエストヘッダー。このパラメーターはオプションです。
        :return: なし
        """
        if not headers:
            headers = {}
    
        try:
            with open(file_path, 'rb') as file:
                response = requests.put(signed_url, data=file, headers=headers)
                print(f"ステータスコード:{response.status_code}")
                if response.status_code == 200:
                    print("ライブラリを使用してオブジェクトがアップロードされました。")
                else:
                    print("アップロードに失敗しました。")
                print(response.text)
        except Exception as e:
            print(f"エラーが発生しました:{e}")
    
    if __name__ == "__main__":
        // <signedUrl> を署名付き URL に置き換えます。
        signed_url = "<signedUrl>"
    
        // ローカルファイルの完全なパスを指定します。デフォルトでは、ローカルファイルの完全なパスを指定しない場合、スクリプトが格納されているディレクトリからローカルファイルがアップロードされます。
        file_path = "C:\\Users\\demo.txt"
    
        headers = {
            "x-oss-callback": "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9",
            "x-oss-callback-var": "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==",
        }
    
        upload_file(signed_url,  file_path, headers)

    Go

    package main
    
    import (
    	"bytes"
    	"fmt"
    	"io"
    
    	"net/http"
    	"os"
    )
    
    func uploadFile(signedUrl string, filePath string, headers map[string]string) error {
    	// ファイルを開きます。
    	file, err := os.Open(filePath)
    	if err != nil {
    		return err
    	}
    	defer file.Close()
    
    	// コンテンツを読み取ります。
    	fileBytes, err := io.ReadAll(file)
    	if err != nil {
    		return err
    	}
    
    	// リクエストを作成します。
    	req, err := http.NewRequest("PUT", signedUrl, bytes.NewBuffer(fileBytes))
    	if err != nil {
    		return err
    	}
    
    	// リクエストヘッダーを指定します。
    	for key, value := range headers {
    		req.Header.Add(key, value)
    	}
    
    	// リクエストを送信します。
    	client := &http.Client{}
    	resp, err := client.Do(req)
    	if err != nil {
    		return err
    	}
    	defer resp.Body.Close()
    
    	// レスポンスを処理します。
    	fmt.Printf("ステータスコード:%d\n", resp.StatusCode)
    	if resp.StatusCode == 200 {
    		fmt.Println("ライブラリを使用してオブジェクトがアップロードされました。")
    	} else {
    		fmt.Println("アップロードに失敗しました。")
    	}
    	body, _ := io.ReadAll(resp.Body)
    	fmt.Println(string(body))
    
    	return nil
    }
    
    func main() {
    	// <signedUrl> を署名付き URL に置き換えます。
    	signedUrl := "<signedUrl>"
    	// ローカルファイルの完全なパスを指定します。ローカルファイルのパスが指定されていない場合、サンプルプログラムが属するプロジェクトのパスからローカルファイルがアップロードされます。
    	filePath := "C:\\Users\\demo.txt"
    
    	// リクエストヘッダーを指定します。リクエストヘッダーの値が、署名付き URL の生成時に指定された値と同じであることを確認してください。
    	headers := map[string]string{
    		"x-oss-callback":     "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9",
    		"x-oss-callback-var": "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==",
    	}
    
    	err := uploadFile(signedUrl, filePath, headers)
    	if err != nil {
    		fmt.Printf("エラーが発生しました:%v\n", err)
    	}
    }
    

    Java

    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    import java.net.URL;
    import java.util.*;
    
    public class SignUrlUpload {
        public static void main(String[] args) throws Throwable {
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
    
            // <signedUrl> を署名付き URL に置き換えます。
            URL signedUrl = new URL("<signedUrl>");
    
            // ローカルファイルの完全なパスを指定します。ローカルファイルのパスが指定されていない場合、サンプルプログラムが属するプロジェクトのパスからローカルファイルがアップロードされます。
            String pathName = "C:\\Users\\demo.txt";
    
            // リクエストヘッダー (x-oss-callback および x-oss-callback-var を含む) を指定します。
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("x-oss-callback", "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9");
            headers.put("x-oss-callback-var", "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==");
    
            try {
                HttpPut put = new HttpPut(signedUrl.toString());
                System.out.println(put);
                HttpEntity entity = new FileEntity(new File(pathName));
                put.setEntity(entity);
                // 署名付き URL の生成時にヘッダーを設定した場合、署名付き URL を使用してファイルをアップロードするときに、これらのヘッダーをサーバーに送信する必要があります。署名計算のためにサーバーに送信されるヘッダーが、署名付き URL の生成時に指定されたヘッダーと異なる場合、署名エラーが報告されます。
                for(Map.Entry header: headers.entrySet()){
                    put.addHeader(header.getKey().toString(),header.getValue().toString());
                }
    
                httpClient = HttpClients.createDefault();
    
                response = httpClient.execute(put);
    
                System.out.println("ステータスコード:"+response.getStatusLine().getStatusCode());
                if(response.getStatusLine().getStatusCode() == 200){
                    System.out.println("ライブラリを使用してオブジェクトがアップロードされました。");
                }
                System.out.println(response.toString());
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
        }
    }       

    PHP

    <?php
    
    function uploadFile($signedUrl, $filePath, $headers = []) {
        // ファイルが存在するかどうかを確認します。
        if (!file_exists($filePath)) {
            echo "ファイルが存在しません: $filePath\n";
            return;
        }
    
        // cURL セッションを初期化します。
        $ch = curl_init();
    
        // cURL オプションを設定します。
        curl_setopt($ch, CURLOPT_URL, $signedUrl);
        curl_setopt($ch, CURLOPT_PUT, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'rb'));
        curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function($key, $value) {
            return "$key: $value";
        }, array_keys($headers), $headers));
    
        // cURL リクエストを実行します。
        $response = curl_exec($ch);
    
        // HTTP ステータスコードをクエリします。
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
        // cURL セッションを閉じます。
        curl_close($ch);
    
        // 結果を出力します
        echo "ステータスコード:$httpCode\n";
        if ($httpCode == 200) {
            echo "ライブラリを使用してオブジェクトがアップロードされました。\n";
        } else {
            echo "アップロードに失敗しました。\n";
        }
        echo $response . "\n";
    }
    
    // <signedUrl> を署名付き URL に置き換えます。
    $signedUrl = "<signedUrl>";
    
    // ローカルファイルの完全なパスを指定します。デフォルトでは、ローカルファイルの完全なパスを指定しない場合、スクリプトが格納されているディレクトリからローカルファイルがアップロードされます。
    $filePath = "C:\\Users\\demo.txt";
    
    $headers = [
        "x-oss-callback" => "eyJjYWxsYmFja1VybCI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2siLCJjYWxsYmFja0JvZHkiOiJidWNrZXQ9JHtidWNrZXR9Jm9iamVjdD0ke29iamVjdH0mbXlfdmFyXzE9JHt4OnZhcjF9Jm15X3Zhcl8yPSR7eDp2YXIyfSJ9",
        "x-oss-callback-var" => "eyJ4OnZhcjEiOiJ2YWx1ZTEiLCJ4OnZhcjIiOiJ2YWx1ZTIifQ==",
    ];
    
    uploadFile($signedUrl, $filePath, $headers);
    
    ?>

関連情報

  • アップロードコールバックの完全なサンプルコードについては、GitHub をご覧ください。

  • アップロードコールバックを設定するために呼び出すことができる API 操作の詳細については、「Callback」をご参照ください。