Spring Boot REST 端点在 Google 云存储上存储空图像

Springboot REST endpoint storing an empty image on Google Cloud Storage

我正在尝试将图像从我的 REST 端点存储到 Google 云存储。但是当我在 Google 云存储上看到图片时,它显示的是一张空图片。

我的服务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";

    }
}

我的控制器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);
    }
}

使用上面的代码,我能够在 Google 云存储上保存带有图像名称的图像,但是图像是 empty.The 文件大小也显示为零 bytes.Please help.Thank你.

您只存储 Google Cloud Storage 文件元数据:BlobInfo,因此您最终会得到一个没有任何内容但仍然创建的文件.

您应该使用 Blob 类型将文件内容 (byte[]) 复制到新创建的文件中:

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

  // ...
}