MultipartFile的属性 file.getOriginalFilename()与file.getName()的区别 MultipartFile与File互转_multipartfile属性-程序员宅基地

技术标签: spring boot  Java  MultipartFile  文件  SpringBoot  File  

MultipartFile

一、概述

MultipartFile为org.springframework.web.mutipart包下的一个类,也就是说如果想使用MultipartFile这个类就必须引入spring框架,换句话说,如果想在项目中使用MultipartFile这个类,那么项目必须要使用spring框架才可以,否则无法引入这个类。

以下基于spring-web.5.2.9.RELEASE源码了解一下MultipartFile
在这里插入图片描述
MultipartFile注释说明

第一句:一种可以接收使用多种请求方式来进行上传文件的代表形式。也就是说,如果你想用spring框架来实现项目中的文件上传功能,则MultipartFile可能是最合适的选择,而这里提到的多种请求方式则可以通俗理解为以表单的形式提交。
第二句:这个文件内容可以存储到内存中或者存储在磁盘的临时位置上。
第三句:无论发生哪种情况,用户都可以自由地拷贝文件内容到session存储中,或者以一种永久存储的形式进行存储,如果有需要的话。
第四句:这种临时性的存储在请求结束之后将会被清除掉。

二、MultipartFile常用方法

首先MultipartFile是一个接口,并继承自InputStreamSource,且在InputStreamSource接口中封装了getInputStream方法,该方法的返回类型为InputStream类型,这也就是为什么MultipartFile文件可以转换为输入流。通过以下代码即可将MultipartFile格式的文件转换为输入流。

multipartFile.getInputStream();
方法 说明
String getName() 返回参数的名称,如(MultipartFile oriFile)则返回为oriFile
String getOriginalFilename() 返回客户端文件系统中的原始文件名。这可能包含盘符路径信息,具体取决于所使用的浏览器, 解决方法可参考 link
String getContentType() getContentType方法获取的是文件的类型,注意是文件的类型,不是文件的拓展名。
boolean isEmpty() 判断传入的文件是否为空,如果为空则表示没有传入任何文件。
long getSize() 用来获取文件的大小,单位是字节。
byte[] getBytes() 用来将文件转换成一种字节数组的方式进行传输,会抛出IOException异常。
InputStream getInputStream() 返回一个InputStream以从中读取文件的内容。通过此方法就可以获取到流
Resource getResource()
void transferTo(File dest) 把接收到的文件写入到目的文件中,如果目的文件已经存在了则会先进行删除。用于将MultipartFile转换为File类型文件
void transferTo(Path dest) 将接收到的文件传输到给定的目标文件。默认实现只复制文件输入流。
@GetMapping("/uploadFile")
public ApiResult test(@RequestParam MultipartFile uploadFile) throws IOException {
    
	// 原文件名称
    System.out.println("uploadFile.getOriginalFilename() = " + uploadFile.getOriginalFilename());
    // 文件的接收参数 @RequestParam MultipartFile uploadFile中的 uploadFile
    System.out.println("uploadFile.getName() = " + uploadFile.getName());
    // 文件的类型
    System.out.println("uploadFile.getContentType() = " + uploadFile.getContentType());
    System.out.println("uploadFile.getResource() = " + uploadFile.getResource());
    System.out.println("uploadFile.getBytes() = " + uploadFile.getBytes());
    // 文件大小
    System.out.println("uploadFile.getSize() = " + uploadFile.getSize());
    return ApiResult.ok();
}

上传的文件:a.png
在这里插入图片描述
执行结果:

uploadFile.getOriginalFilename() = a.png
uploadFile.getName() = uploadFile
uploadFile.getContentType() = image/jpeg
uploadFile.getResource() = MultipartFile resource [file]
uploadFile.getBytes() = [B@1fa8cd72
uploadFile.getSize() = 143

三、Springboot与MultipartFile的使用

3.1 设置文件上传大小限制

springboot默认文件上传大小为1M, 若超过1M会抛出异常,如下:

org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
	at org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl$FileItemStreamImpl$1.raiseError(FileUploadBase.java:628) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.checkLimit(LimitedInputStream.java:76) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:135) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at java.io.FilterInputStream.read(Unknown Source) ~[na:1.8.0_131]
	at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:98) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:68) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:293) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.connector.Request.parseParts(Request.java:2902) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.connector.Request.parseParameters(Request.java:3242) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.connector.Request.getParameter(Request.java:1136) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:84) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_131]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.34.jar:8.5.34]
	at java.lang.Thread.run(Unknown Source) [na:1.8.0_131]
