笔主很早就开始用阿里云OSS 存储服务当做自己的图床了。如果没有用过阿里云OSS 存储服务或者不是很了解这个东西的可以看看官方文档,我这里就不多做介绍了。阿里云对象存储 OSS文档,:
https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.4e401c62EyJK5T
本篇文章会介绍到 SpringBoot 整合阿里云OSS 存储服务实现文件上传下载以及简单的查看。其实今天讲的应该算的上是一个简单的小案例了,涉及到的知识点还算是比较多。
目录:
一 开发前的准备
1.1 前置知识
1.2 环境参数
1.3 你能学到什么
1.4 创建工程
1.5 项目结构
1.6 配置 pom 文件中的相关依赖
二 配置阿里云 OSS 存储相关属性
2.1 通过常量类配置(本项目使用的方式)
2.2 通过.properties 配置
三 工具类相关方法编写
四 Controller 层编写相关测试方法
五 启动类
六 上传图片相关前端页面
七 测试我们的图床
一 开发前的准备
1.1 前置知识
具有 Java 基础以及SpringBoot 简单基础知识即可。
1.2 环境参数
开发工具:IDEA
基础工具:Maven+JDK8
所用技术:SpringBoot+阿里云OSS 存储服务 Java 相关API
SpringBoot版本:2.1.0
1.3 你能学到什么
SpringBoot 整合 阿里云OSS 存储服务并编写相关工具类
SpringBoot 整合 thymeleaf 并实现前后端传值
SpringBoot 从配置文件读取值并注入到类中
如何自己搭建一个图床使用(通过前端选择图片,支持预览,但不支持修改图片)
1.4 创建工程
创建一个基本的 SpringBoot 项目,我这里就不多说这方面问题了,具体可以参考下面这篇文章:
https://blog.csdn.net/qq_34337272/article/details/79563606
1.5 项目结构
项目结构
1.6 配置 pom 文件中的相关依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
<!-- Thymeleaf-->
org.springframework.boot
spring-boot-starter-thymeleaf
<!-- 阿里云OSS-->
com.aliyun.oss
aliyun-sdk-oss
2.4.0
commons-fileupload
commons-fileupload
1.3.1
org.springframework.boot
spring-boot-configuration-processor
true
二 配置阿里云 OSS 存储相关属性
我在项目中使用的通过常量类来配置,不过你也可以使用 .properties 配置文件来配置,然后@ConfigurationProperties注解注入到类中。
2.1 通过常量类配置(本项目使用的方式)
AliyunOSSConfigConstant.java
/**
*@Auther: SnailClimb
*@Date: 2018/12/4 15:09
*@Description: 阿里云OSS存储的相关常量配置.我这里通过常量类来配置的,当然你也可以通过.properties 配置文件来配置,
* 然后利用 SpringBoot 的@ConfigurationProperties注解来注入
*/
publicclassAliyunOSSConfigConstant{
//私有构造方法 禁止该类初始化
privateAliyunOSSConfigConstant(){
}
//仓库名称
publicstaticfinalString BUCKE_NAME ="my-blog-to-use";
//地域节点
publicstaticfinalString END_POINT ="oss-cn-beijing.aliyuncs.com";
//AccessKey ID
publicstaticfinalString AccessKey_ID ="你的AccessKeyID";
//Access Key Secret
publicstaticfinalString AccessKey_Secret ="你的AccessKeySecret";
//仓库中的某个文件夹
publicstaticfinalString FILE_HOST ="test";
}
到阿里云 OSS 控制台:https://oss.console.aliyun.com/overview 获取上述相关信息:
获取 BUCKE_NAME 和 END_POINT:
获取BUCKE_NAME和END_POINT
获取 AccessKey ID 和 Access Key Secret 第一步:
获取AccessKey ID和Access Key Secret第一步
获取AccessKey ID和Access Key Secret第二步:
获取AccessKey ID和Access Key Secret第二步
2.2 通过.properties 配置
#OSS配置
aliyun.oss.bucketname=my-blog-to-use
aliyun.oss.endpoint=oss-cn-beijing.aliyuncs.com
#阿里云主账号AccessKey拥有所有API的访问权限,风险很高。建议创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
aliyun.oss.keyid=你的AccessKeyID
aliyun.oss.keysecret=你的AccessKeySecret
aliyun.oss.filehost=test
然后新建一个类将属性注入:
@Component
@PropertySource(value ="classpath:application-oss.properties")
@ConfigurationProperties(prefix ="aliyun.oss")
/**
* 阿里云oss的配置类
*/
publicclassAliyunOSSConfig{
privateString bucketname;
privateString endpoint;
privateString keyid;
privateString keysecret;
privateString filehost;
...
此处省略getter、setter以及 toString方法
}
三 工具类相关方法编写
该工具类主要提供了三个方法:上传文件upLoad(File file)、通过文件名下载文件downloadFile(String objectName, String localFileName)、列出某个文件夹下的所有文件listFile( )。笔主比较懒,代码可能还比较简陋,各位可以懂懂自己的脑子,参考阿里云官方提供的相关文档来根据自己的需求来优化。Java API文档地址如下:
https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
/**
*@Author: SnailClimb
*@Date: 2018/12/1 16:56
*@Description: 阿里云OSS服务相关工具类.
* Java API文档地址:https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
*/
@Component
publicclassAliyunOSSUtil{
privatestaticfinalorg.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);
privatestaticString FILE_URL;
privatestaticString bucketName = AliyunOSSConfigConstant.BUCKE_NAME;
privatestaticString endpoint = AliyunOSSConfigConstant.END_POINT;
privatestaticString accessKeyId = AliyunOSSConfigConstant.AccessKey_ID;
privatestaticString accessKeySecret = AliyunOSSConfigConstant.AccessKey_Secret;
privatestaticString fileHost = AliyunOSSConfigConstant.FILE_HOST;
/**
* 上传文件。
*
*@paramfile 需要上传的文件路径
*@return如果上传的文件是图片的话,会返回图片的"URL",如果非图片的话会返回"非图片,不可预览。文件路径为:+文件路径"
*/
publicstaticStringupLoad(File file){
// 默认值为:true
booleanisImage =true;
// 判断所要上传的图片是否是图片,图片可以预览,其他文件不提供通过URL预览
try{
Image image = ImageIO.read(file);
isImage = image ==null?false:true;
}catch(IOException e) {
e.printStackTrace();
}
logger.info("------OSS文件上传开始--------"+ file.getName());
SimpleDateFormat format =newSimpleDateFormat("yyyy-MM-dd");
String dateStr = format.format(newDate());
// 判断文件
if(file ==null) {
returnnull;
}
// 创建OSSClient实例。
OSSClient ossClient =newOSSClient(endpoint, accessKeyId, accessKeySecret);
try{
// 判断容器是否存在,不存在就创建
if(!ossClient.doesBucketExist(bucketName)) {
ossClient.createBucket(bucketName);
CreateBucketRequest createBucketRequest =newCreateBucketRequest(bucketName);
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
ossClient.createBucket(createBucketRequest);
}
// 设置文件路径和名称
String fileUrl = fileHost +"/"+ (dateStr +"/"+ UUID.randomUUID().toString().replace("-","") +"-"+ file.getName());
if(isImage) {//如果是图片,则图片的URL为:....
FILE_URL ="https://"+ bucketName +"."+ endpoint +"/"+ fileUrl;
}else{
FILE_URL ="非图片,不可预览。文件路径为:"+ fileUrl;
}
// 上传文件
PutObjectResult result = ossClient.putObject(newPutObjectRequest(bucketName, fileUrl, file));
// 设置权限(公开读)
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
if(result !=null) {
logger.info("------OSS文件上传成功------"+ fileUrl);
}
}catch(OSSException oe) {
logger.error(oe.getMessage());
}catch(ClientException ce) {
logger.error(ce.getErrorMessage());
}finally{
if(ossClient !=null) {
ossClient.shutdown();
}
}
returnFILE_URL;
}
/**
* 通过文件名下载文件
*
*@paramobjectName 要下载的文件名
*@paramlocalFileName 本地要创建的文件名
*/
publicstaticvoiddownloadFile(String objectName, String localFileName){
// 创建OSSClient实例。
OSSClient ossClient =newOSSClient(endpoint, accessKeyId, accessKeySecret);
// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
ossClient.getObject(newGetObjectRequest(bucketName, objectName),newFile(localFileName));
// 关闭OSSClient。
ossClient.shutdown();
}
/**
* 列举 test 文件下所有的文件
*/
publicstaticvoidlistFile(){
// 创建OSSClient实例。
OSSClient ossClient =newOSSClient(endpoint, accessKeyId, accessKeySecret);
// 构造ListObjectsRequest请求。
ListObjectsRequest listObjectsRequest =newListObjectsRequest(bucketName);
// 设置prefix参数来获取fun目录下的所有文件。
listObjectsRequest.setPrefix("test/");
// 列出文件。
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
// 遍历所有文件。
System.out.println("Objects:");
for(OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
System.out.println(objectSummary.getKey());
}
// 遍历所有commonPrefix。
System.out.println("CommonPrefixes:");
for(String commonPrefix : listing.getCommonPrefixes()) {
System.out.println(commonPrefix);
}
// 关闭OSSClient。
ossClient.shutdown();
}
}
四 Controller 层编写相关测试方法
上传文件upLoad(File file)、通过文件名下载文件downloadFile(String objectName, String localFileName)、列出某个文件夹下的所有文件listFile( )这三个方法都在下面有对应的简单测试。另外,还有一个方法uploadPicture(@RequestParam("file") MultipartFile file, Model model)对应于我们等下要实现的图床功能,该方法从前端接受到图片之后上传到阿里云OSS存储空间并返回上传成功的图片 URL 地址给前端。
注意将下面的相关路径改成自己的,不然会报错!!!
/**
*@Author: SnailClimb
*@Date: 2018/12/2 16:56
*@Description: 阿里云OSS服务Controller
*/
@Controller
@RequestMapping("/oss")
publicclassAliyunOSSController{
privatefinalorg.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
privateAliyunOSSUtil aliyunOSSUtil;
/**
* 测试上传文件到阿里云OSS存储
*
*@return
*/
@RequestMapping("/testUpload")
@ResponseBody
publicStringtestUpload(){
File file =newFile("E:/Picture/test.jpg");
AliyunOSSUtil aliyunOSSUtil =newAliyunOSSUtil();
String url = aliyunOSSUtil.upLoad(file);
System.out.println(url);
return"success";
}
/**
* 通过文件名下载文件
*/
@RequestMapping("/testDownload")
@ResponseBody
publicStringtestDownload(){
AliyunOSSUtil aliyunOSSUtil =newAliyunOSSUtil();
aliyunOSSUtil.downloadFile(
"test/2018-12-04/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg","E:/Picture/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg");
return"success";
}
/**
* 列出某个文件夹下的所有文件
*/
@RequestMapping("/testListFile")
@ResponseBody
publicStringtestListFile(){
AliyunOSSUtil aliyunOSSUtil =newAliyunOSSUtil();
aliyunOSSUtil.listFile();
return"success";
}
/**
* 文件上传(供前端调用)
*/
@RequestMapping(value ="/uploadFile")
publicStringuploadPicture(@RequestParam("file")MultipartFile file, Model model){
logger.info("文件上传");
String filename = file.getOriginalFilename();
System.out.println(filename);
try{
if(file !=null) {
if(!"".equals(filename.trim())) {
File newFile =newFile(filename);
FileOutputStream os =newFileOutputStream(newFile);
os.write(file.getBytes());
os.close();
file.transferTo(newFile);
// 上传到OSS
String uploadUrl = aliyunOSSUtil.upLoad(newFile);
model.addAttribute("url",uploadUrl);
}
}
}catch(Exception ex) {
ex.printStackTrace();
}
return"success";
}
}
五 启动类
@SpringBootApplication
publicclassSpringbootOssApplication{
publicstaticvoidmain(String[] args){
SpringApplication.run(SpringbootOssApplication.class, args);
}
}
六 上传图片相关前端页面
注意引入jquery ,避免前端出错。
index.html
JS 的内容主要是让我们上传的图片可以预览,就像我们在网站更换头像的时候一样。
基于阿里云OSS存储的图床
* {
margin:0;
padding:0;
}
#submit {
margin-left:15px;
}
.preview_box img {
width:200px;
}
上传
$("#img_input").on("change", function (e) {
var file = e.target.files[0];//获取图片资源
// 只选择图片文件
if(!file.type.match('image.*')) {
returnfalse;
}
var reader =newFileReader();
reader.readAsDataURL(file);// 读取文件
// 渲染文件
reader.onload = function (arg) {
var img ='<img class="preview" src="'+ arg.target.result +'" alt="preview"/>';
$(".preview_box").empty().append(img);
}
});
success.html
通过<span th:text="${url}"></span>引用后端传过来的值。
<!DOCTYPE html>
上传结果
上传成功!
图片地址为:
七 测试我们的图床
访问 :http://localhost:8080/
① 上传图片
② 图片上传成功返回图片地址
③ 通过图片 URL 访问图片
通过图片 URL 访问图片
我们终于能够独立利用阿里云 OSS 完成一个自己的图床服务,但是其实如果你想用阿里云OSS当做图床可以直接使用极简图床:http://jiantuku.com上传图片,比较方便!大家可能心里在想那你特么让我实现个图床干嘛?我觉得通过学习,大家以后可以做很多事情,比如 利用阿里云OSS 存储服务存放自己网站的相关图片。