文件上传——后端

发布时间:2023年12月20日

文件上传流程:
在这里插入图片描述

创建阿里云OSS(对象存储服务)的bucket

登录阿里云,并完成实名认证,地址:https://www.aliyun.com/.
可以通过搜索,进入以下页面:
在这里插入图片描述
点击立即使用后:
在这里插入图片描述
点击试用后,就开通了相关服务,然后在产品中搜索“OSS”,点击管理平台:
在这里插入图片描述
在这里插入图片描述
点击“Bucket列表”,进行创建:
在这里插入图片描述
在这里插入图片描述

代码

创建成功后再次进入bucket列表,通过帮助文档进入到SDK,选择Java:
在这里插入图片描述
在这里插入图片描述
也可以使用以下文件上传代码示例:
代码思路
配置文件中 (application-dev.xml) 添加OSS的配置项,可以通过配置属性类(AliOssProperties)加载并封装这些属性值,然后通过OssConfiguration创建AliOssProperties,其中OssConfiguration在项目启动时就能调用aliOssUtil方法,把该对象创建出来后,交给spring容器进行管理(通过@Bean实现,@ConditionalOnMissingBean保证整个spring容器里面只有一个AliOssUtil对象),因此可以在对应的Controller类中,通过@Autowired获取到AliOssUtil,实现文件上传。

package com.sky.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}

相关配置项的设置:

  1. 设置配置属性类:
package com.sky.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

}

  1. 项目配置文件设置application.xml:
server:
  port: 8080

spring:
  profiles:
    active: dev
  main:
    allow-circular-references: true
  datasource:
    druid:
      driver-class-name: ${sky.datasource.driver-class-name}
      url: jdbc:mysql://${sky.datasource.host}:${sky.datasource.port}/${sky.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: ${sky.datasource.username}
      password: ${sky.datasource.password}

mybatis:
  #mapper配置文件
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.sky.entity
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true

logging:
  level:
    com:
      sky:
        mapper: debug
        service: info
        controller: info

sky:
  jwt:
    # 设置jwt签名加密时使用的秘钥
    admin-secret-key: itcast
    # 设置jwt过期时间
    admin-ttl: 7200000
    # 设置前端传递过来的令牌名称
    admin-token-name: token
  # 添加阿里云文件存储服务相关配置
  alioss:
    endpoint: ${sky.alioss.endpoint}
    access-key-id: ${sky.alioss.access-key-id}
    access-key-secret: ${sky.alioss.access-key-secret}
    bucket-name: ${sky.alioss.bucket-name}

这里使用变量的方式添加阿里云对象存储服务的相关属性值,以便适应开发(dev)和产品(prod)两种环境,当前使用的环境为dev,于是在application-dev.xml中设置相关属性值,如:

sky:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: localhost
    port: 3306
    database: xxxx
    username: root
    password: xxxx
  alioss:
    endpoint: oss-cn-hangzhou.aliyuncs.com
    access-key-id: xxxx
    access-key-secret: xxxx
    bucket-name: xxxx

添加OSS配置类

package com.sky.config;

import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * ClassName: OssConfig
 * PackageName: com.sky.config
 * Description: 配置类,用于创建AliOssUtil对象
 *
 * @Author Xiyan Zhong
 * @Create 2023/12/19 下午4:35
 * @Version 1.0
 */
@Configuration
@Slf4j
public class OssConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);

        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());

    }
}

相应的controller代码:

package com.sky.controller.admin;

import com.sky.result.Result;
import com.sky.utils.AliOssUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * ClassName: CommonController
 * PackageName: com.sky.controller.admin
 * Description:通用上传接口
 *
 * @Author Xiyan Zhong
 * @Create 2023/12/19 下午2:46
 * @Version 1.0
 */

@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {

    // 通过Autowired注解注入依赖
    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    // 参数名要与前端请求时的参数保持一致
    public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);

        try {
            // 获取原始文件名
            String originalFileName = file.getOriginalFilename();
            // 截取原始文件名的后缀
            String extension = originalFileName.substring(originalFileName.lastIndexOf("."));
            // 构造新文件名称
            String objectName = UUID.randomUUID().toString() + extension;

            // 第一个参数:文件对象转成的字节数组;第二个参数:文件上传到OSS中对应的名称,通过UUID+后缀生成,避免文件重名,导致文件覆盖。
            // filePath表示文件的请求路径
            String filePath =  aliOssUtil.upload(file.getBytes(),objectName);

            return Result.success(filePath);
        }catch (IOException e){
            log.error("文件上传失败:{}",e);
        }


        return Result.error("文件上传失败");
    }
}

文章来源:https://blog.csdn.net/Z__XY_/article/details/135086194
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。