我正在使用此类进行 API 调用:
@Path("uploads")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UploadResource extends BaseResource {
private static final int DEFAULT_BUFFER_SIZE = 8192;
private static final int IMAGE_SIZE_LIMIT = 2000000;
private static final int PDF_SIZE_LIMIT = 5000000;
private static final Logger LOGGER = LoggerFactory.getLogger(UploadResource.class);
private String imageExtension(String type) {
switch (type) {
case "image/jpeg":
return "jpg";
case "image/png":
return "png";
case "image/gif":
return "gif";
case "image/webp":
return "webp";
case "image/svg+xml":
return "svg";
default:
throw new IllegalArgumentException("Unsupported image type");
}
}
@Path("{entity}/{id}")
@POST
@Consumes("image/*")
public Response uploadImage(@PathParam("entity") String entity, @PathParam("id") long entityId, File file,
@HeaderParam(HttpHeaders.CONTENT_TYPE) String type) {
try {
// Extract the file extension from the content type
String extension = type.substring("image/".length());
String name = entityId + "_" + new Date().getTime();
// Ensure correct buffer size and image size limit handling
try (FileInputStream input = new FileInputStream(file);
OutputStream output = Context.getMediaManager().createFileStream(entity, name, extension)) {
byte[] buffer = new byte[8192]; // Use 8 KB buffer
int read;
long transferred = 0;
// Read in chunks and write to output
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
transferred += read;
// Check if the image size exceeds the limit
if (transferred > IMAGE_SIZE_LIMIT) {
throw new IllegalArgumentException("Image size limit exceeded"+transferred);
}
}
output.flush(); // Ensure all data is written
}
// Return successful response with the generated image file name
Map<String, String> result = new HashMap<>();
result.put("image", name + "." + extension);
return Response.ok(ResponseHelper.getResultWith_200(result)).build();
}
catch (Exception ex) {
LOGGER.warn("Image upload failed (LS): ", ex); // Log the entire exception stack trace
return Response.ok(ResponseHelper.getResultWith_400(ResponseHelper.formatMsg(ex.getMessage()))).build();
}
}
}
下面是我的 MediaManager:
public class MediaManager {
private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class);
private final String path;
public MediaManager(String path) {
this.path = path;
}
private File createFile(String uniqueId, String name) throws IOException {
Path filePath = Paths.get(path, uniqueId, name);
Path directoryPath = filePath.getParent();
if (directoryPath != null) {
Files.createDirectories(directoryPath);
}
LOGGER.info("Creating file at path: {}", filePath);
return filePath.toFile();
}
public OutputStream createFileStream(String uniqueId, String name, String extension) throws IOException {
File file = createFile(uniqueId, name + "." + extension);
LOGGER.info("Opening output stream for file: {}", file.getAbsolutePath());
return new FileOutputStream(file);
}
}
每次我使用正文或表单数据中的二进制选择从邮递员上传图像(无论是 .png/.jpeg/.jpg)时, 使用正确的名称、目录和大小创建一个空映像,例如 502kb 而不是 0kb。但是,图像已损坏,我无法使用任何图像查看器打开它。我做错了什么?
尝试使用 MULTIPART_FORM_DATA 和 FormDataParam 代替 PathParam 实现,如以下代码:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/endpoint_name")
public Response uploadImage(@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition contentDispositionHeader,
@FormDataParam("id") long id,
@FormDataParam("entity") String entity,
@HeaderParam(HttpHeaders.CONTENT_TYPE) String type){
// Extract the file extension from the content type
String extension = type.substring("image/".length());
String name = entityId + "_" + new Date().getTime();
//save file in tomcat temporary directory
File file = File.createTempFile(name, "."+extension);
Files.copy(fileInputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
//...
//...
}