springBoot集成华为云obs对象存储
springBoot集成华为云obs对象存储
一、准备工作:华为云平台注册账号
二、springBoot项目集成obs服务器
- spring-boot的pom.xml中添加组件【这里使用的是v=3.21.8】
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
<version>3.21.8</version>
</dependency>
<!--
必须制定okhttp3的最新版本号,
否则会出现java.lang.NoSuchMethodError: okhttp3.RequestBody.create
-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<!--
必须指定与okhttp相匹配的okio的版本,否则会出现okio和okhttp的包冲突问题
java.lang.NoSuchMethodError: kotlin
-->
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>2.8.0</version>
</dependency>
- spring-boot的application.properties文件中配置
#华为云obs配置
hwyun.obs.accessKey=****
hwyun.obs.securityKey=***
hwyun.obs.endPoint=***
hwyun.obs.bucketName=***
- 创建对应的HweiOBSConfig参数配置类
package com.elink;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import lombok.Data;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@Configuration
public class HweiOBSConfig {
private static final Logger log = Logger.getLogger(HweiOBSConfig.class);
/**
* 访问密钥AK
*/
@Value("${hwyun.obs.accessKey}")
private String accessKey;
/**
* 访问密钥SK
*/
@Value("${hwyun.obs.securityKey}")
private String securityKey;
/**
* 终端节点
*/
@Value("${hwyun.obs.endPoint}")
private String endPoint;
/**
* 桶
*/
@Value("${hwyun.obs.bucketName}")
private String bucketName;
/**
* @Description 获取OBS客户端实例
* @return: com.obs.services.ObsClient
*/
public ObsClient getInstance() {
return new ObsClient(accessKey, securityKey, endPoint);
}
/**
* @Description 销毁OBS客户端实例
* @param: obsClient
*/
public void destroy(ObsClient obsClient){
try {
obsClient.close();
} catch (ObsException e) {
log.error("obs执行失败", e);
} catch (Exception e) {
log.error("执行失败", e);
}
}
/**
* @Description 微服务文件存放路径
* @return: java.lang.String
*/
public static String getObjectKey() {
// 项目或者服务名称 日期存储方式
return "Hwei" "/" new SimpleDateFormat("yyyy-MM-dd").format(new Date() ) "/";
}
}
- 创建业务层接口
package com.elink.license.service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
* 华为云OBS服务接口
*/
public interface IHweiYunOBSService {
/**
* @Description 删除文件
* @param: objectKey 文件名
* @return: boolean 执行结果
*/
boolean delete(String objectKey);
boolean deleteFileByPath(String objectKey);
/**
* @Description 批量删除文件
* @param: objectKeys 文件名集合
* @return: boolean 执行结果
*/
boolean delete(List<String> objectKeys);
/**
* @Description 上传文件
* @param: uploadFile 上传文件
* @param: objectKey 文件名称
* @return: java.lang.String url访问路径
*/
String fileUpload(MultipartFile uploadFile, String objectKey);
String uploadFileByte(byte data[], String objectKey);
String uploadFile(File file);
/**
* @Description 文件下载
* @param: objectKey
* @return: java.io.InputStream
*/
InputStream fileDownload(String objectKey);
}
package com.elink.license.service.impl;
import com.elink.HweiOBSConfig;
import com.elink.base.util.PropertiesUtil;
import com.elink.license.service.IHweiYunOBSService;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
/**
* 华为云OBS服务业务层
*/
@Service
public class HweiYunOBSServiceImpl implements IHweiYunOBSService {
private static final Logger log = Logger.getLogger(HweiYunOBSServiceImpl.class);
@Autowired
private HweiOBSConfig hweiOBSConfig;
@Override
public boolean delete(String objectKey) {
ObsClient obsClient = null;
try {
// 创建ObsClient实例
obsClient = hweiOBSConfig.getInstance();
// obs删除
obsClient.deleteObject(hweiOBSConfig.getBucketName(), objectKey);
} catch (ObsException e) {
log.error("obs[delete]删除保存失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return true;
}
@Override
public boolean deleteFileByPath(String path) {
//path:https://wwwbak.obs.ap-southeast-1.myhuaweicloud.com/uploadFiles/xiehui/yongjiu/fujian/wode.jpg
ObsClient obsClient = null;
try {
// 创建ObsClient实例
obsClient = hweiOBSConfig.getInstance();
String file_http_url = PropertiesUtil.readValue("file_http_url");
File file = new File(path);
String key = file.getName();//wode.jpg
//realPath : uploadFiles/xiehui/yongjiu/fujian
String realPath = path.replace(file_http_url, "");
realPath = realPath.substring(0, realPath.lastIndexOf('/'));
// obs删除
obsClient.deleteObject(hweiOBSConfig.getBucketName(), realPath "/" key);
} catch (ObsException e) {
log.error("obs[deleteFileByPath]删除保存失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return false;
}
@Override
public boolean delete(List<String> objectKeys) {
ObsClient obsClient = null;
try {
obsClient = hweiOBSConfig.getInstance();
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(hweiOBSConfig.getBucketName());
objectKeys.forEach(x -> deleteObjectsRequest.addKeyAndVersion(x));
// 批量删除请求
obsClient.deleteObjects(deleteObjectsRequest);
return true;
} catch (ObsException e) {
log.error("obs[delete]删除保存失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return false;
}
@Override
public String fileUpload(MultipartFile uploadFile, String objectKey) {
ObsClient obsClient = null;
try {
String bucketName = hweiOBSConfig.getBucketName();
obsClient = hweiOBSConfig.getInstance();
// 判断桶是否存在
boolean exists = obsClient.headBucket(bucketName);
if (!exists) {
// 若不存在,则创建桶
HeaderResponse response = obsClient.createBucket(bucketName);
log.info("创建桶成功" response.getRequestId());
}
InputStream inputStream = uploadFile.getInputStream();
long available = inputStream.available();
PutObjectRequest request = new PutObjectRequest(bucketName, objectKey, inputStream);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(available);
request.setMetadata(objectMetadata);
// 设置对象访问权限为公共读
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
PutObjectResult result = obsClient.putObject(request);
// 读取该已上传对象的URL
log.info("已上传对象的URL" result.getObjectUrl());
return result.getObjectUrl();
} catch (ObsException e) {
log.error("obs[fileUpload]上传失败", e);
} catch (IOException e) {
log.error("[fileUpload]上传失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return null;
}
@Override
public String uploadFileByte(byte[] data, String fileName) {
try {
ObsClient obsClient = null;
String bucketName = hweiOBSConfig.getBucketName();
obsClient = hweiOBSConfig.getInstance();
// 判断桶是否存在
boolean exists = obsClient.headBucket(bucketName);
if (!exists) {
// 若不存在,则创建桶
HeaderResponse response = obsClient.createBucket(bucketName);
log.info("创建桶成功" response.getRequestId());
}
String file_http_url = PropertiesUtil.readValue("file_http_url");
//转为File
InputStream inputStream = new ByteArrayInputStream(data);
String prefix = fileName.substring(fileName.lastIndexOf(".") 1);//后缀
String uuid = UUID.randomUUID().toString().replace("-", "");//customer_YYYYMMDDHHMM
fileName = uuid "." prefix; //文件全路径
obsClient.putObject(bucketName, fileName.substring(0, fileName.lastIndexOf("/")) "/" fileName, inputStream);
return file_http_url fileName;
} catch (ObsException e) {
log.error("obs[uploadFileByte]上传失败", e);
}
return null;
}
@Override
public String uploadFile(File file) {
ObsClient obsClient = null;
try {
String bucketName = hweiOBSConfig.getBucketName();
obsClient = hweiOBSConfig.getInstance();
// 判断桶是否存在
boolean exists = obsClient.headBucket(bucketName);
if (!exists) {
// 若不存在,则创建桶
HeaderResponse response = obsClient.createBucket(bucketName);
log.info("创建桶成功" response.getRequestId());
}
String file_http_url = PropertiesUtil.readValue("file_http_url");
//转为File
String filename = file.getName();
String prefix = filename.substring(filename.lastIndexOf(".") 1);//后缀
String uuid = UUID.randomUUID().toString().replace("-", "");//customer_YYYYMMDDHHMM
String fileName = uuid "." prefix; //文件全路径
obsClient.putObject(bucketName, fileName.substring(0, fileName.lastIndexOf("/")) "/" fileName, file);
return file_http_url fileName;
} catch (Exception e) {
log.error("obs[uploadFile]上传失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return null;
}
@Override
public InputStream fileDownload(String objectKey) {
ObsClient obsClient = null;
try {
String bucketName = hweiOBSConfig.getBucketName();
obsClient = hweiOBSConfig.getInstance();
ObsObject obsObject = obsClient.getObject(bucketName, objectKey);
return obsObject.getObjectContent();
} catch (ObsException e) {
log.error("obs[fileDownload]文件下载失败", e);
} finally {
hweiOBSConfig.destroy(obsClient);
}
return null;
}
}
- 添加Controller层
package com.elink.license.controller;
import com.elink.license.service.IHweiYunOBSService;
import com.elink.license.util.StringUtils;
import com.elink.share.result.Result;
import com.elink.share.result.ResultCodeWraper;
import com.obs.services.exception.ObsException;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* OBS服务器Controller
*/
@RestController
@RequestMapping({"file"})
public class HweiYunOBSController {
@Resource
private IHweiYunOBSService hweiYunOBSService;
/**
* upload
* 上传 file类型文件
* @param file
* @return
*/
@RequestMapping(value = "upload", method = RequestMethod.POST)
public Map save(@RequestParam(value = "file", required = false) MultipartFile file) {
if (StringUtils.isEmpty(file)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "文件为空");
}
final String test = hweiYunOBSService.fileUpload(file, file.getOriginalFilename());
return new Result<>(ResultCodeWraper.SUCCESS, test);
}
/**
* 下载文件
* /download/123.jpg
* 注意:此处未将文件名写在路径最后,是因为使用rest方法去下载文件的话,这个方法是会自动截取文件名的后缀,传入的参数将是123,下载后的文件也将丢失后缀
* {fileName}/download
*
* @param request
* @param response
* @param fileName
* @return
*/
@RequestMapping(value = "{fileName}/download", method = RequestMethod.POST)
public Map download(HttpServletRequest request, HttpServletResponse response, @PathVariable String fileName) {
if (StringUtils.isEmpty(fileName)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "下载文件为空");
}
try (
InputStream inputStream = hweiYunOBSService.fileDownload(fileName);
BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
if (inputStream == null) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "内部错误");
}
// 为防止 文件名出现乱码
final String userAgent = request.getHeader("USER-AGENT");
// IE浏览器
if (userAgent.indexOf("MSIE") > -1) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
// 谷歌,火狐浏览器
if (userAgent.indexOf("Mozilla") > -1) {
fileName = new String(fileName.getBytes(), "ISO8859-1");
} else {
// 其他浏览器
fileName = URLEncoder.encode(fileName, "UTF-8");
}
}
response.setContentType("application/x-download");
// 设置让浏览器弹出下载提示框,而不是直接在浏览器中打开
response.addHeader("Content-Disposition", "attachment;filename=" fileName);
IOUtils.copy(inputStream, outputStream);
return null;
} catch (IOException | ObsException e) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "内部错误");
}
}
/**
* 上传文件---直接传file
*
* @return
*/
public Map uploadFile(File file) {
if (StringUtils.isEmpty(file)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "文件为空");
}
final String test = hweiYunOBSService.uploadFile(file);
return new Result<>(ResultCodeWraper.SUCCESS, test);
}
/**
* 上传文件---byte类型
*
* @return
*/
public Map uploadFileByte(byte data[], String fileName) {
if (StringUtils.isEmpty(fileName)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "文件为空");
}
final String test = hweiYunOBSService.uploadFileByte(data, fileName);
return new Result<>(ResultCodeWraper.SUCCESS, test);
}
/**
* 下载ObsObject
* @param filePath 需要下载的文件路径。 例:"site/a.txt"
* @return 下载文件的字节数组
* @throws IOException
*/
public byte[] getFileByteArray(String filePath) throws IOException {
//filePath : uploadFiles/xiehui/yongjiu/fujian/wode.jpg
InputStream input = hweiYunOBSService.fileDownload(filePath.substring(0,filePath.lastIndexOf("/")) "/" filePath);
byte[] b = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len;
while ((len = input.read(b)) != -1){
bos.write(b, 0, len);
}
bos.close();
input.close();
return bos.toByteArray();
}
/**
* 删除文件
* 根据文件名称删除
* @param fileName
* @return
*/
@RequestMapping(value = "{fileName}/delete", method = RequestMethod.POST)
public Map delete(@PathVariable String fileName) {
if (StringUtils.isEmpty(fileName)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "删除文件为空");
}
final boolean delete = hweiYunOBSService.delete(fileName);
return new Result<>(delete ? ResultCodeWraper.SUCCESS : ResultCodeWraper.REQUEST_ERROR, delete);
}
/**
* 删除文件
* 根据文件路径删除
* @param param
* 待测试 接口
* https://blog.csdn.net/qq_41992943/article/details/125643664
*/
@RequestMapping("/deleteFileByPath")
public Map deleteFileByPath(HttpServletRequest request, @RequestParam Map param) {
String path = StringUtils.getStringByObj(param.get("path"));
if (StringUtils.isEmpty(path)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "文件path为空");
}
final boolean delete = hweiYunOBSService.deleteFileByPath(path);
return new Result<>(delete ? ResultCodeWraper.SUCCESS : ResultCodeWraper.REQUEST_ERROR, delete);
}
/**
* delete
* 批量删除
*
* @param fileNames
* @return
*/
@RequestMapping(value = "deletes", method = RequestMethod.POST)
public Map delete(@RequestParam("fileNames") List<String> fileNames) {
if (StringUtils.isEmpty(fileNames)) {
return new Result<>(ResultCodeWraper.REQUEST_ERROR, "删除文件为空");
}
final boolean delete = hweiYunOBSService.delete(fileNames);
return new Result<>(delete ? ResultCodeWraper.SUCCESS : ResultCodeWraper.REQUEST_ERROR, delete);
}
/**
* 递归删除多层目录文件
* @param path
*/
public static void dfsdelete(String path) {
File file = new File(path);
if (file.isFile()) {//如果此file对象是文件的话,直接删除
file.delete();
return;
}
//当 file是文件夹的话,先得到文件夹下对应文件的string数组 ,递归调用本身,实现深度优先删除
String[] list = file.list();
for (int i = 0; i < list.length; i ) {
dfsdelete(path File.separator list[i]);
}//当把文件夹内所有文件删完后,此文件夹已然是一个空文件夹,可以使用delete()直接删除
file.delete();
return;
}
/**
* 得到文件流
*
* @param url 网络图片URL地址
* @return
*/
public static byte[] getFileStream(String url) {
try {
URL httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();//通过输入流获取图片数据
byte[] btImg = readInputStream(inStream);//得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从输入流中获取数据
*
* @param inStream 输入流
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
/**
* file转byte
*/
public static byte[] file2byte(File file) {
byte[] buffer = null;
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
/**
* byte 转file
*/
public static File byte2File(byte[] buf, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {
dir.mkdirs();
}
file = new File(filePath File.separator fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(buf);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
/**
* multipartFile转File
**/
public static File multipartFile2File(MultipartFile multipartFile) {
File file = null;
if (multipartFile != null) {
try {
file = File.createTempFile("tmp", null);
multipartFile.transferTo(file);
System.gc();
file.deleteOnExit();
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
}
三、测试接口
- 上传
- 下载
- 删除
注意:上面使用的springBoot版本是1.5.4,使用上述pom依赖没有问题,如果springBoot的版本是2.1.5,则依赖引入如下
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
<version>3.21.8</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>2.8.0</version>
</dependency>
<!--
特别需要引入以下配置,否则会抛出异常
java.lang.NoSuchMethodError: kotlin.collections.ArraysKt.copyInto([B[BIII)
-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.3.50</version>
</dependency>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfhcakj
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24