方式一

application.properties配置文件

# 上传的单个文件的大小最大为3MB
spring.servlet.multipart.max-file-size = 3MB
# 单次请求的所有文件的总大小最大为9MB
spring.servlet.multipart.max-request-size = 9MB

# 如果是想要不限制文件上传的大小,那么就把两个值都设置为-1
方式二

在配置类中配置MultipartConfigElement方法,并将配置类注册到容器中,代码示例:

@Configuration
@SpringBootApplication
@MapperScan("com.demo.explain.mapper")
public class StoreApplication {
    
 
	public static void main(String[] args) {
    
		SpringApplication.run(StoreApplication.class, args);
	}
	@Bean
	public MultipartConfigElement getMultipartConfigElement() {
    
		MultipartConfigFactory factory = new MultipartConfigFactory();
		// DataSize dataSize = DataSize.ofMegabytes(10);
		// 设置文件最大10M,DataUnit提供5中类型B,KB,MB,GB,TB
		factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));
		factory.setMaxRequestSize(DataSize.of(10, DataUnit.MEGABYTES));
		// 设置总上传数据总大小10M
		return factory.createMultipartConfig();
	}
}

全局异常捕获

package com.example.demo.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

// 全局异常捕获类
@ControllerAdvice
public class GlobalExceptionHandler {
    

    // 若上传的文件大小超过配置类中配置的指定大小后会触发下面的异常
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void defultExcepitonHandler(MaxUploadSizeExceededException ex) {
    
		log.info("[exceptionHandler] maxUploadSizeExceededExceptionHandler :"+e.getMessage(),e);
		return ResponseFactory.build(900001,"文件大小超过限制");
    }
}

3.2 Springboot上传单个文件,包含其他参数

Controller层代码如下:

@RestController
@RequestMapping("/test")
public class MultipartFileController {
    
    @PostMapping("/upload")
    public String multipartFileTest(@ApiParam(value = "multipartFile") @RequestParam MultipartFile multipartFile,@ApiParam(value = "用户名") @RequestParam  String userName) throws Exception{
    
       
        return "成功";
    }
}

postman传参如下:
在这里插入图片描述

请求体里, 首先要选择from-data这种方式;key中的multipartFile与后端接口的变量名保持一致即可,类型选择File。

3.3 Springboot上传多个文件,包含请求体

Controller层代码如下:请求体需要使用@Valid注解而不是@RequestBody

@RestController
@RequestMapping("/test")
public class MultipartFileController {
    
    @PostMapping("/upload")
    public String multipartFileTest(@ApiParam(value = "multipartFiles") @RequestParam MultipartFile[] multipartFiles,@Valid UserDO userDO) throws Exception{
    
       
        return "成功";
    }
}
import lombok.Data;

@Data
public class UserDO {
    
    private String userName;
    private String email;
    private int age;

postman传参如下:
在这里插入图片描述

四、MultipartFile中transferTo方法的坑

4.1 调用tansferTo()方法后,再次获取file.getInputStream()方法时,报临时文件异常

2023-02-06 10:00:20.557 ERROR 14780 --- [http-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.io.FileNotFoundException: C:\Users\AppData\Local\Temp\work\demo\upload_file.tmp (系统找不到指定的文件。)
	at java.io.FileInputStream.open0(Native Method) ~[na:1.8.0_322]
	at java.io.FileInputStream.open(FileInputStream.java:195) ~[na:1.8.0_322]
	at java.io.FileInputStream.<init>(FileInputStream.java:138) ~[na:1.8.0_322]
	at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getInputStream(DiskFileItem.java:198) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
	at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getInputStream(StandardMultipartHttpServletRequest.java:254) ~[spring-web-5.3.22.jar:5.3.22]
	at com.tanwei.spring.app.controllers.FileController.file(FileController.java:29) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_322]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_322]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_322]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_322]

