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

新增菜品-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 不正确。


http://www.kler.cn/a/594648.html

相关文章:

  • 基于CVX优化器的储能电池调峰调频算法matlab仿真
  • 算法训练篇06--力扣611.有效三角形的个数
  • 【蓝桥杯速成】| 8.回溯算法
  • 什么是 HTML 实体,常见的 HTML 实体有哪些用途?
  • DeepSeek引爆AIoT革命:华奥系科技领跑“万物智联”时代
  • 实现Token无感刷新
  • 合批Batching
  • 【DR_CAN-最优控制笔记】02.动态规划_Dynamic Programming_基本概念
  • 力扣977. 有序数组的平方(双指针技巧)
  • 三、小白学JAVA-比较运算符与循环
  • Java设计模式之责任链模式
  • UML(统一建模语言)中总共有哪些图
  • ubuntu20如何升级nginx到最新版本(其它版本大概率也可以)
  • git工作区、暂存区、本地仓库、远程仓库的区别和联系
  • 高主频CPU+RTX4090:AI生图性能优化超150%
  • [C++面试] 迭代器面试点(难点)
  • 【docker】--- 详解 WSL2 中的 Ubuntu 和 Docker Desktop 的区别和关系!
  • python_巨潮年报pdf下载
  • Claude:从安全优先的 AI 实验室到创作者协作者(2025 深度解析)
  • UE5材质法线强度控制节点FlattenNormal