自己去申请开通阿里云oss。
1.在pom.xml添加依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.14.0</version>
</dependency>
2.在application.yml 加入OSS配置值
aliyun:
oss:
# oss对外服务的访问域名
endpoint: oss-cn-xxxxx.aliyuncs.com
# 访问身份验证中用到用户标识(填自己的)
accessKeyId: xxxxxx
# 用户用于加密签名字符串和oss用来验证签名字符串的密钥(填自己的)
accessKeySecret: xxxxxx
# oss的存储空间
bucketName: xxxxx
# 上传文件大小(M)
maxSize: 3
# 上传文件夹路径前缀
dir:
prefix: xxxxxx/
3.在项目的包config创建配置类OssConfig.java
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. 在控制层 上传图片,新建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. 需要注意的是,如果上传图片为空,或者 上传图片过大。后端控制台会直接报错。比如:
上传图片是空的
控制台报:因为我异常做了统一封装
异常情况org.springframework.web.multipart.MultipartException: Current request is not a multipart request
网上的帖子说,给postman的header加content-type为multipart/form-data。
但我测试时,加不加是无所谓的。加了反而又报其他bug。
如果你在控制层,做判断,也不行的
if(file.isEmpty()){
//图片没上传
}
因为springboot直接就把异常给捕捉了,并返回统一异常
{
"code": 404,
"msg": "服务器异常~",
"data": null
}
6. 还有一个异常是,上传文件过大时报
控制台打印出。
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.
网上的说法都是tomcat已经默认允许你只上传1M的文件,但我这里是2M的。
但我oss配置的最大文件不是3M吗?
然后在application.yml写配置,在server怎么写,控制台永远都是1M的
应该在spring写配置
7.最后怎么让前端能正确返回异常消息呢?
/**
* 处理文件上传大小超限制
*/
@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.异常返回
9.正确返回