Home > Enterprise >  Springboot REST endpoint storing an empty image on Google Cloud Storage
Springboot REST endpoint storing an empty image on Google Cloud Storage

Time:10-01

I am trying to store an image to Google cloud storage from my REST endpoint. But when i see the image on Google Cloud storage it shows an empty image.

My Service class

package com.example.firebase.springbootfirebasedemo.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.example.firebase.springbootfirebasedemo.entity.Review;
import com.google.api.core.ApiFuture;
import com.google.cloud.firestore.DocumentReference;
import com.google.cloud.firestore.DocumentSnapshot;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.WriteResult;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.firebase.cloud.FirestoreClient;

@Service
public class ReviewService {
    
    @Autowired
    private Storage storage;

    private static final String COLLECTION_NAME ="Reviews";
    private static final String BUCKET_NAME = "gcpfirebase";

    public String saveReview(Review review, MultipartFile file) throws ExecutionException, InterruptedException, IOException {
        
        File convFile = new File( file.getOriginalFilename() );
        FileOutputStream fos = new FileOutputStream( convFile );
        fos.write( file.getBytes());
        fos.close();
        BlobInfo blobInfo = storage.create(BlobInfo.newBuilder(BUCKET_NAME, file.getOriginalFilename()).build());
        System.out.println(blobInfo.getMediaLink());
        
//                                                                .build()
//                     file.openStream() 
        

       Firestore dbFirestore= FirestoreClient.getFirestore();

       ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(review.getName()).set(review);

       return collectionApiFuture.get().getUpdateTime().toString();

    }

    public Review getReviewDetailsByname(String name) throws ExecutionException, InterruptedException {

        Firestore dbFirestore= FirestoreClient.getFirestore();

        DocumentReference documentReference=dbFirestore.collection(COLLECTION_NAME).document(name);

        ApiFuture<DocumentSnapshot> future=documentReference.get();

        DocumentSnapshot document=future.get();

        Review review=null;
        if(document.exists()) {
         review = document.toObject(Review.class);
       return  review;
        }else{
            return null;
        }
    }

    public List<Review> getAllReviews() throws ExecutionException, InterruptedException {

        Firestore dbFirestore= FirestoreClient.getFirestore();

        Iterable<DocumentReference> documentReference=dbFirestore.collection(COLLECTION_NAME).listDocuments();
        Iterator<DocumentReference> iterator=documentReference.iterator();

        List<Review> reviewList=new ArrayList<>();
        Review review=null;

        while(iterator.hasNext()){
            DocumentReference documentReference1=iterator.next();
           ApiFuture<DocumentSnapshot> future= documentReference1.get();
           DocumentSnapshot document=future.get();

            review=document.toObject(Review.class);
           reviewList.add(review);

        }
        return reviewList;
    }


    public String updateReview(Review review) throws ExecutionException, InterruptedException {

        Firestore dbFirestore= FirestoreClient.getFirestore();

        ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(review.getName()).set(review);

        return collectionApiFuture.get().getUpdateTime().toString();

    }

    public String deleteReview(String name) throws ExecutionException, InterruptedException {

        Firestore dbFirestore= FirestoreClient.getFirestore();

        ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(name).delete();

        return "Document with Review ID " name " has been deleted successfully";

    }
}

My Controller class

package com.example.firebase.springbootfirebasedemo.controller;

import com.example.firebase.springbootfirebasedemo.entity.Review;
import com.example.firebase.springbootfirebasedemo.service.ReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;

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

    @Autowired
    private ReviewService reviewService;

    @PostMapping(path = "/reviews", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public String saveReview(@ModelAttribute Review review, @RequestParam(value = "file",required = false) MultipartFile file) 
            throws ExecutionException, InterruptedException,IOException  {

        return reviewService.saveReview(review, file);
    }

    @GetMapping("/reviews/{name}")
    public Review getReview(@PathVariable String name) throws ExecutionException, InterruptedException {

        return reviewService.getReviewDetailsByname(name);
    }

    @GetMapping("/reviews")
    public List<Review> getAllReviews() throws ExecutionException, InterruptedException {

        return reviewService.getAllReviews();
    }


    @PutMapping("/reviews")
    public String updateReview(@RequestBody Review review) throws ExecutionException, InterruptedException {

        return reviewService.updateReview(review);
    }


    @DeleteMapping("/reviews/{name}")
    public String deleteReview(@PathVariable String name) throws ExecutionException, InterruptedException {

        return reviewService.deleteReview(name);
    }
}

Using the above code I was able to save the image with a image name on Google Cloud Storage, but the image is empty.The size of the file is also showing zero bytes.Please help.Thank you.

CodePudding user response:

You are only storing the Google Cloud Storage file metadata: BlobInfo, hence you will end up with a file without any content but still created.

You should copy the file content (byte[]) to the newly created file using the Blob type:

@Service
public class ReviewService {

  public String saveReview(Review review, MultipartFile file) throws ExecutionException, InterruptedException, IOException {
    BlobInfo blobInfo = storage.create(BlobInfo.newBuilder(BUCKET_NAME, file.getOriginalFilename()).build());
    Blob blob = storage.create(blobInfo, file.getBytes());
    
    System.out.println(blobInfo.getMediaLink());
    Firestore dbFirestore = FirestoreClient.getFirestore();
    ApiFuture<WriteResult> collectionApiFuture = dbFirestore.collection(COLLECTION_NAME).document(review.getName()).set(review);
    return collectionApiFuture.get().getUpdateTime().toString();
  }

  // ...
}
  • Related