当前位置:   article > 正文

springboot整合s3,用ImageIO进行图片格式转换_springboot配置两个s3

springboot配置两个s3

上次用laravel进行了一些s3得整合,可以看出来其实蛮简单得。

先导包

  1. <dependency>
  2. <groupId>software.amazon.awssdk</groupId>
  3. <artifactId>s3</artifactId>
  4. </dependency>

然后在配置类中写bean

  1. private static final String AK = "xxxxxxxxxxxx";
  2. private static final String SK = "xxxxxxxxxxxx";
  3. @Bean
  4. public S3Client s3Client() {
  5. return S3Client.builder()
  6. .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(AK, SK)))
  7. .region(Region.US_WEST_2)
  8. .build();
  9. }

然后就可以用注解拿到s3client了,直接开始写接口

Controller

  1. @ApiOperation("上传文件")
  2. @PostMapping("/upload")
  3. public Response upload(@RequestParam("file") MultipartFile file) {
  4. if (StringUtils.isBlank(file.getOriginalFilename())) {
  5. return Response.fail(RespCode.FILE_NAME_IS_EMPTY);
  6. }
  7. if (file.getSize() == 0L) {
  8. return Response.fail(RespCode.FILE_IS_EMPTY);
  9. }
  10. if (file.getSize() > FILE_MAX_BYTE) {
  11. return Response.fail(RespCode.FILE_TOO_LARGE);
  12. }
  13. return SingleResponse.ok(s3Service.upload(file));
  14. }

Service

  1. @Service
  2. public class S3Service {
  3. @Autowired
  4. private S3Client s3Client;
  5. public static final String BUCKET_NAME = "xxxxxxxx";
  6. public static final String URL = "xxxxxxxxxx";
  7. public String upload(MultipartFile multipartFile) {
  8. String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");
  9. String fileSuf = null;
  10. int index = multipartFile.getOriginalFilename().lastIndexOf(".");
  11. if (index > -1) {
  12. fileSuf = multipartFile.getOriginalFilename().substring(index);
  13. }
  14. File file = new File(tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + fileSuf);
  15. try {
  16. multipartFile.transferTo(file);
  17. file.deleteOnExit();
  18. } catch (IOException e) {
  19. throw new SvcException(e.getMessage());
  20. }
  21. return upload(file);
  22. }
  23. public String upload(File file) {
  24. PutObjectRequest putOb = PutObjectRequest.builder()
  25. .bucket(BUCKET_NAME)
  26. .key(file.getName())
  27. .build();
  28. s3Client.putObject(putOb, RequestBody.fromFile(file));
  29. return StringUtils.join(URL, file.getName());
  30. }
  31. }
String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");这一句根据你不同得web容器可能会有不一样得效果,一般是tomcat没什么大毛病,但是我这次用的undertow ,就有一点小坑。如果大家也是用undertow ,大家可以看看这个博客自己解决

spring boot文件上传、undertow 临时文件配置、NoSuchFileException: /tmp/under、IOException: No space left on device_springboot上传文件临时文件清理-CSDN博客

至此,s3基本上传功能是没问题了。

但是我想要改装一下,把图片格式都变成jpg,我使用的是java得imageIO类来处理。先把第一个upload改装一下

  1. public String upload(MultipartFile multipartFile) {
  2. String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");
  3. String fileSuf = null;
  4. int index = multipartFile.getOriginalFilename().lastIndexOf(".");
  5. if (index > -1) {
  6. fileSuf = ".jpg"; // 将所有上传的图片统一转换为 JPG 格式
  7. }
  8. File file = new File(tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + fileSuf);
  9. try {
  10. multipartFile.transferTo(file);
  11. file.deleteOnExit();
  12. // 转换上传的图片为 JPG 格式
  13. String outputImagePath = tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + ".jpg";
  14. ImageConverterUtils.convertToJPG(file.getAbsolutePath(), outputImagePath);
  15. // 调用自己的 upload 方法处理图片上传
  16. return upload(new File(outputImagePath));
  17. } catch (IOException e) {
  18. throw new SvcException(e.getMessage());
  19. }
  20. }

我自己写了个很简单得工具类

  1. public class ImageConverterUtils {
  2. public static void convertToJPG(String sourceImage,String outputImage) throws IOException {
  3. File source = new File(sourceImage);
  4. BufferedImage bufferedImage = ImageIO.read(source);
  5. File output = new File(outputImage);
  6. ImageIO.write(bufferedImage,"jpg",output);
  7. }
  8. }

到这里确实可以把一些图片转换成jpg并且上传到s3,不过依旧有坑。

第一个就是其实imageIO貌似不支持webp格式得转换,一次webp格式得图片总数会转换不成功

很好解决,添加个pom依赖就好:

  1. <dependency>
  2. <groupId>org.sejda.imageio</groupId>
  3. <artifactId>webp-imageio</artifactId>
  4. <version>0.1.6</version>
  5. </dependency>

第二,不仅不支持webp,而且png也会出毛病。我的毛病是只要是png格式的,ImageIO.write居然返回false,抛出异常了。原因是ImageIO.wite方法在中调用的私有方法getWriter寻找合适的ImageWriter时不仅与formatName相关,还是输入的原图有关,造成getWriter方法找不到对应的ImageWriter。

因此改造成了一下我的工具类:

  1. public class ImageConverterUtils {
  2. public static void convertToJPG(String sourceImage,String outputImage) throws IOException {
  3. File source = new File(sourceImage);
  4. BufferedImage bufferedImage = ImageIO.read(source);
  5. BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
  6. bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
  7. Graphics2D g = newBufferedImage.createGraphics();
  8. g.drawImage(bufferedImage, 0, 0,null);
  9. File output = new File(outputImage);
  10. ImageIO.write(newBufferedImage,"jpg",output);
  11. g.dispose();
  12. }
  13. }

然后就没问题了,可以正常上传和转换格式了。

这里顺带有个蛮好用的网站,可以看到文件的MIME类型:MIME File Type Checker - HTMLStrip

 

java : 调用ImageIO.writer从BufferedImage生成jpeg图像的坑-CSDN博客

[ 云计算 | AWS 实践 ] Java 应用中使用 Amazon S3 进行存储桶和对象操作完全指南 - 知乎 (zhihu.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/707080
推荐阅读
相关标签
  

闽ICP备14008679号