基于华为云obs的springMVC文件上传下载,简单demo
使用华为云的obs作为文件服务
使用springdata jpa框架操作数据库
创建springboot项目,添加华为云obs的SDK的maven依赖
<!-- 开启spring配置类 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- 华为云obs的SDK --><dependency><groupId>com.huaweicloud</groupId><artifactId>esdk-obs-java</artifactId><version>[3.19.7,)</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
版本号[3.19.7,)没有问题,表示自动选择最高版本,最低使用3.19.7版本
自定义配置类,并读取配置
# 华为云 obs地址
obs.endPoint=华为云的obs的endpoint地址
obs.ak=华为云账号的ak
obs.sk=华为云账号的sk
obs.bucket=华为云的obs创建的桶名称,建议在华为云obs控制台创建,也可以使用SDK创建
在pom的依赖中配置开启spring的配置类,创建配置类ObsConfigProperties
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data // lombok注解
@Component // 将此类加载到spring容器中
@ConfigurationProperties(prefix = "obs") // 与配置文件中obs的前缀对应
public class ObsConfigProperties {private String endPoint;private String ak;private String sk;private String bucket;
}
在后面的代码中就可以使用
@Autowired
private static ObsConfigProperties properties;
加载配置信息,也可以使用的@Value("${obs.endPoint}") 方式加载配置
编写文件上传下载的工具类
import com.obs.services.ObsClient;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;/*** 以uuid作为存放在华为云的文件名**/
@Component
public class ObsUtils {private static ObsConfigProperties properties;private static ObsClient obsClient;/*** 通过输入流的方式上传文件* @param url 上传到OBS桶中的路径* @param inputStream* @return*/public static String uploadFile(String url, InputStream inputStream) {PutObjectResult putObjectResult = obsClient.putObject(properties.getBucket(), url, inputStream);int statusCode = putObjectResult.getStatusCode();if (statusCode != 200) {throw new RuntimeException("文件上传异常,http响应码为" + statusCode);}return url;}/*** 根据文件的路径获取文件的输入流** @param url* @return* @throws IOException*/public static InputStream downFile(String url) throws IOException {ObsObject obsObject = obsClient.getObject(properties.getBucket(), url);Long contentLength = obsObject.getMetadata().getContentLength();return obsObject.getObjectContent();}@PostConstructpublic void init() {obsClient = new ObsClient(properties.getAk(), properties.getSk(), properties.getEndPoint());}@Autowiredpublic void setProperties(ObsConfigProperties obsConfigProperties) {properties = obsConfigProperties;}}
注意:
1.工具类一般为静态方法,属于class的,而spring容器是基于对象的,
如果直接写成
@Autowired
private static ObsConfigProperties properties;
static的class字段无法被注入进来
需要使用set方法注入,@Component不能丢
2. 静态字段obsClient的初始化,也需要通过spring在创建对象时完成
@PostConstruct表示spring创建对象前执行的方法
对应数据库的实体类
由于上传文件时会有不同文件相同文件名的情况,上传至obs前需对文件名重命名,这里使用uuid作为文件名,将文件信息放在数据库实体类中,下载时替换文件名
import javax.persistence.*;
import java.io.InputStream;
import java.util.Date;/*** 文件交互时的基本类型**/
@Entity
@Table(name = "t_file", indexes = @Index(name = "file_url_index", columnList = "url", unique = true))
public class ObsBeanDTO {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;/*** 用户上传时的文件名*/private String name;/*** 文件类型,根据文件名获取*/private String type;/*** 上传后obs的位置,包含上传后的文件名*/// @Column(name = "url", unique = true)private String url;/*** 华为云obs桶名*/private String bucket;/*** 华为云obs桶名*/@Temporal(TemporalType.TIMESTAMP)private Date dateTime;/*** 文件的输入流*/@Transientprivate InputStream inputStream;@Overridepublic String toString() {return "ObsBeanDTO{" +"id=" + id +", name='" + name + '\'' +", type='" + type + '\'' +", url='" + url + '\'' +", bucket='" + bucket + '\'' +", dateTime=" + dateTime +'}';}public InputStream getInputStream() {return inputStream;}public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getBucket() {return bucket;}public void setBucket(String bucket) {this.bucket = bucket;}public Date getDateTime() {return dateTime;}public void setDateTime(Date dateTime) {this.dateTime = dateTime;}
}
jpa实体类中常见注解说明:https://www.cnblogs.com/jpfss/p/10895336.html
controller层
import com.xq.obs.domain.ObsBeanDTO;
import com.xq.obs.domain.ObsUploadDTO;
import com.xq.service.FileService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;import static org.slf4j.LoggerFactory.getLogger;@Controller
public class FileController {private static final Logger logger = getLogger(FileController.class);@AutowiredFileService fileService;@PostMapping("/file")@ResponseBodypublic ObsBeanDTO uploadFile(@RequestParam("file") MultipartFile file) throws IOException {logger.info("upload file,file name -> {}, file.getSize -> {}", file.getOriginalFilename(), file.getSize());ObsUploadDTO obsUploadDTO = new ObsUploadDTO();obsUploadDTO.setName(file.getOriginalFilename());obsUploadDTO.setInputStream(file.getInputStream());ObsBeanDTO obsBeanDTO = fileService.uploadFile(obsUploadDTO);// 清理流,并将实体类的流设为空InputStream inputStream = obsBeanDTO.getInputStream();inputStream.close();obsBeanDTO.setInputStream(null);logger.info("uploadFile is success, obsBeanDTO -> {}", obsBeanDTO);return obsBeanDTO;}@GetMapping("/file")public void downFile(String url, HttpServletResponse response) throws IOException {ObsBeanDTO obsBeanDTO = fileService.downFile(url);InputStream inputStream = obsBeanDTO.getInputStream();byte[] b = new byte[1024];response.setHeader("content-type", "application/octet-stream");response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=" + obsBeanDTO.getName());ServletOutputStream outputStream = response.getOutputStream();int len;while ((len=inputStream.read(b)) != -1){outputStream.write(b, 0, len);outputStream.flush();}inputStream.close();obsBeanDTO.setInputStream(null);logger.info("downFile success, obsBeanDTO -> {}", obsBeanDTO);}
}
注意:文件下载时response.setHeader应在流的操作之前设置号,放在流之后,响应头信息会丢失
dao层接口
public interface FileRepository extends JpaRepository<ObsBeanDTO, Long> {public ObsBeanDTO findObsBeanDTOByUrl(String url);
}
service层
import com.xq.converter.ObsDTOConverter;
import com.xq.obs.ObsUtils;
import com.xq.obs.domain.ObsBeanDTO;
import com.xq.obs.domain.ObsUploadDTO;
import com.xq.repository.FileRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.io.InputStream;@Service
public class FileService {private static final Logger logger = LoggerFactory.getLogger(FileService.class);@Autowiredprivate ObsDTOConverter obsDTOConverter;@Autowiredprivate FileRepository fileRepository;public ObsBeanDTO uploadFile(ObsUploadDTO obsUploadDTO) {// 1、创建对应的数据库实体类ObsBeanDTO obsBeanDTO = obsDTOConverter.convertObsBean(obsUploadDTO);// 2、上传至华为云obsObsUtils.uploadFile(obsBeanDTO.getUrl(), obsBeanDTO.getInputStream());logger.info("obsBeanDTO -> {}", obsBeanDTO);// 3、保存进数据库ObsBeanDTO save = fileRepository.save(obsBeanDTO);return save;}public ObsBeanDTO downFile(String url) throws IOException {// 1、数据库查询对应的实体类ObsBeanDTO obsBeanDTO = fileRepository.findObsBeanDTOByUrl(url);// 2、从华为云获取文件流InputStream inputStream = ObsUtils.downFile(url);// 3、封装bean,并返回obsBeanDTO.setInputStream(inputStream);return obsBeanDTO;}
}
其中:ObsDTOConverter为类之间转换器,demo里比较简单,完全可以不用,代码如下:
import com.xq.obs.ObsConfigProperties;
import com.xq.obs.domain.ObsBeanDTO;
import com.xq.obs.domain.ObsUploadDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.Date;
import java.util.UUID;@Service
public class ObsDTOConverter {@Autowiredprivate ObsConfigProperties properties;public ObsBeanDTO convertObsBean(ObsUploadDTO obsUploadDTO) {ObsBeanDTO bean = new ObsBeanDTO();bean.setName(obsUploadDTO.getName());bean.setInputStream(obsUploadDTO.getInputStream());bean.setType(makeType(obsUploadDTO.getName()));bean.setUrl(createPath(bean.getType()));bean.setBucket(properties.getBucket());bean.setDateTime(new Date());return bean;}private String createPath(String type) {if (type.isEmpty()) {return "file/" + UUID.randomUUID();}return "file/" + UUID.randomUUID() + "." + type;}private String makeType(String fileName) {// 不能等于0,.txt不是正常的window文件格式int indexOf = fileName.lastIndexOf('.');if (indexOf > 0) {return fileName.substring(indexOf + 1).toLowerCase();}return "";}
}
使用的实体类,下载时需要封装的实体类,demo较简单可以去掉,在实际场景需要的字段可能较多,建议封装一下
public class ObsUploadDTO {private String name;private InputStream inputStream;public String getName() {return name;}public void setName(String name) {this.name = name;}public InputStream getInputStream() {return inputStream;}public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;}
}
github仓库地址:https://github.com/xiongqiang521/jpa-file.git
基于华为云obs的springMVC文件上传下载,简单demo相关推荐
- SpringMVC——文件上传下载,异步请求和SSM整合
一,SpringMVC文件上传下载 1.1 同步 1.1.1 文件上传 第一步:定义上传表单 <form action="${pageContext.request.contextPa ...
- SpringMVC文件上传下载和拦截器
一.文件上传:文件上传是项目开发中最常用的功能.为了能上传文件,必须将表单的method设置为post,将enctype设置为multipart/form-data.只有在这种情况下,浏览器才会把用户 ...
- 轻轻松松实现本地和云主机之间的文件上传下载
云主机开通后在进行应用部署时面临的第一个问题是如何将应用软件安装包.应用数据上传至云主机. 利用几个很简单的工具就可以将本地文件上传至云主机. 先说Windows云主机. Windows远程桌面支持远 ...
- SpringBoot(SpringMVC)文件上传下载
话说,springboot不是一个全新的框架,它只是将其它框架整合在一起,提供一个"开箱即用"的环境.此文,利用的正是SpringMVC的功能. 创建springboot项目:ht ...
- springmvc文件上传下载
在web开发中一般会有文件上传的操作 一般JavaWeb开发中文件上传使用的 Apache组织的Commons FileUpload组件 SpringMVC中使用 MultipartFile file ...
- 基于华为云obs实现文件上传下载(技术栈mysql+springboot+Maven+jsp+java)的技术分享
基于华为云obs实现文件上传下载(技术栈mysql+springboot+jsp+java)的技术分享 obs实现文件上传下载 前言 一.OBS是什么? 二.使用步骤 1.1 前期准备 2 工具的内容 ...
- 华为云OBS文件上传下载工具类
Java-华为云OBS文件上传下载工具类 文章目录 Java-华为云OBS文件上传下载工具类 1.华为云obs文件上传下载 2.文件流转MultipartFile 3.File转换为Multipart ...
- java实现excel文件上传_java相关:SpringMVC下实现Excel文件上传下载
java相关:SpringMVC下实现Excel文件上传下载 发布于 2020-6-21| 复制链接 摘记: 在实际应用中,经常会遇到上传Excel或者下载Excel的情况,比如导入数据.下载统计数据 ...
- SpringMVC 文件上传及下载
文件下载 inline 访问资源时如果没有设置响应头Content-Disposition,浏览器默认按照inline进行处理 inline:能显示就显示,不能显示就下载 响应头 只需修改响应头Con ...
最新文章
- 逻辑模型设计步骤-确定数据分割策略
- Python 字符串大小写转换,值域范围
- MySQL复习资料——用于突击考试总结
- django为什么需要子进程,如何关闭子进程,linux状态
- 〖前端开发〗HTML/CSS基础知识学习笔记
- 工厂方法模式_1天1个设计模式——工厂方法模式
- sgu 106 The equation ★★(线性方程ax+by=c限制区间的解)
- PIR 宣布被营利性机构收购,.org 顶级域名注册费用或上涨
- 【Luogu】【关卡2-3】排序(2017年10月) 【AK】
- 11th Iran Nationwide Internet Contest 解题报告
- 公开下载 |《2021技术人的百宝黑皮书》来了!
- Vue实现简单的音乐播放器
- 数据库去重,group by、distinct、rowid的用法,oracle和mysql如何数据去重保留一条
- Element-ui组ICON图标
- mysql数据备份恢复
- APM飞控添加自定义参数
- Xcode7 网络请求报错:The resource could not be loaded because the App Transport Security policy requir
- 高效开发PHP的5款编辑器
- (Golang)外观模式 VS 工厂模式
- 最新sogou搜狗搜索 机智操作绕过反爬验证码!