春季启动图像上传到谷歌云存储桶不起作用

Posted

技术标签:

【中文标题】春季启动图像上传到谷歌云存储桶不起作用【英文标题】:spring boot image upload to the google cloud storage bucket is not working 【发布时间】:2019-03-26 09:01:49 【问题描述】:

我想将图像上传到谷歌云存储,这是我的 Spring Boot 代码。但问题是这根本不起作用给我这样的错误:

2018-10-22 15:22:55.628 错误 6172 --- [nio-8080-exec-6] oaccC[.[.[/].[dispatcherServlet]:Servlet.service() 用于 servlet [dispatcherServlet]在路径 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是 java.lang.IllegalArgumentException: Invoked method public abstract java.io.InputStream org.apache.commons.fileupload.FileItemStream.openStream() throws java.io.IOException is no accessor method!] 根本原因

请帮助我。以下是我写的代码

 private static Storage storage = null;

    // [START init]
    static 
        storage = StorageOptions.getDefaultInstance().getService();
    

 @SuppressWarnings("deprecation")
 @RequestMapping(method = RequestMethod.POST, value = "/imageUpload")
 public String uploadFile(FileItemStream fileStream)
        throws IOException, ServletException 

     String bucketName = "mcqimages";
        checkFileExtension(fileStream.getName());
        DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
        DateTime dt = DateTime.now(DateTimeZone.UTC);
        String dtString = dt.toString(dtf);
        final String fileName = fileStream.getName() + dtString;


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

        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");
        
    

【问题讨论】:

【参考方案1】:

最后我想出了这个代码:)。工作得很好。需要凭据将文件上传到 GCP 存储。您也可以从 JSON 格式生成凭据。

https://cloud.google.com/docs/authentication/production

     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 

                String bucketName = "mcqimages";
                checkFileExtension(fileStream.getName());
                DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
                DateTime dt = DateTime.now(DateTimeZone.UTC);
                String dtString = dt.toString(dtf);
                final String fileName = fileStream.getName() + dtString;

                File file = convertMultiPartToFile( fileStream );

                BlobInfo blobInfo =
                        storage.create(
                                BlobInfo
                                        .newBuilder(bucketName, fileName)
                                        .setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
                                        .build()
        //                     file.openStream() 
        );
                System.out.println(blobInfo.getMediaLink());
                return blobInfo.getMediaLink();
            


            private File convertMultiPartToFile(MultipartFile file ) throws IOException
            
                File convFile = new File( file.getOriginalFilename() );
                FileOutputStream fos = new FileOutputStream( convFile );
                fos.write( file.getBytes() );
                fos.close();
                return convFile;
            


            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】:

我会尝试上传文件:

public String uploadFile(@RequestParam("file") MultipartFile file) 
    if (file.isEmpty()) 
        //Set error message
    
    else 
        try 
            String extension = FilenameUtils.getExtension(file.getOriginalFilename()); //Commons IO

            // Get the file 
            byte[] bytes = file.getBytes();
            ....
    

上传文件的一个很好的例子是:https://www.baeldung.com/spring-file-upload

【讨论】:

让我试试。为什么我不能使用 FileItemStream 上传? ://【参考方案3】:
Credentials credentials = GoogleCredentials.fromStream(new ClassPathResource("key.json").getInputStream());   
Storage storage=StorageOptions.newBuilder().setCredentials(credentials).build().getService();
BlobId blobId = BlobId.of(bucketName, yourobjectName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
storage.create(blobInfo,Files.readAllBytes(Paths.get(filePath)));

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于春季启动图像上传到谷歌云存储桶不起作用的主要内容,如果未能解决你的问题,请参考以下文章

通过云端的 https 和 AWS 的 S3 存储桶不起作用

使用 multer 和 nodejs 将图像上传到谷歌云存储时出错

春季启动@Transactional 不起作用

春季启动验证不起作用

春季启动 - MySQL 设置不起作用

当我尝试将图像上传到 Firebase 存储时,putFile 在 kotlin 中不起作用