上传 application/octet-stream(图片 JPG - Spring 多部分 post 请求)
Upload application/octet-stream (image JPG - Spring Multipart post Request)
我正在尝试通过移动应用程序在我的服务器上存储图像 (jpg)
我用离子相机 (CameraPreview) 拍摄图像,并通过 post http 方法将它们传递给返回服务 (Spring)。
The problem is the format. The images are stored correctly but without any format.
这是拍照的相机代码:
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);
}
这是 server-side 代码:
@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 类型并且postman 发送的图像是 image/jpg
我尝试将 application/octet-stream 转换为 image/jpg,但在 java 中没有成功。
我还尝试将 Content-Type
headers 放入请求中,但我只遇到了一些错误...
我也试过直接通过form传图,不带blob,也没有blob和form,还是不行。
有什么办法可以在复制文件时将其传递给具体的表格吗?
或任何方式从离子相机格式化此图像?
谢谢!
这里可能有两个不同的问题。返回的图像数据是 base64 编码的 JPEG,当加上 data:image/jpeg;base64,
前缀时适合 Web 视图。但是普通的图片查看器(和大多数其他应用程序)期望 binary JPEG(不是 base64 编码),并且没有前置 data:image
标签。
我们可以通过打开服务器上的文件(使用十六进制或文本编辑器)来检查它是否是 base64 编码的。可以通过在文件开头附近添加字符串 'JFIF' 来识别二进制 JPEG。
如果是这样,首先要尝试将 base64 图像转换为二进制格式(没有 'data:image'),然后再将其发送到服务器。或者我们也可以转换服务器端。使用 Javascript 有 atob()
函数,而在服务器上 Java 8 有一个 Base64 库。还有一个来自 Apache Commons 的 coder/decoder(编解码器)。
文件扩展名可以通过给fd.append()
指定一个完整的文件名来解决。
我正在尝试通过移动应用程序在我的服务器上存储图像 (jpg)
我用离子相机 (CameraPreview) 拍摄图像,并通过 post http 方法将它们传递给返回服务 (Spring)。
The problem is the format. The images are stored correctly but without any format.
这是拍照的相机代码:
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);
}
这是 server-side 代码:
@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 类型并且postman 发送的图像是 image/jpg
我尝试将 application/octet-stream 转换为 image/jpg,但在 java 中没有成功。
我还尝试将 Content-Type
headers 放入请求中,但我只遇到了一些错误...
我也试过直接通过form传图,不带blob,也没有blob和form,还是不行。
有什么办法可以在复制文件时将其传递给具体的表格吗? 或任何方式从离子相机格式化此图像?
谢谢!
这里可能有两个不同的问题。返回的图像数据是 base64 编码的 JPEG,当加上 data:image/jpeg;base64,
前缀时适合 Web 视图。但是普通的图片查看器(和大多数其他应用程序)期望 binary JPEG(不是 base64 编码),并且没有前置 data:image
标签。
我们可以通过打开服务器上的文件(使用十六进制或文本编辑器)来检查它是否是 base64 编码的。可以通过在文件开头附近添加字符串 'JFIF' 来识别二进制 JPEG。
如果是这样,首先要尝试将 base64 图像转换为二进制格式(没有 'data:image'),然后再将其发送到服务器。或者我们也可以转换服务器端。使用 Javascript 有 atob()
函数,而在服务器上 Java 8 有一个 Base64 库。还有一个来自 Apache Commons 的 coder/decoder(编解码器)。
文件扩展名可以通过给fd.append()
指定一个完整的文件名来解决。