首页
学习
活动
专区
圈层
工具
发布

如何使用JSON API和CloseableHttpClient将文件上传到Google Cloud Storage bucket?

使用JSON API和CloseableHttpClient上传文件到Google Cloud Storage

基础概念

Google Cloud Storage (GCS) 是Google提供的对象存储服务,允许用户存储和检索任意数量的数据。JSON API是GCS提供的RESTful接口,可以通过HTTP请求与之交互。

CloseableHttpClient是Apache HttpClient库中的一个类,用于执行HTTP请求并管理连接资源。

实现步骤

1. 准备工作

首先需要设置Google Cloud项目并启用GCS API,创建服务账号并获取JSON密钥文件。

2. 获取访问令牌

代码语言:txt
复制
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

public class GCSUploader {
    private static final String SERVICE_ACCOUNT_EMAIL = "your-service-account@your-project.iam.gserviceaccount.com";
    private static final String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n";
    private static final String SCOPE = "https://www.googleapis.com/auth/devstorage.read_write";
    
    private String getAccessToken() throws Exception {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            long now = System.currentTimeMillis() / 1000L;
            
            // 创建JWT声明
            JSONObject header = new JSONObject();
            header.put("alg", "RS256");
            header.put("typ", "JWT");
            
            JSONObject claimSet = new JSONObject();
            claimSet.put("iss", SERVICE_ACCOUNT_EMAIL);
            claimSet.put("scope", SCOPE);
            claimSet.put("aud", "https://oauth2.googleapis.com/token");
            claimSet.put("exp", now + 3600);
            claimSet.put("iat", now);
            
            // 这里需要实现JWT签名逻辑(使用PRIVATE_KEY)
            // 实际项目中建议使用JWT库如jjwt
            
            HttpPost httpPost = new HttpPost("https://oauth2.googleapis.com/token");
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            
            StringEntity entity = new StringEntity(
                "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" + signedJwt);
            httpPost.setEntity(entity);
            
            // 执行请求并解析响应获取access_token
            // ...
        }
    }
}

3. 上传文件到GCS

代码语言:txt
复制
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class GCSUploader {
    // ... 之前的代码
    
    public void uploadFile(String bucketName, String objectName, File file) throws Exception {
        String accessToken = getAccessToken();
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            String url = String.format("https://storage.googleapis.com/upload/storage/v1/b/%s/o?uploadType=media&name=%s",
                                      bucketName, objectName);
            
            HttpPut httpPut = new HttpPut(url);
            httpPut.setHeader("Authorization", "Bearer " + accessToken);
            httpPut.setHeader("Content-Type", ContentType.APPLICATION_OCTET_STREAM.getMimeType());
            
            FileEntity fileEntity = new FileEntity(file);
            httpPut.setEntity(fileEntity);
            
            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPut)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode != 200) {
                    throw new RuntimeException("Upload failed with status code: " + statusCode);
                }
                // 处理成功响应
            }
        }
    }
}

优势

  1. 灵活性:直接使用HTTP API可以完全控制上传过程
  2. 轻量级:不需要引入额外的GCS客户端库
  3. 可定制:可以根据需要自定义重试逻辑、进度跟踪等

应用场景

  1. 需要精细控制上传过程的应用
  2. 受限环境中无法使用官方SDK的情况
  3. 需要与现有HTTP客户端集成的系统

常见问题及解决方案

认证失败

原因

  • JWT签名不正确
  • 服务账号权限不足
  • 访问令牌过期

解决

  • 检查JWT生成逻辑
  • 确保服务账号有存储对象写入权限
  • 实现令牌刷新机制

上传速度慢

原因

  • 单次上传大文件效率低
  • 网络条件不佳

解决

  • 考虑使用分块上传(resumable upload)
  • 优化网络配置或使用CDN

内存消耗高

原因

  • 大文件直接加载到内存

解决

  • 使用流式上传(InputStreamEntity)
  • 分块处理大文件

完整示例

代码语言:txt
复制
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONObject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class GCSUploadExample {
    public static void main(String[] args) {
        try {
            GCSUploader uploader = new GCSUploader();
            File fileToUpload = new File("path/to/your/file.txt");
            uploader.uploadFile("your-bucket-name", "destination-object-name", fileToUpload);
            System.out.println("File uploaded successfully");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意:实际项目中应考虑使用Google官方Java客户端库简化开发,此示例展示了底层API的使用方式。

相关搜索:使用Python API从Google Cloud Datalab上传文件到Google Cloud Storage Bucket如何使用Curl和API密钥上传到Google Cloud Storage?如何将Google Cloud Video情报结果的json文件放入Google Cloud bucketLaravel:如何将pdf文件直接上传到Google Cloud Storage bucket,而无需先将其保存到本地使用python将文件上传到google-cloud-storage存储桶时捕获异常如何使用Google Cloud Storage在CORS json文件中设置多个原点?如何使用multer将文件通过管道传输到Google Cloud Storage?Google Cloud Storage NodeJS和JSON API在尝试列出时未返回某些文件夹如何使用php将文件上传到google云存储bucket中的子文件夹如何使用Google Cloud Storage将文件夹目标设置到存储桶中?对存储在Google Cloud Storage (存储桶)上的CSV文件使用seek、write和readline方法如何使用API将文件上传到国外(其他人) Google云存储?如何使用API和CURL将文件夹上传到bitbucket repo如何使用google-cloud客户端将大于32MB的文件上传到GCS?如何使用api和python将原始zip文件上传到Nexus存储库如何使用Google Play Developer API Client Library for Java将扩展文件上传到草稿Apk?如何使用通过REST API获得的userId和令牌将文件上载到Firebase Storage如何使用yaml文件将Google Cloud build上的构建发布到Google Container注册表如何从控制台应用程序c#使用Google API将文件上传到Google Drive (注意-需要从控制台应用程序上传)
相关搜索:
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的文章

领券