当前位置:   article > 正文

springboot使用MultipartFile上传文件以及File与MultipartFile互转_springboot multipartfile

springboot multipartfile

    如下所示的代码,是一个在springboot项目中使用MultipartFile进行文件上传的示例:

  1. package com.springboot.web;
  2. import org.springframework.http.ResponseEntity;
  3. import org.springframework.web.bind.annotation.PostMapping;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import org.springframework.web.multipart.MultipartFile;
  7. import java.io.File;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. @RestController
  11. @RequestMapping("/test")
  12. public class UploadController {
  13. private String path = "d:/temp";
  14. @PostMapping("/upload")
  15. public ResponseEntity upload(MultipartFile file) {
  16. Map<String,Object> res = new HashMap<>();
  17. try {
  18. File outFile = new File(path.concat(File.separator).concat(file.getOriginalFilename()));
  19. file.transferTo(outFile);
  20. res.put("url",outFile.getAbsolutePath());
  21. res.put("code",200);
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. res.put("msg","upload fail");
  25. res.put("code",500);
  26. }
  27. return ResponseEntity.ok(res);
  28. }
  29. }

    我们在前端页面上,进行配置上传的时候,可以使用这样的form:

  1. <form action="/test/upload" method="post" enctype="multipart/form-data">
  2. <input type="file" name="file"/>
  3. <input type="submit" value="upload"/>
  4. </form>

    这里需要注意的是,前端的元素<input type="file" name="file"/>这里的name属性,它要和后端接口里面MultipartFile file参数名字对应起来。否则,接口会报空指针异常。

    现在web一般流行的是异步上传,所以使用三方javascript框架的时候,也需要注意,这里代表file的属性名一定要指定为file,与接口中参数file名字对应起来。

    到这里,使用MultipartFile上传文件基本就完成了,但是,我们这种接口有一个问题,如果我们使用三方服务来调用这个接口,那么这个参数MultipartFile还不好传递,因为这个类型是一个接口类型

  1. public interface MultipartFile extends InputStreamSource {
  2. String getName();
  3. @Nullable
  4. String getOriginalFilename();
  5. @Nullable
  6. String getContentType();
  7. boolean isEmpty();
  8. long getSize();
  9. byte[] getBytes() throws IOException;
  10. InputStream getInputStream() throws IOException;
  11. default Resource getResource() {
  12. return new MultipartFileResource(this);
  13. }
  14. void transferTo(File dest) throws IOException, IllegalStateException;
  15. default void transferTo(Path dest) throws IOException, IllegalStateException {
  16. FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
  17. }
  18. }

    如果java后端来写这个接口调用,我们本地的文件File有的是,问题是怎么把这个File转为MultipartFile,有一种办法就是借助spring-test依赖下的MockMultipartFile类型,代码如下所示:

  1. package com.springboot.web;
  2. import org.junit.Before;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. import org.springframework.mock.web.MockMultipartFile;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import org.springframework.test.web.servlet.MockMvc;
  10. import org.springframework.test.web.servlet.MvcResult;
  11. import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
  12. import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
  13. import org.springframework.test.web.servlet.setup.MockMvcBuilders;
  14. import org.springframework.web.context.WebApplicationContext;
  15. import java.io.File;
  16. import java.io.FileInputStream;
  17. @SpringBootTest
  18. @RunWith(SpringRunner.class)
  19. public class UploadControllerTest {
  20. private MockMvc mockMvc;
  21. @Autowired
  22. private WebApplicationContext webApplicationContext;
  23. @Before
  24. public void setup() {
  25. mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
  26. }
  27. @Test
  28. public void upload() {
  29. FileInputStream inputStream = null;
  30. File file = new File("c:\\users\\buejee\\pictures\\avatar.png");
  31. try {
  32. inputStream = new FileInputStream(file);
  33. MockMultipartFile multipartFile = new MockMultipartFile(
  34. "file",
  35. file.getName(),
  36. "APPLICATION_OCTET_STREAM",
  37. inputStream);
  38. MvcResult result = mockMvc.perform(
  39. MockMvcRequestBuilders
  40. .fileUpload("/test/upload")
  41. .file(multipartFile))
  42. .andExpect(MockMvcResultMatchers.status().isOk())
  43. .andReturn();
  44. String response = result.getResponse().getContentAsString();
  45. System.out.println(response);
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. }

    这里的核心代码就是这几行:

  1. FileInputStream inputStream = null;
  2. File file = new File("c:\\users\\buejee\\pictures\\avatar.png");
  3. inputStream = new FileInputStream(file);
  4. MockMultipartFile multipartFile = new MockMultipartFile(
  5. "file",
  6. file.getName(),
  7. "APPLICATION_OCTET_STREAM",
  8. inputStream);

    在构造MockMultipartFile的时候,我们传入的第一个参数就是file,这个还是上面说的,需要和接口中MultipartFile file参数的名称对应起来。

    如果不想使用spring-test依赖下的MockMultipartFile,那么就只能自定义一个MultipartFile的实现,其实实现过程完全可以参考MockMultipartFile:

  1. public class MockMultipartFile implements MultipartFile {
  2. private final String name;
  3. private final String originalFilename;
  4. @Nullable
  5. private final String contentType;
  6. private final byte[] content;
  7. public MockMultipartFile(String name, @Nullable byte[] content) {
  8. this(name, "", (String)null, (byte[])content);
  9. }
  10. public MockMultipartFile(String name, InputStream contentStream) throws IOException {
  11. this(name, "", (String)null, (byte[])FileCopyUtils.copyToByteArray(contentStream));
  12. }
  13. public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
  14. Assert.hasLength(name, "Name must not be empty");
  15. this.name = name;
  16. this.originalFilename = originalFilename != null ? originalFilename : "";
  17. this.contentType = contentType;
  18. this.content = content != null ? content : new byte[0];
  19. }
  20. public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException {
  21. this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
  22. }
  23. public String getName() {
  24. return this.name;
  25. }
  26. @NonNull
  27. public String getOriginalFilename() {
  28. return this.originalFilename;
  29. }
  30. @Nullable
  31. public String getContentType() {
  32. return this.contentType;
  33. }
  34. public boolean isEmpty() {
  35. return this.content.length == 0;
  36. }
  37. public long getSize() {
  38. return (long)this.content.length;
  39. }
  40. public byte[] getBytes() throws IOException {
  41. return this.content;
  42. }
  43. public InputStream getInputStream() throws IOException {
  44. return new ByteArrayInputStream(this.content);
  45. }
  46. public void transferTo(File dest) throws IOException, IllegalStateException {
  47. FileCopyUtils.copy(this.content, dest);
  48. }
  49. }

    构造出了MultipartFile实例,那么调用上传接口就方便了,在上面给出的上传接口UploadController.upload(MultipartFile file)中,其实隐含了一个操作,就是MultipartFile转File,直接借助MultipartFile.transferTo()就可以写为File类型了,最后我们返回File就可以。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/895664
推荐阅读
相关标签
  

闽ICP备14008679号