Java GCP已签名url将内容配置设置为内联

Java GCP已签名url将内容配置设置为内联,java,kotlin,google-cloud-platform,google-cloud-storage,Java,Kotlin,Google Cloud Platform,Google Cloud Storage,在问这个问题之前,我做了很多研究,做了很多测试,像往常一样,我不喜欢问只是因为 我无法使用在浏览器中显示文件(内容配置:内联)的java创建签名url 当我使用PHPSDK做这件事时,我没有任何问题,我在浏览器中复制并粘贴了签名的url,文件显示在浏览器中。但是,当对同一个文件使用java时,会下载该文件 在这篇文章中,它提到了一些关于清除元数据的内容,并将“&response content disposition=inline”附加到已签名的url,在中也提到了这一点 我已经尝试了几种方法,

在问这个问题之前,我做了很多研究,做了很多测试,像往常一样,我不喜欢问只是因为

我无法使用在浏览器中显示文件(内容配置:内联)的java创建签名url

当我使用PHPSDK做这件事时,我没有任何问题,我在浏览器中复制并粘贴了签名的url,文件显示在浏览器中。但是,当对同一个文件使用java时,会下载该文件

在这篇文章中,它提到了一些关于清除元数据的内容,并将“&response content disposition=inline”附加到已签名的url,在中也提到了这一点

我已经尝试了几种方法,但我就是无法让它工作,当我按照中的指定附加“&response content disposition=inline”时,我得到以下错误:

 <Code>SignatureDoesNotMatch</Code> 
 <Message> The request signature we
 calculated does not match the signature you provided. Check your
 Google secret key and signing method. </Message>
但是它说这些参数不包括在签名的计算中,所以我不知道发生了什么

在我尝试过的代码中:

    (transformed to kotlin)

    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()
    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    blobInfo.toBuilder().setMetadata(newMetadata).build()

    val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS,Storage.SignUrlOption.withV4Signature())
        
    return signUrl.toString()
有什么建议吗

编辑

我注意到,当我使用PHP SDK请求文件时,我得到了响应头“content type:application/pdf”,而在Java上我得到了“content type:application/octet stream”,也许这就是我需要更改的内容

我尝试使用以下方法覆盖metada:

    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    newMetadata["contentType"] = "application%2Fpdf"
    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).setMetadata(newMetadata).build()
val newMetadata:MutableMap=HashMap()
newMetadata[“contentDisposition”]=“内联”
newMetadata[“contentType”]=“应用程序%2PDF”
val blobInfo=blobInfo.newBuilder(BlobId.of(configuracion.bucket,fileName)).setMetadata(newMetadata.build())

不过,运气不好。

这是我运行的代码,它生成pdf的签名url,然后在浏览器中呈现。如果这对您不起作用,我会查看pdf或浏览器设置

String projectId  = "<project_name>";
String bucketName = "<bucket_name>";
String objectName = "<file_name>";

Storage strg = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
BlobInfo blobinfo = BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build();
FileInputStream key = new FileInputStream("<path_to_json>");

URL url = strg.signUrl(blobinfo, 
  1, TimeUnit.MINUTES, Storage.SignUrlOption.withV4Signature(),
  SignUrlOption.signWith(ServiceAccountCredentials.fromStream(key))
);

System.out.println("Signed URL:");
System.out.println(url);
String projectd=“”;
字符串bucketName=“”;
字符串objectName=“”;
Storage strg=StorageOptions.newBuilder().setProjectId(projectId.build().getService();
BlobInfo BlobInfo=BlobInfo.newBuilder(BlobId.of(bucketName,objectName)).build();
FileInputStream键=新FileInputStream(“”);
URL URL=strg.signUrl(blobinfo,
1,TimeUnit.MINUTES,Storage.SignUrlOption.withV4Signature(),
SignUrlOption.signWith(ServiceAccountCredentials.fromStream(密钥))
);
System.out.println(“签名URL:”);
System.out.println(url);
所以

我一直在阅读和修改文档中的代码,直到我找到了答案

我读得越多,所有的阅读和研究开始变得更有意义

因此,如果将来有人遇到同样的问题,我最后用来更改响应头的代码是:

val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

//The query params
val queryParams: MutableMap<String, String> = HashMap()
queryParams["response-content-disposition"] = "inline"
queryParams["response-content-type"] = "application/pdf"

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, 
Storage.SignUrlOption.withQueryParams(queryParams), //This is the magic line
Storage.SignUrlOption.withV4Signature())

return signUrl.toString()
val storage=this.getStorageDefaultInstance()
val blobInfo=blobInfo.newBuilder(BlobId.of(configuracion.bucket,fileName)).build()
//查询参数
val queryParams:MutableMap=HashMap()
queryParams[“响应内容处置”]=“内联”
queryParams[“响应内容类型”]=“应用程序/pdf”
val signUrl=storage.signUrl(blobInfo,expiration,TimeUnit.ms,
Storage.signurlpoption.withQueryParams(queryParams),//这是一条神奇的线
Storage.SignUrlOption.withV4Signature())
return signUrl.toString()
为了更清楚,当我阅读其他帖子和文档时,关于在url中附加参数(响应内容配置响应内容类型),我尝试了几种方法,在评论中的某个地方,我只阅读响应内容配置是不够的,我就是这样,我还需要添加响应内容类型,但我的主要错误是在url签名后添加这些内容

在对url进行签名之前,您需要创建url并将参数附加到查询字符串中(上面的示例代码),并且google api将返回已签名的url,其中包括附加在查询字符串中的两个参数以及指定的值,因此您无需在之后修改url,即可使用


希望这能帮助其他人节省时间。

只是出于好奇,什么样的文件?我正在尝试用一个图像进行复制,我的浏览器可以从用java代码生成的签名url很好地呈现这个图像。这是一个pdf@JabbsContriented pdf,仍然在浏览器中呈现。问题是,当我通过PHP请求相同的文件时,它会在浏览器中打开,没有问题。当我在java上做的时候,它下载了,我注意到标题内容类型不同,我要添加一个编辑问题。
val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

//The query params
val queryParams: MutableMap<String, String> = HashMap()
queryParams["response-content-disposition"] = "inline"
queryParams["response-content-type"] = "application/pdf"

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, 
Storage.SignUrlOption.withQueryParams(queryParams), //This is the magic line
Storage.SignUrlOption.withV4Signature())

return signUrl.toString()