Home > Software engineering >  How to generate and preview a presigned url of a file in jsf?
How to generate and preview a presigned url of a file in jsf?

Time:05-17

I am trying to preview any type of file such as image,pdf,doc,odt,xlsx,csv,text etc in my web app using jsf.

My flow of code:

  1. Generating a presigned url using aws s3 bucket, java sdk.
  2. Then passing this to google doc or microsoft API to preview.

Code of generating presigned 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>

and

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

I tried many solutions and many ways but preview is not working in browser as well as in code.

I edited my question now I am getting url and pdf is opening in browser but when I passing to google doc showing as preview not available and when passing in microsoft doc showing as file not found. but the same pdf link is previewing in browser.

Please guide me or tell me where am I wrong. Anyhelp will be appreciated Thanks alot in advance.

working with Jsf 2 and primefaces 6.2

CodePudding user response:

After a hard and searching Got the solution

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

Mainly I forgot to encode the url while passing in office API's.

  • Related