【问题标题】:Upload application/octet-stream (image JPG - Spring Multipart post Request)上传应用程序/八位字节流(图片 JPG - Spring Multipart post Request)
【发布时间】:2023-03-10 19:42:01
【问题描述】:

我正在尝试通过移动应用在我的服务器上存储图像 (jpg)

我使用离子相机 (CameraPreview) 拍摄图像并通过 post http 方法将它们传递给 Back 服务 (Spring)。

问题在于格式。图片已正确存储,但没有任何格式

这是拍照的相机代码:

 takePicture() {
    this.cameraPreview.takePicture(this.pictureOpts).then((imageData) => {
     this.selectedImage = 'data:image/jpeg;base64,' + imageData;
      this.globalDataService.changePictureTaken(this.selectedImage);
      this.location.back();
    }, (err) => {
      console.log(err);
      this.selectedImage = 'assets/img/test.jpg';
    });
  }

这是将图像发送到服务器的代码

uploadImageService(url: string, param: any) {
    const fd: FormData = new FormData();
    const imgBlob = new Blob([param],{type: param.type});
    fd.append('file', imgBlob);
     return this.http
       .post(url, fd, httpOptionsImages);
  }

这是服务器端代码:

 @RequestMapping(method = RequestMethod.POST, value = "/subir-imagen")
    public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException, SQLException {
        LOGGER.log(Level.INFO, "/subir-imagen, handleFileUpload file.tostring {0}", file.toString());
 String fileName = fileManagerService.storeFile(file);
 String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                .path("/downloadFile/")
                .path(fileName)
                .toUriString()
        return ResponseEntity.ok(fileDownloadUri);
}

public String storeFile(MultipartFile file) throws SQLException, IOException {
        // Normalize file name
        String fileName = StringUtils.cleanPath(file.getName());
        try {
            // Check if the file's name contains invalid characters
            if (fileName.contains("..")) {
                LOGGER.log(Level.INFO, "Sorry! Filename contains invalid path sequence {0}", fileName);
            }
            String extension = FilenameUtils.getExtension(file.getOriginalFilename());
            Path path = Paths.get(fileStoragePath + File.separator + fileName + "." + extension.toLowerCase());
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
       } 
       catch (IOException ex) {
            LOGGER.log(Level.INFO, "Could not store file " + fileName + ". Please try again! {0}", ex);
       }
    return fileName;
}

当我通过 Postman 发出 post 请求时,图像以正确的格式存储,下载时,图像正确显示。

当我通过应用程序发出请求时,图像正确存储在服务器中,但没有扩展,我尝试手动输入格式但无法显示。

当我在服务器端file.getContentType());运行时,我看到我的应用程序发送的图像是application/octet-stream类型,邮递员发送的图像是image/ jpg

我尝试在 java 中将 application/octet-stream 转换为 image/jpg,但没有成功。 我还尝试将Content-Typeheaders 放入请求中,但我只有一些错误...

我也试过直接通过form传图片,不带blob,也可以不带blob或者form,还是不行。

有什么方法可以在复制文件时将其传递给具体形式? 或任何方式从离子相机格式化此图像?

谢谢!

【问题讨论】:

  • 澄清一下,当您说“无格式”时,您的意思是指文件名中没有文件扩展名(例如 jpg)或其他内容吗?
  • @peekay 保存的图像没有扩展名,(.jpg,.png ...)但就好像它们没有任何格式一样。如果我手动为它们提供 .png 或 .jpg 格式,照片查看器不会读取它们并显示错误,就好像它们不兼容一样。

标签: spring image file-upload format ionic4


【解决方案1】:

这里可能有两个不同的问题。返回的图像数据是 base64 编码 JPEG,当带有 data:image/jpeg;base64, 时,它适用于 Web 视图。但是普通的图片查看器(和大多数其他应用程序)需要 二进制 JPEG(不是 base64 编码),并且没有预先添加 data:image 标记。

我们可以通过打开服务器上的文件(使用十六进制或文本编辑器)来检查它是否是 base64 编码的。二进制 JPEG 可以通过在文件开头附近使用字符串“JFIF”来识别。

如果是这样,首先要尝试将 base64 图像转换为二进制格式(不带“data:image”),然后再将其发送到服务器。或者我们也可以转换服务器端。使用 Javascript 有 atob() 函数,而在服务器上 Java 8 有一个 Base64 库。还有一个来自 Apache Commons 的编码器/解码器(编解码器)。

文件扩展名可以通过将完整文件名指定为fd.append()来解决。

【讨论】:

  • 我已尝试删除数据:图像的图像,图像未显示在应用程序中并且仍未正确保存。你能更好地解释一下 atob() 或 coder/decoder 是什么意思吗?
  • JPEG图像可以用两种不同的文件格式(编码)来表示。第一种是binary编码,第二种是base64编码. (Base64 也称为“文本”编码。)。您的应用程序需要 base64 编码(加上“数据:图像”等标签)。但大多数其他应用程序(图片查看器、photoshop 等)都需要原始二进制编码。由于不同的目的需要两种不同的编码,因此您可以使用 Javascript 中的 atob() / btoa() 或 Java/Apache 等价函数在它们之间进行转换。
  • 另请参阅:developer.mozilla.org/en-US/docs/Web/API/WindowBase64/… 以了解其他转换选项(例如转换为缓冲区数组)。
猜你喜欢
  • 1970-01-01
  • 2022-10-11
  • 2012-08-14
  • 2019-05-13
  • 2012-11-17
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多