使用API上传图像,但每次都得到损坏的图像

问题描述 投票:0回答:1

我正在使用此类进行 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。但是,图像已损坏,我无法使用任何图像查看器打开它。我做错了什么?

java rest file-upload
1个回答
0
投票

尝试使用 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);
       
       //...
       //...
}
© www.soinside.com 2019 - 2024. All rights reserved.