day11-SpringBootWeb案例-2

SpringBoot中文件上传与阿里云OSS集成教程

一、新增员工

在这里插入图片描述
在这里插入图片描述

二、文件上传

1 简介

  • 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程。
  • 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

在这里插入图片描述

上传文件前端页面三要素:

  1. 表单必须有 file 域,用于选择要上传的文件
<input type="file" name="image"/>
  1. 表单提交方式必须为 POST
通常上传的文件会比较大,所以需要使用 POST 提交方式
  1. 表单的编码类型 enctype 必须要设置为:multipart/form-data
普通默认的编码格式是不适合传输大型的二进制数据的,所以在文件上传时,表单的编码格
式必须设置为 multipart/form-data

Spring 中提供了一个 API:MultipartFile,使用这个 API 就可以来接收到上传的文件。

表单提交的三项数据(姓名、年龄、文件),分别存储在不同的临时文件中。
当我们程序运行完毕之后,这个临时文件会自动删除。
所以,我们如果想要实现文件上传,需要将这个临时文件,要转存到我们的磁盘目录中。

2 本地存储

@Slf4j
@RestController
public class UploadController {

    @Autowired
    private AliOSSUtils aliOSSUtils;
    //本地存储文件
    @PostMapping("/upload")
    public Result upload(String username , Integer age , MultipartFile image) throws Exception {
        log.info("文件上传: {}, {}, {}", username, age, image);
        //获取原始文件名 - 1.jpg  123.0.0.jpg
        String originalFilename = image.getOriginalFilename();

        //构造唯一的文件名 (不能重复) - uuid(通用唯一识别码) de49685b-61c0-4b11-80fa-c71e95924018
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
        String newFileName = UUID.randomUUID().toString() + extname;
        log.info("新的文件名: {}", newFileName);

        //将文件存储在服务器的磁盘目录中 E:\images
        image.transferTo(new File("E:\\images\\"+newFileName));

        return Result.success();
    }

}

String getOriginalFilename(); //获取原始文件名
void transferTo(File dest); //将接收的文件转存到磁盘文件中
long getSize(); //获取文件的大小,单位:字节
byte[] getBytes(); //获取文件内容的字节数组
InputStream getInputStream(); //获取接收到的文件内容的输入流

在这里插入图片描述
在 SpringBoot中,文件上传,默认单个文件允许最大大小为 1M。如果需要上传 大文件,可以进行如下配置:

#配置单个文件最大上传大小
spring.servlet.multipart.max-file-size=10MB

#配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB

如果直接存储在服务器的磁盘目录中,存在以下缺点:

  1. 不安全:磁盘如果损坏,所有的文件就会丢失
  2. 容量有限:如果存储大量的图片,磁盘空间有限(磁盘不可能无限制扩容)
  3. 无法直接访问

为了解决上述问题呢,通常有两种解决方案:

  1. 自己搭建存储服务器,如:fastDFS 、MinIO
  2. 使用现成的云服务,如:阿里云,腾讯云,华为云

3 阿里云OSS

3.1 准备

阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是国内最大的云服务提供商 。

云服务 指的就是通过互联网对外提供的各种各样的服务,比如像:语音服务、短信服务、邮件服务、视频直播服务、文字识别服务、对象存储服务等等。

阿里云对象存储 OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用 OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。

在我们使用了阿里云 OSS 对象存储服务之后,我们的项目当中如果涉及到文件上传这样的业务,在前端进行文件上传并请求到服务端时,在服务器本地磁盘当中就不需要再来存储文件了。我们直接将接收到的文件上传到 oss,由 oss 帮我们存储和管理,同时阿里云的 oss 存储服务还保障了我们所存储内容的安全可靠。在这里插入图片描述

第三方服务-通用思路
在这里插入图片描述

阿里云OSS-使用步骤
在这里插入图片描述

  1. SDK:Software Development Kit 的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。
  2. Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。

3.2 入门

参照官方所提供的 sdk 示例来编写入门程序。

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI4GCH1vX6DKqJWxd6nEuW";
        String accessKeySecret = "yBshYweHOpqDuhCArrVHwIiBKpyqSL";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "web-tlias";

        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "1.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "C:\\Users\\Administrator\\Pictures\\Camera Roll\\1.jpg";

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

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } 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();
            }
        }
    }
}

3.3 集成

集成步骤

  1. 引入阿里云 OSS 上传文件工具类(由官方的示例代码改造而来)
  2. 上传图片接口开发
