Springboot整合OSS实现文件上传

阿里云对象存储服务(Object Storage Service,简称
OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。

OSS中的相关概念

  • Endpoint:访问域名,通过该域名可以访问OSS服务的API,进行文件上传、下载等操作。
  • Bucket:存储空间,是存储对象的容器,所有存储对象都必须隶属于某个存储空间。
  • Object:对象,对象是 OSS 存储数据的基本单元,也被称为 OSS 的文件。
  • AccessKey:访问密钥,指的是访问身份验证中用到的 AccessKeyId 和 AccessKeySecret。

1)创建Springboot项目,并在pom.xml中添加相关依赖

<!-- OSS SDK 相关依赖 -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.5.0</version>
		</dependency>

2)在application.yml中添加OSS相关配置

# OSS相关配置信息
aliyun:
  oss:
    endpoint: oss-cn-beijing.aliyuncs.com # oss对外服务的访问域名
    accessKeyId: test # 访问身份验证中用到用户标识
    accessKeySecret: test # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
    bucketName: probe-oss # oss的存储空间
    dir:
      prefix: mall/images/ # 上传文件夹路径前缀

3)创建OssConfig.java,用于配置OSS的连接客户端OSSClient

@Configuration
public class OssConfig {
    @Value("${aliyun.oss.endpoint}")
    private String ALIYUN_OSS_ENDPOINT;
    @Value("${aliyun.oss.accessKeyId}")
    private String ALIYUN_OSS_ACCESSKEYID;
    @Value("${aliyun.oss.accessKeySecret}")
    private String ALIYUN_OSS_ACCESSKEYSECRET;
    @Bean
    public OSSClient ossClient(){
        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
    }
}

4)添加图片上传状态的实体类和枚举类

FileStateEnum

public enum FileStateEnum {
    GET_FILE_FAIL(-1,"获取文件流失败"),GET_FILE_SUCCESS(1,"成功获取文件流ccc"),
    NULL_FILE(-1,"上传文件为空"),MAX_SIZE_FILE(-1,"上传图片大小不能超过10M"),
    UPLOAD_FILE_FAIL(-1,"上传文件失败"),UPLOAD_FILE_SUCCESS(1,"上传文件成功"),
    DELETE_FILE_FAIL(-1,"删除文件失败");

    private int state;
    private String stateInfo;

    FileStateEnum(int state, String stateInfo) {
        this.state = state;
        this.stateInfo = stateInfo;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getStateInfo() {
        return stateInfo;
    }

    public void setStateInfo(String stateInfo) {
        this.stateInfo = stateInfo;
    }
}

ImageHolder

@Data
public class ImageHolder {
    private FileStateEnum StateEnum;
    private String fileName;
    private MultipartFile multipartFile;
    private List<MultipartFile> list;

    //成功的构造器
    public ImageHolder(FileStateEnum stateEnum, MultipartFile multipartFile) {
        StateEnum = stateEnum;
        this.multipartFile = multipartFile;
    }
    public ImageHolder(FileStateEnum stateEnum, String fileName) {
        StateEnum = stateEnum;
        this.fileName = fileName;
    }

    //失败的构造器
    public ImageHolder(FileStateEnum stateEnum) {
        StateEnum = stateEnum;
    }
}

5)添加OSS业务接口OssService,到时候只需在Controller层获取表单传过来的MultipartFile,然后调用service接口的方法即可实现文件上传功能

/**
 * oss上传管理Service
 *
 */
public interface OssService {
    FileStateEnum addHeadImage(MultipartFile file);
}

6)添加OSS业务接口OssService的实现类OssServiceImpl

/**
 * oss上传管理Service实现类
 */
@Service
public class OssServiceImpl implements OssService {

    @Value("${aliyun.oss.bucketName}")
    private String ALIYUN_OSS_BUCKET_NAME;
    @Value("${aliyun.oss.endpoint}")
    private String ALIYUN_OSS_ENDPOINT;
    @Value("${aliyun.oss.dir.prefix}")
	private String ALIYUN_OSS_DIR_PREFIX;

    //图片URL过期时间为10年  3600l* 1000*24*365*10
    private final long EXPIRATION = 36001 * 1000 * 24 * 365 * 10;

    @Autowired
    private OSSClient ossClient;
    
    /**
     * 上传一张图片到阿里云OSS中
     * @param file 需要上传的图片输入流
     * @return
     */
    @Override
    @Transactional
    public FileStateEnum addHeadImage(MultipartFile file) {
        //上传图片到阿里云中并返回成功上传后的图片名
        ImageHolder holder = addHeadImageToOss(file,ALIYUN_OSS_DIR_PREFIX);
        if (holder.getStateEnum().getState()>0){
            //如果需要获取上传后图片的URL,则调用该方法即可
            //String imgUrl = getImageUrl(holder.getFileName(),ALIYUN_OSS_DIR_PREFIX);
            return FileStateEnum.UPLOAD_FILE_SUCCESS;
        }else {
            return FileStateEnum.UPLOAD_FILE_FAIL;
        }
    }

    
    /**
     * 获取成功上传后文件的url
     * @param fileName 文件名
     * @param dirPre 上传文件的所在路径
     * @return
     */
    private String getImageUrl(String fileName,String dirPre) {
        String imgUrl = "";
        if (!StringUtils.isEmpty(fileName)){
            String[] split = fileName.split("/");
            String key = dirPre + split[split.length-1];
            Date expiration =  new Date(System.currentTimeMillis() + EXPIRATION);
            //生成URL
            URL url = ossClient.generatePresignedUrl(ALIYUN_OSS_BUCKET_NAME,key,expiration);
            if (null != url){
                imgUrl = url.toString();
            }
        }
        return "".equals(imgUrl)?imgUrl:imgUrl.substring(0,imgUrl.indexOf("?"));
    }

