当前位置: 首页 > news >正文

新增菜品-02.代码开发2

一.阿里云OSS文件上传接口

根据类型(type)查询分类接口已经开发完毕,接下来我们要开发第二个接口:使用阿里云OSS进行文件上传接口。

1.接口文档

在文件上传接口文档中,我们可以看到请求方式为POST,因此在controller层使用@PostMapping注解,路径为“/admin/common/upload”。请求的参数是MultipartFile类型的file。

返回值是String类型的参数,代表文件的url路径,前端通过该路径获得文件并渲染出来。 

2.配置阿里云OSS属性

既然要使用阿里云OSS,那么就要配置相关的属性。我们在application-dev.yml,即开发环境配置文件中配置相关的属性,然后在application.yml配置文件中引入。

application-dev.yml:

sky:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: localhost
    port: 3306
    database: sky_take_out
    username: root
    password:
  alioss:
    endpoint: https://oss-cn-nanjing.aliyuncs.com
    bucket-name: sky-gjw-yhx
    access-key-secret: *********************
    access-key-id: ********************
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}

 3.进行阿里云OSS工具类的开发

AliOssUtil.class

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();
    }
}

在AliOssUtil.class中我们要使用AliOssProperties.class中的属性。我们在AliOssProperties.class这个配置属性类上加上了@ConfigurationProperties注解,并在prefix当中指定了该属性在配置文件中的位置,这样在依赖注入AliOssProperties实现类对象时,该对象就会自动获取到位置文件中配置的属性。

package com.sky.properties;

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

@Component
@ConfigurationProperties(prefix = "sky.alioss")     // 只有当对象由Spring容器创建时,属性绑定才会生效。如果new AliOssProperties(),再去get属性是获取不到的,必须使用依赖注入才行
@Data
public class AliOssProperties {

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

}

然后我们定义一个配置类OssConfiguration,用来将AliOssProperties中的属性配置给AliOssUtil对象并返回。

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;

/**
 * 定义一个配置类,用来将AliOssProperties中的属性配置给AliOssUtil对象并返回
 */
@Configuration
@Slf4j
public class OssConfiguration {

    @Bean   // 使用bean注解,这样就可以直接从IOC容器中获取到该AliOssUtil对象了,而不需要再OssConfiguration ossConfiguration = new OssConfiguration(),然后
//        AliOssUtil aliOssUtil = ossConfiguration.aliOssUtil(aliOssProperties);    aliOssProperties要通过以来后注入
    @ConditionalOnMissingBean



    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());
    }
}

定义aliOssUtil方法用来返回AliOssUtil类的实现类对象,该方法的参数为aliOssProperties,(在 Spring 中,@Configuration 注解的类中的方法如果使用了 @Bean 注解,那么该方法的返回值会被注册到 Spring 的 IOC 容器中作为一个 Bean。方法的参数则会被 Spring 自动从 IOC 容器中获取,前提是这些参数本身也是容器中管理的 Bean。)然后调用该对象的get方法获取到属性值并传递给aliOssUtil对象。

4.定义Controller层

在Controller层中,使用@PostMapping("/upload")请求,要进行文件上传,我们设置Controller层来对前端传输过来的数据进行接收,对于普通的表单项,使用正常的参数变量进行接收即可,对于图片、文本、音视频等二进制类型的文件来说,使用一个特定的变量类型MultipartFile进行文件接收即可。要想成功接收到传输过来表单项,必须要保证表单项的名称和方法形参的名称要保持一致。叫file。

package com.sky.controller.admin;

import com.sky.config.OssConfiguration;
import com.sky.constant.MessageConstant;
import com.sky.properties.AliOssProperties;
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;

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

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file) {
        log.info("文件上传:{}",file);


        try {
            // 获得原始文件名
            String originalFilename = file.getOriginalFilename();
            // 获得文件扩展名
            String extension = originalFilename.substring(originalFilename.indexOf("."));   // indexOf:查找子字符串或字符在字符串中第一次出现的位置。substring(beginIndex):截取从 beginIndex(包含)到字符串末尾的子串
            // 创建新名称:UUID+扩展名
            String fileName = UUID.randomUUID().toString() + extension;
            // 获得文件路径
            String filePath = aliOssUtil.upload(file.getBytes(), fileName);// upload(byte[] bytes,String objectName)   bytes:要上传的文件字节码 objectName:上传的文件在阿里云OSS中的名称
            return Result.success(filePath);    // 将文件在阿里云OSS中的路径返回给前端,以让前端进行渲染

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

使用.getOriginalFilename()获得原始文件名,然后获得文件名后缀。在使用工具类UUID生成UUID,拼接上文件名后缀,生成新的文件名。使用依赖注入将aliOssUtil注入并调用upload方法传入要上传的文件以及文件名。获得文件的上传路径,最后将该文件路径返回给前端,让前端进行渲染展示。

注意:阿里云 OSS 的 Endpoint 通常只需要填写域名部分,例如 oss-cn-hangzhou.aliyuncs.com,而不需要包含 https://。如果在配置中包含了 https://,可能会导致生成的图片 URL 不正确。

相关文章:

  • 【后端】【Djagno】【ORM】models.ManyToManyField 多对多字段类型全解
  • 【设计模式】策略模式
  • EasyExcel--导入和导出Excel的方法
  • 面向机器人领域 | AKM Delta-Sigma数字输出无磁芯电流传感器
  • turnjs图册翻书效果
  • 数据仓库是什么,跟数据集成有什么关系
  • Web3 时代数据保护的关键挑战与应对策略
  • PostgreSQL 触发器
  • 电机控制常见面试问题(十四)
  • gralloc1_perform具体在干什么
  • 从两指到三指:Robotiq机器人自适应夹持器技术解析
  • MySQL InnoDB 事务隔离级别和锁
  • git 命令回退版本
  • nodejs - 基础知识
  • Plant Simulation中怎么更改机器人3D模型
  • 精挑20题:MySQL 8.0高频面试题深度解析——掌握核心知识点、新特性和优化技巧
  • WPF 布局中的共性尺寸组(Shared Size Group)
  • Git远程拉取和推送配置
  • Docker Compose部署MantisBT
  • 在本地跑通spark环境
  • 国家统计局:下阶段要继续发挥宏观政策作用,促进价格合理回升
  • 南宁海关辟谣网传“查获600公斤稀土材料”:实为焊锡膏
  • 中国田径巡回赛西安站完赛:男子跳远石雨豪夺冠
  • 荣盛发展:新增未支付债务11.05亿元
  • 以军证实空袭也门多个港口
  • 爱德华多·阿拉纳宣誓就任秘鲁新总理