FileNotFoundException异常就是文件找不到了,也就是说tansferTo()可能在传输完成后把临时文件删除了,这是肯定的,但是答案只能说是对一半,我们将一步一步的进行源码分析

源码分析

以下基于spring-web.5.2.9.RELEASE源码分析MultipartFile的tansferTo()方法
调用tansferTo()方法,Spring Boot Web默认是调用StandardMultipartHttpServletRequest.StandardMultipartFile.tansferTo()方法,如下所示:

private static class StandardMultipartFile implements MultipartFile, Serializable {
    
		//......省略其他内容

		@Override
		public void transferTo(File dest) throws IOException, IllegalStateException {
    
			this.part.write(dest.getPath());
			if (dest.isAbsolute() && !dest.exists()) {
    
				// Servlet 3.0 Part.write is not guaranteed to support absolute file paths:
				// may translate the given path to a relative location within a temp dir
				// (e.g. on Jetty whereas Tomcat and Undertow detect absolute paths).
				// At least we offloaded the file from memory storage; it'll get deleted
				// from the temp dir eventually in any case. And for our user's purposes,
				// we can manually copy it to the requested location as a fallback.
				FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest.toPath()));
			}
		}
		
		@Override
		public void transferTo(Path dest) throws IOException, IllegalStateException {
    
			FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest));
		}

	}

我们主要看一下.tansferTo(File dest)这个方法里的this.part.write(dest.getPath());代码,这里的part实现是ApplicationPart,如下所示:

public class ApplicationPart implements Part {
    
 	//......省略其他内容

    public void write(String fileName) throws IOException {
    
        // 构建一个需要存储的文件
        File file = new File(fileName);
        // 判断文件的地址是否是一个绝对路径地址,如C://demo/xxx.txt,返回true
        // 若文件路径不是绝对路径,将创建一个临时目录,所以这里也是经常会出现问题的地方,在使用multipartFile.tansferTo()的时候最好给绝对路径
        if (!file.isAbsolute()) {
    
            // 如果不是一个绝对路径地址,则在this.location下创建
            // this.location是一个临时文件对象,地址(C:\Users\xxxx\AppData\Local\Temp\tomcat.8090.3830877266980608489\work\Tomcat\localhost)
            file = new File(this.location, fileName);
        }

        try {
    
            this.fileItem.write(file);
        } catch (Exception var4) {
    
            throw new IOException(var4);
        }
    }
}

this.fileItem.write(file);这行代码是主要的核心代码,我们继续跟进去查看一下具体做了什么,如下所示:

public class DiskFileItem implements FileItem {
    
    //......省略其他内容

    public void write(File file) throws Exception {
    
        // 判断文件项是否缓存在内存中的,这里我们没设置,一般都是存在上面的临时磁盘中
        if (this.isInMemory()) {
    
            FileOutputStream fout = null;

            try {
    
                fout = new FileOutputStream(file);
                fout.write(this.get());
                fout.close();
            } finally {
    
                IOUtils.closeQuietly(fout);
            }
        } else {
    
             // 主要看一下这个代码块
            // 获取文件项的存储位置,即你上传的文件在磁盘上的临时文件
            File outputFile = this.getStoreLocation();
            if (outputFile == null) {
    
                throw new FileUploadException("Cannot write uploaded file to disk!");
            }
            // 获取文件长度
            this.size = outputFile.length();
            if (file.exists() && !file.delete()) {
    
                throw new FileUploadException("Cannot write uploaded file to disk!");
            }
            // 之所以不能再调用file.getInputStream()方法,原因就是在这
            // fileA.renameTo(fileB)方法:
            //    1) 当fileA文件信息(包含文件名、文件路径)与fileB全部相同时,只是单纯的重命名
            //    2) 当fileA文件信息(特别是文件路径)与fileB不一致时,则存在重命名和剪切,这里的剪切就会把临时文件删除,并将文件复制到fileB位置
            // 所以,在调用file.getInputStream()时,file获取的还是原始的文件位置,调用transerTo()方法后(其实调用了renameTo()),原始文件已经不存在了
            // 故而抛出FileNotFoundException异常
            if (!outputFile.renameTo(file)) {
    
                BufferedInputStream in = null;
                BufferedOutputStream out = null;

                try {
    
                    in = new BufferedInputStream(new FileInputStream(outputFile));
                    out = new BufferedOutputStream(new FileOutputStream(file));
                    IOUtils.copy(in, out);
                    out.close();
                } finally {
    
                    IOUtils.closeQuietly(in);
                    IOUtils.closeQuietly(out);
                }
            }
        }

    }

}

