java——文件上传

2024-06-01 1063阅读

一、文件上传——简介

  1. 文件上传的简介:文件上传是指将本地计算机中的文件传输到网络上的服务器或另一台计算机上的过程。在 Web 开发中,文件上传通常指的是将用户通过 Web 页面提交的文件(如图像、文档、音频、视频等)传输到服务器端的操作。

    • 简单来说,文件上传是指将本地图片、视频、音频等文件上传到服务器上,供其他用户浏览或下载的过程。
    • 文件上传通常涉及以下几个主要组件:

        1. 客户端:指的是文件上传的发起方,通常是用户在 Web 浏览器中通过表单提交文件。
        1. 服务器端:指的是接收并处理文件上传请求的计算机系统或服务器。
        1. 上传表单:通过 HTML 表单元素来实现文件上传功能。表单需要设置 enctype 属性为 “multipart/form-data”,并包含一个文件输入框用于选择要上传的文件。
        1. 文件处理逻辑:服务器端接收到文件上传请求后,需要将上传的文件保存到指定的位置,并可能进行进一步的处理,如文件存储、文件重命名、文件格式验证等。
        1. 文件上传控制器:在 Web 开发框架中,通常需要编写文件上传的处理逻辑,这些逻辑通常由服务器端的控制器或处理器来处理。
      • 文件上传在 Web 开发中非常常见,常见的应用场景包括但不限于用户头像上传、文件分享、数据备份等。

二、文件上传——入门

  1. 文件上传的步骤:

      1. 先创建一个springboot工程(这个常识了,不展示了)
      1. 编写一个上传文件的前端html文件
      1. 编写一个controller
    • 项目结构

      java——文件上传

    • 文件上传前端的三要素:

      • 请求方式是:post
      • 需要设置 enctype=“multipart/form-data” 属性以支持文件上传
      • 元素应该包含一个 元素,用于让用户选择要上传的文件。

        java——文件上传

编写的html文件:



    
    
    文件上传


上传文件

编写的controller

package com.knife.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class UploadController {
    @PostMapping("/upload")
    public void upload(MultipartFile file){
        System.out.println("file == " + file);
    }
}

运行截图:(通过xml配置的路径去访问html文件,然后点击上传文件)

file内容不等于null,说明文件上传成功。

java——文件上传

java——文件上传

总结:服务端要想接收到从前端页面上传的文件,需要使用到一个api:MultipartFile,通过该api来接收上传的文件。而上传上来的文件是一个临时文件,当文件上传这次请求完成之后,这些临时文件会自动删除。因此,在上传文件的同时,应该把文件保存起来。

三、文件上传——本地存储—第一版

  1. 在服务端,接收到上传上来的文件之后,将文件存储在本地服务器磁盘中。

  2. 基础实现:在上面的文件上传——入门的基础上,修改一下controller就行。

package com.knife.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
public class UploadController {
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
        System.out.println("file == " + file);
        // 获取源文件的文件名
        String originalFilename = file.getOriginalFilename();
//        把上传上来的文件存储到磁盘上:transferTo的参数是一个文件
        file.transferTo(new File("E:\\images\\"+ originalFilename));
        
    }
}

只需把上面的controller改成上面一样,然后运行,然后如果你的路径不对,或者你盘符的目录不存在,就会报错了(因为这里没有对异常处理,只是简单地把异常抛出去了)

java——文件上传

最快的解决办法就是,修改本地存储的路径,输入一个存在的目录的路径。

java——文件上传

最佳解决办法:如下更改controller

package com.knife.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class UploadController {
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
        System.out.println("file == " + file);
        // 1. 获取源文件的文件名
        String originalFilename = file.getOriginalFilename();
//        定义要上传的路径
       String  fileUploadPath = "E:\\images\\"+ originalFilename;
//       创建要上传的文件
        File uploadFile = new File(fileUploadPath);
        // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if(!parentFile.exists()) {
            parentFile.mkdirs();
        }
        System.out.println(uploadFile);
        
        file.transferTo(uploadFile);
    }
}

运行:

java——文件上传

四、文件上传——本地存储—第二版

  1. 本地存储第一版存在的问题:

      1. 使用原始文件名进行存储时,如果同时上传了文件名一样的文件,那么后面上传的文件会把前面上传的文件给覆盖。
      • 解决:保证每一个文件的文件名是唯一的(文件名不能重复)
        • 使用uuid工具(通用唯一标识码)——使用生成的uuid码+原始文件名的后缀
        • 不管文件路径的报错的写法(和上面文件上传——本地存储—第一版就只有controller的差别):

package com.knife.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class UploadController {
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
        System.out.println("file == " + file);
        // 1. 获取源文件的文件名
        String originalFilename = file.getOriginalFilename();
       // 2. 构造唯一的文件名  -- 使用uuid(通用唯一识别码,长度固定的字符串,而且是唯一的)+ 原始文件文件后缀名
//        2.1. 通过字符串的截取,获取文件的后缀名
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
//        2.2 把uuid和文件后缀名合并
        String newFileName = UUID.randomUUID().toString() + extname;
        System.out.println("newFileName = " + newFileName);
//        把上传上来的文件存储到磁盘上:(指定一个路径)
        file.transferTo(new File("E:\\"+ newFileName));
    }
    
}
  1. 解决文件路径的报错的写法(和上面文件上传——本地存储—第一版就只有controller的差别):
