SpringMVC如何实现文件上传下载功能,涉及哪些长尾关键词?

2026-04-19 06:441阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1331个文字,预计阅读时间需要6分钟。

SpringMVC如何实现文件上传下载功能,涉及哪些长尾关键词?

一、文件上传,首先,上传文件时HTTP请求的content-type为multipart/form-data,默认情况下,SpringMVC对这类类型报文的解析器为org.springframework.web.multipart.MultipartResolver类型的对象。MultipartResolver本身是一个上传文件解析器。

SpringMVC如何实现文件上传下载功能,涉及哪些长尾关键词?


一、文件上传

首先,http上传时候的content-type为multipart/form-data,默认情况下SpringMVC对该种类型报文的解析器为 org.springframework.web.multipart.MultipartResolver 类型的对象。MultipartResolver本身是个接口,其实现类为org.springframework.web.multipart.support.StandardServletMultipartResolver

需要说明的是,CommonsMultipartResolver从 Spring Framework 6.0 及其新的 Servlet 5.0+ 基线开始,基于 Apache Commons FileUpload 的过时版本不再可用

SpringMvc在初始化时会从IOC中获取名为”multipartResolver“类型为MultipartResolver类型的Bean作为multipartResolver。

在Springboot的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中对要使用的multipartResolver进行了配置,具备配置在org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration中,其配置如下

@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) @ConditionalOnMissingBean(MultipartResolver.class) public StandardServletMultipartResolver multipartResolver() { StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily()); return multipartResolver; }

可见其默认使用的就是StandardServletMultipartResolver。

我们可以通过配置来对文件大小,存储路径等进行设置,如下:

spring.servlet.multipart.enabled=true # servlet 接受到文件的时候,会先将其保存在一个临时目录 # 这个参数就可以指定这个目录的位置 spring.servlet.multipart.location= #允许上传的文件最大值,默认为-1,表示没有限制 spring.servlet.multipart.maxFileSize=-1 #针对 multipart/form-data 请求的最大数量,默认为-1,表示没有限制 spring.servlet.multipart.maxRequestSize=-1 #文件大小超过这个值的会被写入磁盘,默认值为 0,都会写入磁盘, #小于这个值的会被写在内存中。单位:byte spring.servlet.multipart.fileSizeThreshold=0

StandardServletMultipartResolver作用就是从HttpServletRequest中获取Part,然后对其进行封装成MultipartFile对象

方式1:原生方式上传