4.2 MultipartFile调用transferTo传入相对路径报FileNotFoundException

错误代码

@PostMapping("/uploadFile")
public String uploadImg(@RequestParam("file") MultipartFile file) {
    
	String baseDir = "./imgFile"; // 这里不能直接使用相对路径
	if (!file.isEmpty()) {
    
		String name = file.getOriginalFilename();
		String prefix = name.lastIndexOf(".") != -1 ? name.substring(name.lastIndexOf(".")) : ".jpg";
		String path = UUID.randomUUID().toString().replace("-", "") + prefix;

		try {
    
			// 这里代码都是没有问题的
			File filePath = new File(baseDir, path);
			// 第一次执行代码时,路径是不存在的
			logger.info("文件保存路径:{},是否存在:{}", filePath.getParentFile().exists(), filePath.getParent());
			if (!filePath.getParentFile().exists()) {
     // 如果存放路径的父目录不存在,就创建它。
				filePath.getParentFile().mkdirs();
			}
			// 如果路径不存在,上面的代码会创建路径,此时路径即已经创建好了
			logger.info("文件保存路径:{},是否存在:{}", filePath.getParentFile().exists(), filePath.getParent());
			// 此处使用相对路径,似乎是一个坑!
			// 相对路径:filePath
			// 绝对路径:filePath.getAbsoluteFile()
			logger.info("文件将要保存的路径:{}", filePath.getPath());

			file.transferTo(filePath);
			logger.info("文件成功保存的路径:{}", filePath.getAbsolutePath());
			return "上传成功";
		} catch (Exception e) {
    
			logger.error(e.getMessage());
		}
	}
	return "上传失败";
}

一旦执行到file.transferTo(filePath),就会产生一个FileNotFoundException,如下图:

2020-11-27 10:15:06.522 ERROR 5200 --- [nio-8080-exec-1] r.controller.LearnController : java.io.FileNotFoundException: C:\Users\Alfred\AppData\Local\Temp

\tomcat.8080.2388870592947355119\work\Tomcat\localhost\ROOT\.\imgFile\684918a520684801b658c85a02bf9ba5.jpg (系统找不到指定的路径。)

原理在上面那个问题中已经分析过,void transferTo(File dest)内部若判断文件路径不是绝对路径,则会创建一个临时目录出来

解决方法
String baseDir = "./imgFile";
File saveFile= new File(baseDir, path);
//修改此处传如的参数,改为文件的绝对路径
multipartFile.transferTo(saveFile.getAbsoluteFile());

五、MultipartFile与File文件互转

5.1 MultipartFile转换为File文件

5.1.1 MultipartFile.transferTo(File dest)

若MultipartFile对象是在controller层传入,回话结束后MultipartFile文件会自动清理; 若MultipartFile对象是自己创建出来的,则使用完需要自己手动删除文件。

 @PostMapping("/upload")
    public String multipartFileTest(@ApiParam(value = "multipartFile") @RequestParam MultipartFile multipartFile,@ApiParam(value = "用户名") @RequestParam  String userName) throws Exception{
    
        //考虑不同浏览器上传文件会带入盘符等路径信息,此处处理一下
    	String fileName = org.apache.commons.io.FilenameUtils.getName(multipartFile.getOriginalFilename());
        File saveFile= new File("/app/home/data/",fileName );
		//修改此处传如的参数,改为文件的绝对路径
		multipartFile.transferTo(saveFile.getAbsoluteFile());
        return "成功";
    }
