springboot使用MultipartFile上传文件以及File与MultipartFile互转
Posted luffy5459
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot使用MultipartFile上传文件以及File与MultipartFile互转相关的知识,希望对你有一定的参考价值。
如下所示的代码,是一个在springboot项目中使用MultipartFile进行文件上传的示例:
package com.springboot.web;
import org.springframework.http.ResponseEntity;
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.File;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/test")
public class UploadController
private String path = "d:/temp";
@PostMapping("/upload")
public ResponseEntity upload(MultipartFile file)
Map<String,Object> res = new HashMap<>();
try
File outFile = new File(path.concat(File.separator).concat(file.getOriginalFilename()));
file.transferTo(outFile);
res.put("url",outFile.getAbsolutePath());
res.put("code",200);
catch (Exception e)
e.printStackTrace();
res.put("msg","upload fail");
res.put("code",500);
return ResponseEntity.ok(res);
我们在前端页面上,进行配置上传的时候,可以使用这样的form:
<form action="/test/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="upload"/>
</form>
这里需要注意的是,前端的元素<input type="file" name="file"/>这里的name属性,它要和后端接口里面MultipartFile file参数名字对应起来。否则,接口会报空指针异常。
现在web一般流行的是异步上传,所以使用三方javascript框架的时候,也需要注意,这里代表file的属性名一定要指定为file,与接口中参数file名字对应起来。
到这里,使用MultipartFile上传文件基本就完成了,但是,我们这种接口有一个问题,如果我们使用三方服务来调用这个接口,那么这个参数MultipartFile还不好传递,因为这个类型是一个接口类型:
public interface MultipartFile extends InputStreamSource
String getName();
@Nullable
String getOriginalFilename();
@Nullable
String getContentType();
boolean isEmpty();
long getSize();
byte[] getBytes() throws IOException;
InputStream getInputStream() throws IOException;
default Resource getResource()
return new MultipartFileResource(this);
void transferTo(File dest) throws IOException, IllegalStateException;
default void transferTo(Path dest) throws IOException, IllegalStateException
FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
如果java后端来写这个接口调用,我们本地的文件File有的是,问题是怎么把这个File转为MultipartFile,有一种办法就是借助spring-test依赖下的MockMultipartFile类型,代码如下所示:
package com.springboot.web;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.io.File;
import java.io.FileInputStream;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UploadControllerTest
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setup()
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
@Test
public void upload()
FileInputStream inputStream = null;
File file = new File("c:\\\\users\\\\buejee\\\\pictures\\\\avatar.png");
try
inputStream = new FileInputStream(file);
MockMultipartFile multipartFile = new MockMultipartFile(
"file",
file.getName(),
"APPLICATION_OCTET_STREAM",
inputStream);
MvcResult result = mockMvc.perform(
MockMvcRequestBuilders
.fileUpload("/test/upload")
.file(multipartFile))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
String response = result.getResponse().getContentAsString();
System.out.println(response);
catch (Exception e)
e.printStackTrace();
这里的核心代码就是这几行:
FileInputStream inputStream = null;
File file = new File("c:\\\\users\\\\buejee\\\\pictures\\\\avatar.png");
inputStream = new FileInputStream(file);
MockMultipartFile multipartFile = new MockMultipartFile(
"file",
file.getName(),
"APPLICATION_OCTET_STREAM",
inputStream);
在构造MockMultipartFile的时候,我们传入的第一个参数就是file,这个还是上面说的,需要和接口中MultipartFile file参数的名称对应起来。
如果不想使用spring-test依赖下的MockMultipartFile,那么就只能自定义一个MultipartFile的实现,其实实现过程完全可以参考MockMultipartFile:
public class MockMultipartFile implements MultipartFile
private final String name;
private final String originalFilename;
@Nullable
private final String contentType;
private final byte[] content;
public MockMultipartFile(String name, @Nullable byte[] content)
this(name, "", (String)null, (byte[])content);
public MockMultipartFile(String name, InputStream contentStream) throws IOException
this(name, "", (String)null, (byte[])FileCopyUtils.copyToByteArray(contentStream));
public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content)
Assert.hasLength(name, "Name must not be empty");
this.name = name;
this.originalFilename = originalFilename != null ? originalFilename : "";
this.contentType = contentType;
this.content = content != null ? content : new byte[0];
public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
public String getName()
return this.name;
@NonNull
public String getOriginalFilename()
return this.originalFilename;
@Nullable
public String getContentType()
return this.contentType;
public boolean isEmpty()
return this.content.length == 0;
public long getSize()
return (long)this.content.length;
public byte[] getBytes() throws IOException
return this.content;
public InputStream getInputStream() throws IOException
return new ByteArrayInputStream(this.content);
public void transferTo(File dest) throws IOException, IllegalStateException
FileCopyUtils.copy(this.content, dest);
构造出了MultipartFile实例,那么调用上传接口就方便了,在上面给出的上传接口UploadController.upload(MultipartFile file)中,其实隐含了一个操作,就是MultipartFile转File,直接借助MultipartFile.transferTo()就可以写为File类型了,最后我们返回File就可以。
以上是关于springboot使用MultipartFile上传文件以及File与MultipartFile互转的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
Springboot读取Resource资源文件并转化为MultipartFile和File
SpringBoot 2.x版本+MultipartFile设置指定文件上传大小
当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空