赞
踩
上次用laravel进行了一些s3得整合,可以看出来其实蛮简单得。
先导包
- <dependency>
- <groupId>software.amazon.awssdk</groupId>
- <artifactId>s3</artifactId>
- </dependency>
然后在配置类中写bean
- private static final String AK = "xxxxxxxxxxxx";
- private static final String SK = "xxxxxxxxxxxx";
-
- @Bean
- public S3Client s3Client() {
- return S3Client.builder()
- .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(AK, SK)))
- .region(Region.US_WEST_2)
- .build();
- }
然后就可以用注解拿到s3client了,直接开始写接口
Controller
- @ApiOperation("上传文件")
- @PostMapping("/upload")
- public Response upload(@RequestParam("file") MultipartFile file) {
- if (StringUtils.isBlank(file.getOriginalFilename())) {
- return Response.fail(RespCode.FILE_NAME_IS_EMPTY);
- }
- if (file.getSize() == 0L) {
- return Response.fail(RespCode.FILE_IS_EMPTY);
- }
- if (file.getSize() > FILE_MAX_BYTE) {
- return Response.fail(RespCode.FILE_TOO_LARGE);
- }
- return SingleResponse.ok(s3Service.upload(file));
- }
Service
- @Service
- public class S3Service {
-
- @Autowired
- private S3Client s3Client;
-
- public static final String BUCKET_NAME = "xxxxxxxx";
- public static final String URL = "xxxxxxxxxx";
-
- public String upload(MultipartFile multipartFile) {
- String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");
- String fileSuf = null;
- int index = multipartFile.getOriginalFilename().lastIndexOf(".");
- if (index > -1) {
- fileSuf = multipartFile.getOriginalFilename().substring(index);
- }
- File file = new File(tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + fileSuf);
- try {
- multipartFile.transferTo(file);
- file.deleteOnExit();
- } catch (IOException e) {
- throw new SvcException(e.getMessage());
- }
- return upload(file);
- }
-
- public String upload(File file) {
- PutObjectRequest putOb = PutObjectRequest.builder()
- .bucket(BUCKET_NAME)
- .key(file.getName())
- .build();
- s3Client.putObject(putOb, RequestBody.fromFile(file));
- return StringUtils.join(URL, file.getName());
- }
-
- }

String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");这一句根据你不同得web容器可能会有不一样得效果,一般是tomcat没什么大毛病,但是我这次用的undertow ,就有一点小坑。如果大家也是用undertow ,大家可以看看这个博客自己解决
至此,s3基本上传功能是没问题了。
但是我想要改装一下,把图片格式都变成jpg,我使用的是java得imageIO类来处理。先把第一个upload改装一下
- public String upload(MultipartFile multipartFile) {
- String tmpPath = StringUtils.join(System.getProperties().getProperty("java.io.tmpdir"), "/");
- String fileSuf = null;
- int index = multipartFile.getOriginalFilename().lastIndexOf(".");
- if (index > -1) {
- fileSuf = ".jpg"; // 将所有上传的图片统一转换为 JPG 格式
- }
- File file = new File(tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + fileSuf);
- try {
- multipartFile.transferTo(file);
- file.deleteOnExit();
-
- // 转换上传的图片为 JPG 格式
- String outputImagePath = tmpPath + UUIDUtils.lowerCaseNoSeparatorUUID() + ".jpg";
- ImageConverterUtils.convertToJPG(file.getAbsolutePath(), outputImagePath);
-
- // 调用自己的 upload 方法处理图片上传
- return upload(new File(outputImagePath));
- } catch (IOException e) {
- throw new SvcException(e.getMessage());
- }
- }

我自己写了个很简单得工具类
- public class ImageConverterUtils {
- public static void convertToJPG(String sourceImage,String outputImage) throws IOException {
- File source = new File(sourceImage);
- BufferedImage bufferedImage = ImageIO.read(source);
-
- File output = new File(outputImage);
- ImageIO.write(bufferedImage,"jpg",output);
-
- }
- }
到这里确实可以把一些图片转换成jpg并且上传到s3,不过依旧有坑。
第一个就是其实imageIO貌似不支持webp格式得转换,一次webp格式得图片总数会转换不成功
很好解决,添加个pom依赖就好:
- <dependency>
- <groupId>org.sejda.imageio</groupId>
- <artifactId>webp-imageio</artifactId>
- <version>0.1.6</version>
- </dependency>
第二,不仅不支持webp,而且png也会出毛病。我的毛病是只要是png格式的,ImageIO.write居然返回false,抛出异常了。原因是ImageIO.wite方法在中调用的私有方法getWriter寻找合适的ImageWriter时不仅与formatName相关,还是输入的原图有关,造成getWriter方法找不到对应的ImageWriter。
因此改造成了一下我的工具类:
- public class ImageConverterUtils {
- public static void convertToJPG(String sourceImage,String outputImage) throws IOException {
- File source = new File(sourceImage);
- BufferedImage bufferedImage = ImageIO.read(source);
- BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
- bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
- Graphics2D g = newBufferedImage.createGraphics();
- g.drawImage(bufferedImage, 0, 0,null);
- File output = new File(outputImage);
- ImageIO.write(newBufferedImage,"jpg",output);
- g.dispose();
- }
- }
然后就没问题了,可以正常上传和转换格式了。
这里顺带有个蛮好用的网站,可以看到文件的MIME类型:MIME File Type Checker - HTMLStrip
java : 调用ImageIO.writer从BufferedImage生成jpeg图像的坑-CSDN博客
[ 云计算 | AWS 实践 ] Java 应用中使用 Amazon S3 进行存储桶和对象操作完全指南 - 知乎 (zhihu.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。