5.1.2 使用FileUtils.copyInputStreamToFile()

导入依赖包

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.7</version>
</dependency>
  File file = new File(path,"demo.txt");
 // 得到MultipartFile文件
  MultipartFile multipartFile = getFile();
  // 把流输出到文件
  FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);

5.2 File转换为MultipartFile文件

5.2.1 使用org.springframework.mock.web.MockMultipartFile(不推荐)

(1):使用org.springframework.mock.web.MockMultipartFile 需要导入spring-test.jar
该方法需要使用spring-test.jar包,生产环境一般是跳过测试包的,因此可能会导致其他问题,所以尽量不要使用这种方式

public static void main(String[] args) throws Exception {
    
    String filePath = "F:\\test.txt";
    File file = new File(filePath);
    FileInputStream fileInputStream = new FileInputStream(file);
    // MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)
    // 其中originalFilename,String contentType 旧名字,类型  可为空
    // ContentType.APPLICATION_OCTET_STREAM.toString() 需要使用HttpClient的包
    MultipartFile multipartFile = new MockMultipartFile("copy"+file.getName(),file.getName(),ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
    System.out.println(multipartFile.getName()); // 输出copytest.txt
}
5.2.2 使用CommonsMultipartFile

导入依赖包

<dependency>
	<groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;


public class Test {
    
   
    public static MultipartFile getMultipartFile(File file) {
    
        //如果传输有点问题可能传输的类型有点不同,可以试下更改为MediaType.TEXT_PLAIN_VALUE
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
    
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
    
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }

        return new CommonsMultipartFile(item);
    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43842093/article/details/131140647

智能推荐

Node.js毕业设计家用电器电商网站(Express+源码+调试)_关于家电网站的选题背景和意义-程序员宅基地

文章浏览阅读729次,点赞26次,收藏17次。本毕业设计旨在利用前端技术HTML、CSS、JavaScript和Vue框架,结合后端技术Node.js和Express框架,以及MySQL 5.7数据库,通过VSCode和Navicat开发工具,实现一个功能完善、操作简便的家用电器电商网站。此外,通过本毕业设计的实践,可以锻炼学生的实际操作能力,提高学生的编程水平,为学生今后的职业生涯打下坚实的基础。HBuilder X是一个专为前端开发者设计的IDE,支持HTML、CSS、JavaScript等前端技术,以及Vue.js框架。_关于家电网站的选题背景和意义

ESXi+docker_esxi docker-程序员宅基地

文章浏览阅读1.3w次。文章目录ESXi安装1、ESXi安装:2、重启后的配置:Docker环境部署1、创建虚拟机2、安装完之后,连上xshell,安装docker3、配置容器镜像4、从容器里拉取资源Docker部署Tomcat发布测试1、从容器里拉取资源tomcat2、新建数据库插入数据3、新建maven工程,webapp4、写ssm读数据库5、打war包5、上传到容器里ESXi安装1、ESXi安装:基本上都是下一步,就不做过多介绍了自定义硬件为iso镜像的路径,然后就完成了,重启2、重启后的配置:_esxi docker

ArcGIS RunTime概述_arcgis runtime qt 删除点-程序员宅基地

文章浏览阅读1w次,点赞3次,收藏9次。ArcGIS Runtime 是新一代的轻量级的桌面开发产品,它提供多种API,可以使用WPF,Java等开发环境快速的构建地图应用,并将应用程序部署在Microsoft Windows和Linux等通用平台上。ArcGIS Runtime支持在线和离线的资源调用模式,具有开发简单,部署快速,体验良好等特点,成为云GIS环境下一个不错的选择,将在云GIS环境下扮演重要角色。 ArcGIS_arcgis runtime qt 删除点

FFmpeg指定x265编码器线程数-程序员宅基地

文章浏览阅读4.7k次。转载请注明出处:http://cyc.wiki/index.php/2018/07/17/ffmpeg指定x265编码器线程数/FFmpeg的-threads参数FFmpeg调用编码器时,一般使用-threads参数对编码器使用的线程数进行设置。 比如:ffmpeg -s 1920x1080 -framerate 25 -i input.yuv -c:v libx264 -t..._ffmpeg指定x265编码器线程数

ubuntu查看网速的工具_ubuntu查看网口百兆千兆-程序员宅基地

文章浏览阅读3.4k次。1.工具一:slurm安装sudo apt-get install slurm (Ubuntu系统)查看网速命令slurm -i eth0 (etho为网卡名)*******************************************************************************************************xiabi_ubuntu查看网口百兆千兆

基于OpenCPU方案的BC26 NB模组开发总结-程序员宅基地

文章浏览阅读3.8k次,点赞3次,收藏30次。本文详细分析并介绍了基于opencpu方案开打bc26 NB模组的流程,主要分为开发工具套件的使用以及代码分析。_bc26

随便推点

Linux下的WEB服务器的搭建实战_linux搭建web服务器-程序员宅基地

文章浏览阅读1.9w次,点赞43次,收藏332次。Linux下的web服务器搭建详细过程每次搭建一个服务器之前,比如MySQL、DNS、WEB等首先要挂载磁盘目录文件挂载就是当要使用某个设备时(例如光盘或软盘),必须先将它们对应放到 Linux 系统中的某个目录上。其中对应的目录就叫作挂载点。只有经过操作之后,用户或程序才能访问到这些设备。这个操作过程就叫作文件系统的挂载。这里/dev/sr0是软盘,/mnt/cdrom是挂载点[root@wry139 ~]# mount /dev/sr0 /mnt/cdrom/mount: /dev/sr0 写保_linux搭建web服务器

SSM框架配置文件详解_ssm配置文件-程序员宅基地

文章浏览阅读4.8k次,点赞5次,收藏70次。SSM框架配置文件详解在SSM项目当中,所需要的配置文件总共有以下三个:①web.xml ②applicationContext.xml ③springmvc.xml以及两个properties文件jdbc.properties和log4j.properties1.web.xmlweb.xml是ssm项目当中最重要的一个配置文件,当服务启动时会首先加载web.xml这个文件,里面包括了对前端控制器、字符编码的配置案例:<?xml version="1.0" encoding_ssm配置文件

HTC Vive手柄圆盘控制角色移动_unity怎么用htc的手柄控制人物移动-程序员宅基地

文章浏览阅读6.9k次,点赞3次,收藏27次。这篇文章主要写的是通过手柄控制移动在场景中漫游。 在通过手柄控制移动时,我主要写了两个脚本一个ChildTransform.cs、Move.cs; 1、 ChildTransform这个脚本主要是为了获取头部Y轴方向的转动。以及头部在x、z轴方向的移动。将这个信息赋值给这个脚本绑定的对象身上。 2、 Move这个脚本主要是为了控制玩家的移动的,移动的方向是依据绑定ChildTransf_unity怎么用htc的手柄控制人物移动

centos7安装mysqlclient踩坑记录_mysqlclient.lib gcc-程序员宅基地

文章浏览阅读1.2k次。centos7安装mysqlclient踩坑记录服务器环境为centos7 使用Django3.1部署一个小项目 安装mysqlclient的过程中报错[root@guest download]# pip3.9 install mysqlclientCollecting mysqlclient Using cached mysqlclient-2.0.2.tar.gz (88 kB)Using legacy 'setup.py install' for mysqlclient, since pa_mysqlclient.lib gcc

spring-boot-admin-starter-client与spring-boot版本不匹配的坑_找不到 de.codecentric:spring-boot-admin-starter-serve-程序员宅基地

文章浏览阅读8.8k次。***************************APPLICATION FAILED TO START***************************Description:An attempt was made to call the method org.springframework.boot.web.client.RestTemplateBuilder.setConnectTimeout(Ljava/time/Duration;)Lorg/springframe..._找不到 de.codecentric:spring-boot-admin-starter-server:sources:2.5.2

遍历 ArrayList 时安全删除元素_java arraylist安全删除-程序员宅基地

文章浏览阅读258次。遍历 ArrayList 时安全删除元素_java arraylist安全删除

推荐文章

热门文章

相关标签