@MultipartConfig( location="", maxFileSize=-1, maxRequestSize=-1, fileSizeThreshold=50*1024*1024 ) @WebServlet("/upload") public class UploadServlet extends HttpServlet { public void upload(HttpServletRequest request){ //方式1:读取指定参数的单个文件 Part part = request.getPart("file1"); //方式2:获取请求中所有参数的文件集合 Collection parts = req.getParts(); //获取文件名 String fileName = part.getSubmittedFileName(); //读取文件内容并写入文件 part.write(realPath + "/" + fileName); //删除临时文件 part.delete(); } }


方式2:SpringMvc中上传

@RestController @RequestMapping("/upload") public class UploadController { /** * 说明:这里用了注解@RequestPart,除此以外@RequestParam也是可用的。 * @RequestPart注解解析的是multipart/form-data表单中的数据, * 可以支持文件参数 如MultipartFile * @RequestParam 能解析请求格式为‘application/json’的数据 , * 同样也支持‘multipart/form-data’ * * 1、当请求的contentType为“multipart/form-data”的时候@RequestParam 只能解析出String类型的 key-value的这种数据而@RquestPart可以接收 复杂的请求域如:json,xml,字节 * 2、@RequstParam依赖 Converter or PropertyEditor对数据进行解析, @RequestPart参考‘contentType’依赖HttpMessageConverts对数据 进行解析 */ @PostMapping("/file1") public void upload1(@RequestPart MultipartFile file){ //destFile为目标文件,即将上传的文件写到destFile中 file.transferTo(destFile); } @PostMapping("/file2") public void upload2(@RequestPart("param1") MultipartFile file){ } @PostMapping("/file3") public void upload3(@RequestPart("param1") MultipartFile file1, @RequestPart("param2") MultipartFile file2){ } @PostMapping("/file4") public void upload4(MultipartFile[] fils) {} @PostMapping("/file5") public void upload5(MultipartHttpServletRequest request) { //1.获取表单中非文件数据 Map parameterMap = request.getParameterMap(); //2、获取表单中文件数据 MultiValueMap multiFileMap = request.getMultiFileMap(); } }


二、文件下载

方法1:使用HttpServletResponse

@RestController @RequestMapping("/download") @Tag(name = "文件下载示例") public class DownloadController { @Operation(summary = "访问我下载文件了") @GetMapping("/v1") public void download1 (HttpServletResponse response) { //1. 接受文件名,读取磁盘对应的文件,创建输入流对象 FileInputStream inputStream = new FileInputStream("C:/"+fileName); //2.获取响应对象的输出流 ServletOutputStream outputStream = response.getOutputStream(); //3.文件下载文件名的编码使用ISO-08859-1编码 //我们需要将我们UTF-8的 filename转换ISO-8859-1编码 //3.1先将字符串以UTF-8转换成字节数组 byte[] bytes = fileName.getBytes("UTF-8"); //3.2再将字节数组以 ISO-8859-1转换字符串 fileName = new String(bytes, "ISO-8859-1"); //4.响应的内容应该是以附件的形式响应给浏览器(设置响应头) response.setHeader("Content-Disposition", "attachment;filename="+fileName); //5.响应文件给浏览器 IOUtils.copy(inputStream, outputStream); //6.关闭流 inputStream.close(); outputStream.close(); } }


方法2:使用ResponseEntity

@RestController @RequestMapping("/download") @Tag(name = "文件下载示例") public class DownloadController { @Operation(summary = "访问我下载文件了") @GetMapping("/v1") public ResponseEntity<Resource> download1 () { //要下载的文件路径 Path path = Paths.get(".......") ; Resource resource = new InputStreamResource(Files.newInputStream(path)); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileInfo.getOriginalName(), "UTF-8")); return ResponseEntity.ok() .headers(headers) .contentLength(Files.size(path)) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource) ; } @Operation(summary = "访问我下导出excel文件了") @GetMapping("/v2") public ResponseEntity<Resource> download2 () { //查询数据库得到的数据 TODO List<DataEntity> dataList = null ; if(dataList == null){ dataList = new ArrayList<>() ; } //输出excel格式数据(这里使用了EasyExcel组件) ByteArrayOutputStream outputStream = new ByteArrayOutputStream() ; EasyExcel.write(outputStream, DataEntity.class) .sheet("数据") .doWrite(dataList); /* 多个sheet输出: ByteArrayOutputStream outputStream = new ByteArrayOutputStream() ; ExcelWriter excelWriter = EasyExcel.write(outputStream).build() ; try{ // 写出sheet数据 doWriteSheet(excelWriter,"我是sheet1",XXXDto.class,xxxDtoList); doWriteSheet(excelWriter,"我是sheet2",YYYDto.class,yyyDtoList); }finally { // 关流 excelWriter.finish(); } */ String fileName = "下载文件.xlsx" ; //字节数 long contentLength = outputStream.size() ; //进行数据的写出 Resource resource = new ByteArrayResource(outputStream.toByteArray()) ; HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); return ResponseEntity.ok() .headers(headers) .contentLength(contentLength) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource) ; } private void doWriteSheet(ExcelWriter excelWriter,String sheetName,Class<?> clazz,List data){ // 构建sheet对象 WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).head(clazz).build(); // 写出sheet数据 excelWriter.write(data, writeSheet); } }


本文共计1331个文字,预计阅读时间需要6分钟。

SpringMVC如何实现文件上传下载功能,涉及哪些长尾关键词?

一、文件上传,首先,上传文件时HTTP请求的content-type为multipart/form-data,默认情况下,SpringMVC对这类类型报文的解析器为org.springframework.web.multipart.MultipartResolver类型的对象。MultipartResolver本身是一个上传文件解析器。

SpringMVC如何实现文件上传下载功能,涉及哪些长尾关键词?


一、文件上传

首先,http上传时候的content-type为multipart/form-data,默认情况下SpringMVC对该种类型报文的解析器为 org.springframework.web.multipart.MultipartResolver 类型的对象。MultipartResolver本身是个接口,其实现类为org.springframework.web.multipart.support.StandardServletMultipartResolver

需要说明的是,CommonsMultipartResolver从 Spring Framework 6.0 及其新的 Servlet 5.0+ 基线开始,基于 Apache Commons FileUpload 的过时版本不再可用

SpringMvc在初始化时会从IOC中获取名为”multipartResolver“类型为MultipartResolver类型的Bean作为multipartResolver。

在Springboot的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中对要使用的multipartResolver进行了配置,具备配置在org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration中,其配置如下

@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) @ConditionalOnMissingBean(MultipartResolver.class) public StandardServletMultipartResolver multipartResolver() { StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily()); return multipartResolver; }

可见其默认使用的就是StandardServletMultipartResolver。

我们可以通过配置来对文件大小,存储路径等进行设置,如下:

spring.servlet.multipart.enabled=true # servlet 接受到文件的时候,会先将其保存在一个临时目录 # 这个参数就可以指定这个目录的位置 spring.servlet.multipart.location= #允许上传的文件最大值,默认为-1,表示没有限制 spring.servlet.multipart.maxFileSize=-1 #针对 multipart/form-data 请求的最大数量,默认为-1,表示没有限制 spring.servlet.multipart.maxRequestSize=-1 #文件大小超过这个值的会被写入磁盘,默认值为 0,都会写入磁盘, #小于这个值的会被写在内存中。单位:byte spring.servlet.multipart.fileSizeThreshold=0

StandardServletMultipartResolver作用就是从HttpServletRequest中获取Part,然后对其进行封装成MultipartFile对象

方式1:原生方式上传

@MultipartConfig( location="", maxFileSize=-1, maxRequestSize=-1, fileSizeThreshold=50*1024*1024 ) @WebServlet("/upload") public class UploadServlet extends HttpServlet { public void upload(HttpServletRequest request){ //方式1:读取指定参数的单个文件 Part part = request.getPart("file1"); //方式2:获取请求中所有参数的文件集合 Collection parts = req.getParts(); //获取文件名 String fileName = part.getSubmittedFileName(); //读取文件内容并写入文件 part.write(realPath + "/" + fileName); //删除临时文件 part.delete(); } }


方式2:SpringMvc中上传

@RestController @RequestMapping("/upload") public class UploadController { /** * 说明:这里用了注解@RequestPart,除此以外@RequestParam也是可用的。 * @RequestPart注解解析的是multipart/form-data表单中的数据, * 可以支持文件参数 如MultipartFile * @RequestParam 能解析请求格式为‘application/json’的数据 , * 同样也支持‘multipart/form-data’ * * 1、当请求的contentType为“multipart/form-data”的时候@RequestParam 只能解析出String类型的 key-value的这种数据而@RquestPart可以接收 复杂的请求域如:json,xml,字节 * 2、@RequstParam依赖 Converter or PropertyEditor对数据进行解析, @RequestPart参考‘contentType’依赖HttpMessageConverts对数据 进行解析 */ @PostMapping("/file1") public void upload1(@RequestPart MultipartFile file){ //destFile为目标文件,即将上传的文件写到destFile中 file.transferTo(destFile); } @PostMapping("/file2") public void upload2(@RequestPart("param1") MultipartFile file){ } @PostMapping("/file3") public void upload3(@RequestPart("param1") MultipartFile file1, @RequestPart("param2") MultipartFile file2){ } @PostMapping("/file4") public void upload4(MultipartFile[] fils) {} @PostMapping("/file5") public void upload5(MultipartHttpServletRequest request) { //1.获取表单中非文件数据 Map parameterMap = request.getParameterMap(); //2、获取表单中文件数据 MultiValueMap multiFileMap = request.getMultiFileMap(); } }


二、文件下载

方法1:使用HttpServletResponse

@RestController @RequestMapping("/download") @Tag(name = "文件下载示例") public class DownloadController { @Operation(summary = "访问我下载文件了") @GetMapping("/v1") public void download1 (HttpServletResponse response) { //1. 接受文件名,读取磁盘对应的文件,创建输入流对象 FileInputStream inputStream = new FileInputStream("C:/"+fileName); //2.获取响应对象的输出流 ServletOutputStream outputStream = response.getOutputStream(); //3.文件下载文件名的编码使用ISO-08859-1编码 //我们需要将我们UTF-8的 filename转换ISO-8859-1编码 //3.1先将字符串以UTF-8转换成字节数组 byte[] bytes = fileName.getBytes("UTF-8"); //3.2再将字节数组以 ISO-8859-1转换字符串 fileName = new String(bytes, "ISO-8859-1"); //4.响应的内容应该是以附件的形式响应给浏览器(设置响应头) response.setHeader("Content-Disposition", "attachment;filename="+fileName); //5.响应文件给浏览器 IOUtils.copy(inputStream, outputStream); //6.关闭流 inputStream.close(); outputStream.close(); } }


方法2:使用ResponseEntity

@RestController @RequestMapping("/download") @Tag(name = "文件下载示例") public class DownloadController { @Operation(summary = "访问我下载文件了") @GetMapping("/v1") public ResponseEntity<Resource> download1 () { //要下载的文件路径 Path path = Paths.get(".......") ; Resource resource = new InputStreamResource(Files.newInputStream(path)); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileInfo.getOriginalName(), "UTF-8")); return ResponseEntity.ok() .headers(headers) .contentLength(Files.size(path)) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource) ; } @Operation(summary = "访问我下导出excel文件了") @GetMapping("/v2") public ResponseEntity<Resource> download2 () { //查询数据库得到的数据 TODO List<DataEntity> dataList = null ; if(dataList == null){ dataList = new ArrayList<>() ; } //输出excel格式数据(这里使用了EasyExcel组件) ByteArrayOutputStream outputStream = new ByteArrayOutputStream() ; EasyExcel.write(outputStream, DataEntity.class) .sheet("数据") .doWrite(dataList); /* 多个sheet输出: ByteArrayOutputStream outputStream = new ByteArrayOutputStream() ; ExcelWriter excelWriter = EasyExcel.write(outputStream).build() ; try{ // 写出sheet数据 doWriteSheet(excelWriter,"我是sheet1",XXXDto.class,xxxDtoList); doWriteSheet(excelWriter,"我是sheet2",YYYDto.class,yyyDtoList); }finally { // 关流 excelWriter.finish(); } */ String fileName = "下载文件.xlsx" ; //字节数 long contentLength = outputStream.size() ; //进行数据的写出 Resource resource = new ByteArrayResource(outputStream.toByteArray()) ; HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); return ResponseEntity.ok() .headers(headers) .contentLength(contentLength) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource) ; } private void doWriteSheet(ExcelWriter excelWriter,String sheetName,Class<?> clazz,List data){ // 构建sheet对象 WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).head(clazz).build(); // 写出sheet数据 excelWriter.write(data, writeSheet); } }