Spring boot上传文件(图片)到阿里云OSS(直接上传到应用服务器)
主要思路
上传图片的思路有两种:
- 第一种是上传到应用服务器,再由应用服务器上传到OSS。这种适合上传的文件较小,较为简单,但文件过大会造成服务器压力变大。
-
第二种是利用签名直传的方式,较为复杂,但能减轻服务器的压力。
直接上传到应用服务器的方式
0.导入依赖
除去常规的依赖还需要以下依赖:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
1.写配置
这里的配置主要是为了方便后面修改,可以直接利用读取配置文件的方式编写工具类,需要用到这些阿里云的相关参数时直接调用工具类即可。四个主要的属性需要参照自己实际情况来填写。
aliyun.oss.file.endpoint=<endpoint>
aliyun.oss.file.keyid=<keyid>
aliyun.oss.file.keysecret=<keysecret>
aliyun.oss.file.bucketname=<bucketname>
2.写工具类
编写一个工具类,读取配置文件,其中InitializingBean是为了复制给public静态变量,afterPropertiesSet()会在容器加载完后执行。
@Component
public class OssUtil implements InitializingBean {
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;
@Value("${aliyun.oss.file.keyid}")
private String accessKeyID;
@Value("${aliyun.oss.file.keysecret}")
private String accesskeySecret;
@Value("${aliyun.oss.file.bucketname}")
private String bucketName;
public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
ACCESS_KEY_ID = accessKeyID;
ACCESS_KEY_SECRET = accesskeySecret;
BUCKET_NAME = bucketName;
}
}
3.编写Controller和Service
完整的包结构:
编写Controller:其中CrossOrigin是为了解决跨域请求的问题,这里会调用service的上传方法,返回一个url,这样,我们就可以把这个url存进数据库了。
@RestController
@RequestMapping("/cat")
@CrossOrigin
public class OSSController {
@Autowired
private OSSService ossService;
@PostMapping("/oss/upload")
public String upload(@RequestPart("file") MultipartFile file){
String url = ossService.uploadFile(file);
return url;
}
}
编写service:这里只展示实现类
@Service
public class OSSServiceImpl implements OSSService {
@Override
public String uploadFile(MultipartFile file) {
String url = null;
String endpoint = OssUtil.END_POINT;
String accessKeyId = OssUtil.ACCESS_KEY_ID;
String accessKeySecret = OssUtil.ACCESS_KEY_SECRET;
String bucketName = OssUtil.BUCKET_NAME;
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
InputStream inputStream = file.getInputStream();
//获取上传的文件的名字
String filename = file.getOriginalFilename();
//随机uuid是为了拼接文件名,防止用户上传两个名字相同的文件后覆盖掉前一个
UUID uuid = UUID.randomUUID();
//这里是为了按上传时间分配目录。精确到月
String s = DateTime.now().toString("yyyy/MM/");
//拼接成完整的文件名。
filename = s + uuid + filename;
//传入三个参数
ossClient.putObject(bucketName, filename, inputStream);
//拼接url
url = "https://" + bucketName + "." + endpoint + "/" + filename;
} catch (IOException e) {
e.printStackTrace();
}finally {
ossClient.shutdown();
}
return url;
}
}
4.测试
启动项目,浏览器访问http://localhost:8080/swagger-ui/ 进行接口测试
上传文件:
上传成功:
阿里云oss控制台就可以看到相应的文件了: