Spring Boot应用中如何实现图片大小校验与超限自动压缩?
在Spring Boot中实现图片上传的大小校验与自动压缩
一、基础配置:拦截超大请求
先通过Spring配置设置文件上传的基础阈值,避免容器直接拦截过大的请求:
spring: servlet: multipart: max-file-size: 50MB # 单个文件最大允许值,按需调整 max-request-size: 100MB # 整个请求的总文件大小限制
二、自定义大小校验与压缩逻辑
1. 配置可调整的参数
创建配置类,把压缩阈值、目标尺寸等参数抽出来,方便后续修改:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "image.upload") public class ImageUploadProperties { // 触发压缩的大小阈值(2MB) private long compressThreshold = 2 * 1024 * 1024; // 压缩后的目标宽度(按比例缩放高度) private int targetWidth = 1920; // 图片质量(0-1,值越高质量越好) private float quality = 0.7f; // getter、setter 省略 }
2. 实现图片压缩工具类
用Thumbnails库简化压缩逻辑,先在pom.xml添加依赖:
<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.19</version> </dependency>
编写工具类,集成大小校验和压缩:
import net.coobird.thumbnailator.Thumbnails; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; import java.io.File; import java.io.InputStream; @Component public class ImageCompressUtil { private final ImageUploadProperties properties; public ImageCompressUtil(ImageUploadProperties properties) { this.properties = properties; } public MultipartFile processImage(MultipartFile file) throws IOException { // 大小未超过阈值,直接返回原文件 if (file.getSize() <= properties.getCompressThreshold()) { return file; } // 执行压缩 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Thumbnails.of(file.getInputStream()) .size(properties.getTargetWidth(), Integer.MAX_VALUE) // 按宽度等比例缩放 .outputQuality(properties.getQuality()) .toOutputStream(outputStream); // 包装为MultipartFile返回 return new CustomMultipartFile(file.getOriginalFilename(), file.getContentType(), outputStream.toByteArray()); } // 自定义MultipartFile实现,用于包装压缩后的字节数据 private static class CustomMultipartFile implements MultipartFile { private final String filename; private final String contentType; private final byte[] content; public CustomMultipartFile(String filename, String contentType, byte[] content) { this.filename = filename; this.contentType = contentType; this.content = content; } @Override public String getName() { return filename; } @Override public String getOriginalFilename() { return filename; } @Override public String getContentType() { return contentType; } @Override public boolean isEmpty() { return content.length == 0; } @Override public long getSize() { return content.length; } @Override public byte[] getBytes() { return content; } @Override public InputStream getInputStream() { return new ByteArrayInputStream(content); } @Override public void transferTo(File dest) throws IOException { Files.write(dest.toPath(), content); } } }
3. 在Controller中集成
在上传接口里调用工具类,完成校验、压缩和后续业务处理:
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @RestController public class ImageUploadController { private final ImageCompressUtil imageCompressUtil; public ImageUploadController(ImageCompressUtil imageCompressUtil) { this.imageCompressUtil = imageCompressUtil; } @PostMapping("/upload/image") public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file) throws IOException { // 校验是否为图片类型 String contentType = file.getContentType(); if (contentType == null || !contentType.startsWith("image/")) { return ResponseEntity.badRequest().body("仅支持上传图片类型文件"); } // 处理图片:校验大小并压缩 MultipartFile processedFile = imageCompressUtil.processImage(file); // 此处添加文件保存逻辑(如存本地、OSS等) // saveToStorage(processedFile); return ResponseEntity.ok(String.format("上传成功:原大小%.2fMB,处理后%.2fMB", file.getSize() / 1024.0 / 1024, processedFile.getSize() / 1024.0 / 1024)); } }
三、优化建议
- 全局异常处理:捕获压缩时的IO异常、不支持的图片格式异常,返回标准化错误响应。
- 格式适配:针对PNG、WebP等格式做特殊处理,比如保留PNG的透明度。
- 异步处理:大图片压缩耗时较长时,用异步线程处理,避免阻塞请求线程。
内容的提问来源于stack exchange,提问作者Gaur 97
相关产品推荐
相关产品推荐