package com.knife.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class UploadController {
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
        System.out.println("file == " + file);
        // 1. 获取源文件的文件名
        String originalFilename = file.getOriginalFilename();
       // 2. 构造唯一的文件名  -- 使用uuid(通用唯一识别码,长度固定的字符串,而且是唯一的)+ 原始文件文件后缀名
//        2.1. 通过字符串的截取,获取文件的后缀名
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
//        2.2 把uuid和文件后缀名合并
        String newFileName = UUID.randomUUID().toString() + extname;
        //        定义要上传的路径
        String  fileUploadPath = "E:\\images\\"+ newFileName;
        //       创建要上传的文件
        File uploadFile = new File(fileUploadPath);
    // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if(!parentFile.exists()) {
            parentFile.mkdirs();
        }
        System.out.println(uploadFile);
//        把上传上来的文件存储到磁盘上:(指定一个路径)
        file.transferTo(uploadFile);
    }
}

运行:

java——文件上传

文件上传大小限制的问题:在配置文件里面进行配置

java——文件上传

如果是application.properties则如上图一样配置就行,如果是application.yml,则如下配置即可

application.yml:

server:
  port: 8088   # 配置访问服务器的端口
spring:
  servlet:
    multipart:
      max-file-size: 10MB  # 配置单个文件最大上传大小
      max-request-size: 100MB   # 配置单个请求最大上传文件的大小(一次可以上传多个文件,即多个文件的总和也算)
  1. 本地存储存在的问题:

    java——文件上传

五、文件上传——对象存储——阿里云OOS

java——文件上传

java——文件上传

java——文件上传

五、1、参照官方SDK编写入门程序

  1. 第一步:在Maven工程中使用OSS Java SDK,只需在pom.xml中加入相应依赖即可。在中加入如下内容(参考官方文档的说明):
    com.aliyun.oss
    aliyun-sdk-oss
    3.15.1

  • 如果使用的是Java 9及以上的版本,则需要添加JAXB相关依赖。添加JAXB相关依赖示例代码如下:
        javax.xml.bind
        jaxb-api
        2.3.1
    
    
        javax.activation
        activation
        1.1.1
    
    
    
        org.glassfish.jaxb
        jaxb-runtime
        2.3.3
    
    
    1. 第二步:复制上传文件入门代码(官方文档)官方文档入门程序例子:然后再根据自己的实际情况改写
    import com.aliyun.oss.ClientException;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.OSSException;
    import com.aliyun.oss.model.PutObjectRequest;
    import com.aliyun.oss.model.PutObjectResult;
    import java.io.FileInputStream;
    import java.io.InputStream;
    public class Demo {
        public static void main(String[] args) throws Exception {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
            String objectName = "exampledir/exampleobject.txt";
            // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
            // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
            String filePath= "D:\\localpath\\examplefile.txt";
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
            try {
                InputStream inputStream = new FileInputStream(filePath);
                // 创建PutObjectRequest对象。
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
                // 创建PutObject请求。
                PutObjectResult result = ossClient.putObject(putObjectRequest);
            } 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();
                }
            }
        }
    } 
    

    改写后的入门程序:主要修改自己的endpoint、accessKeyId、bucketName、objectName、filePath

    package com.knife;
    import com.aliyun.oss.ClientException;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.OSSException;
    import com.aliyun.oss.model.PutObjectRequest;
    import com.aliyun.oss.model.PutObjectResult;
    import java.io.FileInputStream;
    import java.io.InputStream;
    public class uploadOss{
        public static void main(String[] args) throws Exception {
            // Endpoint:(华北2(北京))请按实际情况填写。
            String endpoint = "oss-cn-beijing.aliyuncs.com"; // 根据自己的实际情况填写
            // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    //        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
    //        使用accessKeyId、accessKeyIdSecret替代。
            String accessKeyId = "你自己的密钥id"; // 根据自己的实际情况填写
            String accessKeyIdSecret ="你自己的密钥";// 根据自己的实际情况填写
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "你自己的bucketName";// 根据自己的实际情况填写
            // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
            String objectName = "1.jpg";  //设置我们上传的文件,最终在阿里云上面是什么名字
            // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
            // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
            String filePath= "C:\\Users\\qq351\\Pictures\\Saved Pictures\\1.jpg";
            // 创建OSSClient实例。
    //        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeyIdSecret);
            try {
                InputStream inputStream = new FileInputStream(filePath);
                // 创建PutObjectRequest对象。
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
                // 创建PutObject请求。
                PutObjectResult result = ossClient.putObject(putObjectRequest);
            } 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();
                }
            }
        }
    } 
    

    路径获取:

    java——文件上传

    运行就可以传进去了

    java——文件上传

    java——文件上传

    通过浏览器访问该图片的路径时,会直接下载该图片,但是在页面显示出来挺简单的,就是使用一个imag标签,然后把路径放在src下即可

     
    

    六、在项目中使用OOS文件上传

    1. 在项目中,一般会把文件上传的方法封装成一个工具类然后再使用。

    在配置文件里面对oss的参数进行配置

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

    属性配置类:(读取配置文件里面的属性)

    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    @Data
    @Component
    @ConfigurationProperties(prefix = "aliyun.oss")
    public class AliOSSProperties {
        private String endpoint;
        private String accessKeyId;
        private String accessKeySecret;
        private String bucketName;
    }
    

    封装工具类:

    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
    import java.io.*;
    import java.util.UUID;
    /**
     * 阿里云 OSS 工具类
     */
    @Component
    public class AliOSSUtils {
        @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的路径返回
        }
    }
    

    controller类上使用

    import com.itheima.pojo.Result;
    import com.itheima.utils.AliOSSUtils;
    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.RestController;
    import org.springframework.web.multipart.MultipartFile;
    import java.io.File;
    import java.io.IOException;
    import java.util.UUID;
    @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);
        }
    }
    
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]