java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java文件上传

java实现文件上传的详细步骤

作者:大刀爱敲代码

文件上传是用户将本地文件通过Web页面提交到服务器的过程,涉及客户端、服务器端、上传表单等组件,在SpringBoot中,通过MultipartFile接口处理上传文件,并将其保存在服务器,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、文件上传——简介

二、文件上传——入门

编写的html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传</title>
</head>
<body>

<h2>上传文件</h2>

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="fileToUpload">
    <input type="submit" value="上传" name="submit">
</form>

</body>
</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,说明文件上传成功。

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

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

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

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

最佳解决办法:如下更改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);

    }
}

运行:

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

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


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

    }
}

运行:

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

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

application.yml:

server:
  port: 8088   # 配置访问服务器的端口

spring:
  servlet:
    multipart:
      max-file-size: 10MB  # 配置单个文件最大上传大小
      max-request-size: 100MB   # 配置单个请求最大上传文件的大小(一次可以上传多个文件,即多个文件的总和也算)

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

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

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.15.1</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>
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();
            }
        }
    }
} 

路径获取:

运行就可以传进去了

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

<image src="https://cangqiongwaimaiknife.oss-cn-beijing.aliyuncs.com/1.jpg">

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

在配置文件里面对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);
    }

}

总结 

到此这篇关于java实现文件上传的文章就介绍到这了,更多相关java文件上传内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文