Springboot Alibaba Cloud oss image upload and exception handling

Apply for the activation of Alibaba Cloud oss ​​by yourself.

Object Storage OSS_Cloud Storage Service_Enterprise Data Management_Storage-Alibaba Cloud

1. Add dependencies in pom.xml

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.14.0</version>
        </dependency>

 2. Add OSS configuration values ​​in application.yml

aliyun:
  oss:
    # oss对外服务的访问域名
    endpoint: oss-cn-xxxxx.aliyuncs.com
    # 访问身份验证中用到用户标识(填自己的)
    accessKeyId: xxxxxx
    # 用户用于加密签名字符串和oss用来验证签名字符串的密钥(填自己的)
    accessKeySecret: xxxxxx
    # oss的存储空间
    bucketName: xxxxx
    # 上传文件大小(M)
    maxSize: 3
    # 上传文件夹路径前缀
    dir:
      prefix: xxxxxx/

3. Create a configuration class OssConfig.java in the project's package config

package com.xxxx.config;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 阿里云OSS配置信息
 */
@Configuration
public class OssConfig {

    @Value("${aliyun.oss.endpoint}")
    String endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    String accessKeySecret;

    @Bean
    public OSSClient createOssClient() {
        return (OSSClient) new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
}

4. Upload pictures in the control layer and create a new UploadController.java

package com.xxxx.controller;

/**
 * 阿里云Oss上传图片
 */
@RestController
public class UploadController {

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Value("${aliyun.oss.dir.prefix}")
    private String dirPrefix;

    @Resource
    private OSSClient ossClient;

    
    //允许上传的格式 可以自己增加上传文件格式
    private static final String[] IMAGE_TYPE = new String[]{".jpg", ".jpeg", ".gif", ".png"};

    @PostMapping("/upload")
    public ApiRestResponse upload(@RequestParam("photo") MultipartFile file) {
        //在这里写判断file isEmpty是无效的,压根进不去,之间就被拦截异常了
        //if(file.isEmpty()){....}
        //写file.getSize()也是无效的

        boolean bol = assessFileType(file);
        if (!bol) {
            return ApiRestResponse.error(400, "上传格式不对~");
        }
        String url = "";
        try {

            InputStream inputStream = file.getInputStream();
            //整理文件名称
            String fileName = getFileName(file);
            //创建PutObject请求
            PutObjectResult result = ossClient.putObject(bucketName, fileName, inputStream);
            System.out.println(result);

            //关闭OOSClient
            //ossClient.shutdown();

            //返回完整路径给前端
            url = "https://" + bucketName + "." + ossClient.getEndpoint().getHost() + "/" + fileName;
        } catch (IOException e) {
            return ApiRestResponse.error(400, "上传失败~");
        }
        return ApiRestResponse.success(url);
    }

    /**
     * 整理上传 文件名称 和 路径
     * @param file
     * @return
     */
    private String getFileName(MultipartFile file) {
        // 文件后缀
        String suffixName = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
        //文件名称
        String fileName = UUID.randomUUID().toString() + suffixName;

        //当前年月日
        String loalYmd = DateTimeUtil.localYmd();
        String path = dirPrefix + loalYmd + "/" + fileName;

        return path;
    }

    /**
     * 判断文件格式
     */
    private boolean assessFileType(MultipartFile file) {
        //对图片的后缀名做校验
        boolean isPass = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), type)) {
                isPass = true;
                break;
            }
        }
        return isPass;
    }
}

5. It should be noted that if the uploaded picture is empty, or the uploaded picture is too large. The backend console will directly report an error. for example:

upload image is empty

Console report: Because I made a unified package for exception

异常情况org.springframework.web.multipart.MultipartException: Current request is not a multipart request

 The online post says to add content-type to the header of postman as multipart/form-data.

But when I tested it, it didn't matter whether it was added or not. Added it but reported other bugs.

If you are in the control layer, making judgments will not work

if(file.isEmpty()){
   //图片没上传
}

Because springboot directly captures the exception and returns a unified exception

{
    "code": 404,
    "msg": "服务器异常~",
    "data": null
}

6. Another exception is that the uploaded file is too large

The console prints out. 

Maximum upload size exceeded; nested exception is 
java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: 
The field photo exceeds its maximum permitted size of 2097152 bytes.

It is said on the Internet that tomcat has allowed you to upload only 1M files by default, but mine is 2M here.

But isn't the largest file configured by my oss 3M?

 Then write the configuration in application.yml, how to write it in the server, the console will always be 1M

 The configuration should be written in spring

7. Finally, how can the front end return the exception message correctly?

    /**
     * 处理文件上传大小超限制
     */
    @ExceptionHandler(MultipartException.class)
    @ResponseBody
    public ApiRestResponse fileUploadExceptionHandler(MultipartException e) {
        log.error("上传文件异常:", e);
        if (e.getRootCause() instanceof org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException) {
           
            return ApiRestResponse.error(400, "上传文件不能超过2M");

        }else if(e.getRootCause() instanceof org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException){
            
            return ApiRestResponse.error(400, "上传文件异常");
        }
        return ApiRestResponse.error(400, "上传文件不存在或异常");
    }

8. Abnormal return

9. Return correctly

Guess you like

Origin blog.csdn.net/deng_zhihao692817/article/details/130593759