3
votes

I'm trying to upload an image to a existing bucket in my Google Cloud Storage. The image file gets uploaded successfully when I go and check,
but the returned download url is null

CODE

private String uploadImage(File filePath, String blobName, File uploadCreds) throws FileNotFoundException, IOException{


   Storage storage = StorageOptions.newBuilder().setProjectId("myProjectId")
                .setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(uploadCreds)))
                .build()
                .getService();

                    String bucketName = "myBucketName"; 
                    Bucket bucket = storage.get(bucketName);
        BlobId blobId = BlobId.of(bucket.getName(), blobName);
        InputStream inputStream = new FileInputStream(filePath);
        BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/jpeg").build();


    try (WriteChannel writer = storage.writer(blobInfo)) {
        byte[] buffer = new byte[1024];
        int limit;
        try {
            while ((limit = inputStream.read(buffer)) >= 0) {
                writer.write(ByteBuffer.wrap(buffer, 0, limit));
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }finally {
            writer.close();

        }
                     System.out.println("Image URL : " + blobInfo.getMediaLink());
                     System.out.println("Blob URL : " + blobInfo.getSelfLink());
                     return blobInfo.getMediaLink();
    }


}

filePath is the Image File
blobName is a random Image Name
uploadCreds is my credintials.json file

Why is the blobInfo.getMediaLink() and blobInfo.getSelfLink() returning null?
What am i doing wrong?

3

3 Answers

4
votes

Here is my code that works perfectly

@RestController
@RequestMapping("/api")
public class CloudStorageHelper  {

    Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("C:\\Users\\sachinthah\\Downloads\\MCQ project -1f959c1fc3a4.json"));
    Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

    public CloudStorageHelper() throws IOException {
    }

    @SuppressWarnings("deprecation")
    @RequestMapping(method = RequestMethod.POST, value = "/imageUpload112")
    public String uploadFile(@RequestParam("fileseee")MultipartFile fileStream)
            throws IOException, ServletException {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        String bucketName = "mcqimages";
        checkFileExtension(fileStream.getName());
        DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
        DateTime dt = DateTime.now(DateTimeZone.UTC);

        String fileName = fileStream.getOriginalFilename();

        BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, fileName)
                .setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
                .build(),
        fileStream.getInputStream());

        System.out.println(blobInfo.getMediaLink());

        // sachintha added a comma after the link to identify the link that get generated
        return blobInfo.getMediaLink() + ",";
    }


private void checkFileExtension(String fileName) throws ServletException {
    if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
        String[] allowedExt = {".jpg", ".jpeg", ".png", ".gif"};
        for (String ext : allowedExt) {
            if (fileName.endsWith(ext)) {
                return;
            }
        }
        throw new ServletException("file must be an image");
    }
}
2
votes

The Answer was quite simple, i just got rid of the manual upload method and used the inbuilt create blob.

private String uploadImage(File filePath, String blobName, File uploadCreds) throws FileNotFoundException, IOException{


   Storage storage = StorageOptions.newBuilder().setProjectId("porjectId")
                .setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(uploadCreds)))
                .build()
                .getService();

                    String bucketName = "bucketName"; 
                    Bucket bucket = storage.get(bucketName);
        BlobId blobId = BlobId.of(bucket.getName(), blobName);
        InputStream inputStream = new FileInputStream(filePath);
        BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/jpeg").build();


                    Blob blob = storage.create(blobInfo, inputStream);


                     System.out.println("Image URL : " +  blob.getMediaLink());

           return  blob.getMediaLink();



}
0
votes

In case you want to store it in a special folder get the blobinfo.name() and append the "/" to it. for e.g if temp.jpg need to be stored with date folders. get the date from date object and format it with date formatter and prepend it

blobinfo.name() = date+"/"+blobinfo.name();

will classify all images date wise..