如何在 jsf 中生成和预览文件的预签名 url?

How to generate and preview a presigned url of a file in jsf?

我正在尝试使用 jsf 在我的网络应用程序中预览任何类型的文件,例如图像、pdf、doc、odt、xlsx、csv、文本等。

我的代码流程:

  1. 正在使用 aws s3 存储桶、java sdk 生成预签名 url。
  2. 然后将其传递给 google 文档或 Microsoft API 进行预览。

生成预签名代码url

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Duration;
import java.util.Date;
import java.util.logging.Level;
import org.apache.tika.Tika;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetUrlRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;

.........
.........
.........

    public void awsService(){ 
        AwsCredentialsProvider acp = StaticCredentialsProvider.create(AwsBasicCredentials.create("AccesId", "Key"));
        String fileName  = "dummy.pdf";
        String bucketName = "ViewerBucket";
        File file = new File("some/path/to/file/dummy.pdf");
        if (file.exists()) {

//uploading file before getting pre-signed url
            PutObjectResponse response = s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(fileName)
                        .contentType(tika.detect(file)).contentDisposition("attachment; filenName=\"" + fileName + "\"").build(),
                        RequestBody.fromFile(file));   //incontentDisposition tried with attachment/inline

            S3Presigner presigner = S3Presigner.builder()
                            .credentialsProvider(acp)
                            .region(Region.US_EAST_1)
                            .build();
            signBucket(presigner, bucketName, fileName, file, new Tika().detect(file));
            getPresignedUrl(presigner, bucketName, fileName);
        }
    }

    public void getPresignedUrl(S3Presigner presigner, String bucketName, String keyName) {

        try {
            GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(bucketName).key(keyName).build();

            GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder().signatureDuration(Duration.ofMinutes(10))
                    .getObjectRequest(getObjectRequest).build();

            // Generate the presigned request
            PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest);

            // Log the presigned URL
            System.out.println("Presigned URL: " + presignedGetObjectRequest.url());  //This url also has same issue with image and pdf as mentioned above
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.16.60</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>

我尝试了很多解决方案和方法,但预览在浏览器和代码中都无法正常工作。

我编辑了我的问题,现在我得到 url 并且 pdf 正在浏览器中打开,但是当我传递到 google 显示为预览的文档不可用 并且在传入显示为未找到文件的 Microsoft 文档时。 但相同的 pdf link 正在浏览器中预览。

请指导我或告诉我我哪里错了。任何帮助将不胜感激 提前致谢。

与 Jsf 2 和 primefaces 6.2

经过艰苦的寻找得到了解决方案

    public String previewFile;

    public void preview(String path, String fileName) {
        try {
//file path
            path += fileName;

            File file = new File(path.toString());
            if (file.exists()) {
                fileType = new Tika().detect(file);
//aws bucket name
                String bucketName = "bucketName";

//aws credentials if we not define here it will search by default at lcoation .aws/credentials
                AwsCredentialsProvider acp = StaticCredentialsProvider
                        .create(AwsBasicCredentials.create("Access key", "Secret key"));

                //upload file to aws account
                upload(acp, bucketName, fileName, file);

                //generating presigned url Thisis a public url
                getUrl(acp, bucketName, fileName);

//public url opening in browser
                PrimeFaces.current().executeScript("window.open('" + previewFile + "', '_blank');");
            } else {
                Message.addMessage("File does not exist", Message.severity.ERR);
            }
        } catch (IOException | AwsServiceException | SdkClientException e) {
            
            e.printStackTrac();
        } catch (Exception e) {
            e.printStackTrac();
        }
    }

//uplaod file to aws bucket
    public void upload(AwsCredentialsProvider acp, String bucketName, String fileName, File file) {
        S3Client s3Client = S3Client.builder().credentialsProvider(acp).region(Region.US_EAST_1).build();

       s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(fileName)
                .contentType(fileType).contentDisposition("inline; filenName=\"" + fileName + "\"")
                .build(),
                RequestBody.fromFile(file));

        s3Client.close();
    }
    
//getting public url
    public void getUrl(AwsCredentialsProvider acp, String bucketName, String keyName) {
        try {
            S3Presigner presigner = S3Presigner.builder()
                    .credentialsProvider(acp)
                    .region(Region.US_EAST_1)
                    .build();

            GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(bucketName).key(keyName).build();

            GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder().signatureDuration(Duration.ofMinutes(10))
                    .getObjectRequest(getObjectRequest).build();

            PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest);

            String url = presignedGetObjectRequest.url().toString();
            presigner.close();

            if (fileType.startsWith("image/") || fileType.startsWith("application/pdf")) {
                this.previewFile = url;
            } else {
                this.previewFile = "https://view.officeapps.live.com/op/embed.aspx?src=" + URLEncoder.encode(url, "UTF-8");
            }

        } catch (Exception e) {
            
            e.printStackTrac();
        }
    }

主要是我在办公室 API 的路过时忘记对 url 进行编码。