@Component
public class AliOSSUtils {

//    @Value("${aliyun.oss.endpoint}")
//    private String endpoint ;
//    @Value("${aliyun.oss.accessKeyId}")
//    private String accessKeyId ;
//    @Value("${aliyun.oss.accessKeySecret}")
//    private String accessKeySecret ;
//    @Value("${aliyun.oss.bucketName}")
//    private String bucketName ;

    @Autowired
    private AliOSSProperties aliOSSProperties;

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {
        //获取阿里云OSS参数
        String endpoint = aliOSSProperties.getEndpoint();
        String accessKeyId = aliOSSProperties.getAccessKeyId();
        String accessKeySecret = aliOSSProperties.getAccessKeySecret();
        String bucketName = aliOSSProperties.getBucketName();

        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }

}
@Slf4j
@RestController
public class UploadController {

    @Autowired
    private AliOSSUtils aliOSSUtils;
    
    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        log.info("文件上传, 文件名: {}", image.getOriginalFilename());

        //调用阿里云OSS工具类进行文件上传
        String url = aliOSSUtils.upload(image);
        log.info("文件上传完成,文件访问的url: {}", url);

        return Result.success(url);
    }

}

三、修改员工

1 查询回显

在这里插入图片描述

/**
 * 员工管理Controller
 */
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;
    
    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id){
        log.info("根据ID查询员工信息, id: {}",id);
        Emp emp = empService.getById(id);
        return Result.success(emp);
    }
}
/**
 * 员工管理
 */
@Mapper
public interface EmpMapper {

    /**
     * 根据ID查询员工
     * @param id
     * @return
     */
    @Select("select * from emp where  id = #{id}")
    Emp getById(Integer id);


}

2 修改员工

在这里插入图片描述

/**
 * 员工管理Controller
 */
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;
    
    @PutMapping
    public Result update(@RequestBody Emp emp){
        log.info("更新员工信息 : {}", emp);
        empService.update(emp);
        return Result.success();
    }
}
/**
 * 员工管理
 */
@Mapper
public interface EmpMapper {

    @Override
    public void update(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now());

        empMapper.update(emp);
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
    <!--更新员工-->
    <update id="update">
        update emp
        <set>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="name != null and name != ''">
                name = #{name},
            </if>
            <if test="gender != null">
                gender = #{gender},
            </if>
            <if test="image != null and image != ''">
                image = #{image},
            </if>
            <if test="job != null">
                job = #{job},
            </if>
            <if test="entrydate != null">
                entrydate = #{entrydate},
            </if>
            <if test="deptId != null">
                dept_id = #{deptId},
            </if>
            <if test="updateTime != null">
                update_time = #{updateTime}
            </if>
        </set>
        where id = #{id}
    </update>
</mapper>

四、配置文件

1 参数配置化

在这里插入图片描述
在这里插入图片描述

@Value 注解通常用于外部配置的属性注入,具体用法为: @Value(“${配置文件中的key}”)

2 yml 配置文件

yml 基本语法

  1. 大小写敏感
  2. 数值前边必须有空格,作为分隔符
  3. 使用缩进表示层级关系,缩进时,不允许使用 Tab 键,只能用空格(idea 中会自动将 Tab 转换为空格)
  4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  5. # 表示注释,从这个字符一直到行尾,都会被解析器忽略

在这里插入图片描述

对象/Map集合:

user:
   name: zhangsan
   age: 18
   password: 123456

数组/List/Set集合:

hobby:
  - java  
  - game
  - sport
spring:
  #数据库连接信息
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tlias
    username: root
    password: 1234
  #文件上传的配置
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 100MB
#Mybatis配置
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

#阿里云OSS
aliyun:
  oss:
    endpoint: https://oss-cn-hangzhou.aliyuncs.com
    accessKeyId: LTAI4GCH1vX6DKqJWxd6nEuW
    accessKeySecret: yBshYweHOpqDuhCArrVHwIiBKpyqSL
    bucketName: web-tlias

3 @ConfigurationProperties

在这里插入图片描述
在这里插入图片描述

如果要注入的属性非常的多,并且还想做到复用,就可以定义这么一个 bean 对象。通过 configuration properties 批量的将外部的属性配置直接注入到 bin 对象的属性当中。在其他的类当中,我要想获取到注入进来的属性,我直接注入 bin 对象,然后调用 get 方法,就可以获取到对应的属性值了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值