    /**
     * 上传至OSS中并返回新生成的文件名
     * @param file 需要上传的文件图片
     * @return
     */
    private ImageHolder addHeadImageToOss(MultipartFile file,String filePath) {
        String fileName = null;
        InputStream instream = null;
        try {
            //根据原始文件名随机生成新的文件名
            fileName = getRandomName(file.getOriginalFilename());
            instream = file.getInputStream();
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            //上传文件
            PutObjectResult putResult = ossClient.putObject(ALIYUN_OSS_BUCKET_NAME, filePath + fileName, instream, objectMetadata);
        } catch (IOException e) {
            return new ImageHolder(FileStateEnum.UPLOAD_FILE_FAIL);
        } finally {
            try {
                if (null != instream){
                    instream.close();
                }
            }catch (IOException e){
                return new ImageHolder(FileStateEnum.UPLOAD_FILE_FAIL);
            }
        }
        return new ImageHolder(FileStateEnum.UPLOAD_FILE_SUCCESS,fileName);
    }

    /**
     * 随机生成文件名
     * @param originalFileName 原始的文件名
     * @return
     */
    private String getRandomName(String originalFileName) {
        //获取文件的后缀名
        String subString = originalFileName.substring(originalFileName.lastIndexOf("."))
                .toLowerCase();
        Random random = new Random();
        return random.nextInt(10000) + System.currentTimeMillis() + subString;
    }

    /**
     * 判断OSS服务文件上传时文件的类型contentType
     * @param fileNameExtension
     * @return
     */
    private String getContentType(String fileNameExtension){
        if (fileNameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (fileNameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (fileNameExtension.equalsIgnoreCase(".jpeg") ||
                fileNameExtension.equalsIgnoreCase(".jpg") ||
                fileNameExtension.equalsIgnoreCase(".png")) {
            return "image/jpeg";
        }
        if (fileNameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (fileNameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (fileNameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (fileNameExtension.equalsIgnoreCase(".pptx") ||
                fileNameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (fileNameExtension.equalsIgnoreCase(".docx") ||
                fileNameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (fileNameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }

}
  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot 是一种快速开发应用程序的框架,而OSS(Object Storage Service)是阿里云提供的对象存储服务。将它们结合起来,可以实现文件的上传、下载、查看等功能。 下面是实现上传、查看、下载的具体步骤: 1. 引入依赖 在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 2. 配置 OSS 客户端 在配置文件中添加 OSS 的配置: ```properties aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com aliyun.oss.accessKeyId=yourAccessKeyId aliyun.oss.accessKeySecret=yourAccessKeySecret aliyun.oss.bucketName=yourBucketName ``` 然后创建 OSS 客户端: ```java @Configuration public class OSSConfig { @Autowired private OSSProperties ossProperties; @Bean public OSS ossClient() { return new OSSClientBuilder().build(ossProperties.getEndpoint(), ossProperties.getAccessKeyId(), ossProperties.getAccessKeySecret()); } } ``` 3. 实现上传功能 在控制器中实现上传功能: ```java @RestController public class OSSController { @Autowired private OSS ossClient; @Autowired private OSSProperties ossProperties; @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file) throws IOException { // 上传文件到 OSS String filename = file.getOriginalFilename(); ossClient.putObject(ossProperties.getBucketName(), filename, file.getInputStream()); // 返回文件 URL return ossClient.generatePresignedUrl(ossProperties.getBucketName(), filename, new Date(System.currentTimeMillis() + 3600 * 1000)).toString(); } } ``` 4. 实现查看功能 在控制器中实现查看功能: ```java @RestController public class OSSController { @Autowired private OSS ossClient; @Autowired private OSSProperties ossProperties; @GetMapping("/view/{filename:.+}") public ResponseEntity<Resource> view(@PathVariable String filename) throws IOException { // 从 OSS 中获取文件流 OSSObject ossObject = ossClient.getObject(ossProperties.getBucketName(), filename); InputStream inputStream = ossObject.getObjectContent(); // 将文件流转换为 Resource 对象 ByteArrayResource resource = new ByteArrayResource(IOUtils.toByteArray(inputStream)); // 返回 Resource 对象 return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"") .contentLength(resource.contentLength()) .contentType(MediaType.parseMediaType("application/octet-stream")) .body(resource); } } ``` 5. 实现下载功能 在控制器中实现下载功能: ```java @RestController public class OSSController { @Autowired private OSS ossClient; @Autowired private OSSProperties ossProperties; @GetMapping("/download/{filename:.+}") public ResponseEntity<Resource> download(@PathVariable String filename) throws IOException { // 从 OSS 中获取文件流 OSSObject ossObject = ossClient.getObject(ossProperties.getBucketName(), filename); InputStream inputStream = ossObject.getObjectContent(); // 将文件流转换为 Resource 对象 ByteArrayResource resource = new ByteArrayResource(IOUtils.toByteArray(inputStream)); // 返回 Resource 对象 return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"") .contentLength(resource.contentLength()) .contentType(MediaType.parseMediaType("application/octet-stream")) .body(resource); } } ``` 这样就可以通过访问 `/upload` 接口上传文件,访问 `/view/{filename}` 接口查看文件,访问 `/download/{filename}` 接口下载文件了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值