1、文件下载
使用ResponseEntity实现下载文件的功能
💡 具体实现过程:
- 引入依赖:首先确保项目中引入了
javax.servlet-api
的4版本依赖。注意,为了避免潜在的版本冲突和错误,不应该引入其他版本的此依赖。 - 使用ResponseEntity:Spring框架提供的
ResponseEntity
类允许我们定义HTTP响应的各个方面,包括状态码、头部信息和响应体。这使得它特别适合用于实现文件下载功能。 - 设置响应头部:为了告诉浏览器响应是一个文件下载,需要设置适当的响应头部,如
Content-Disposition
。 - 获取文件:根据需求,从文件系统、数据库或其他地方获取要下载的文件。
- 构建响应:使用
ResponseEntity
构建响应,将文件内容作为响应体,并设置相应的状态码和头部信息。
💡 注意事项:
- 确保已正确配置项目,并且已经引入了
javax.servlet-api
的4版本依赖。 - 根据业务需求,调整文件路径和文件名。
- 对于大文件,考虑使用流式传输,而不是一次性读取整个文件到内存中。
- 捕获并处理可能出现的异常,例如文件不存在或没有读取权限等。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@RestController
public class FileController {
@GetMapping("/download")
public ResponseEntity download(HttpServletRequest request) throws IOException {
ServletContext servletContext = request.getServletContext();
String realPath = servletContext.getRealPath("456.jpg");
FileInputStream fileInputStream = new FileInputStream(realPath);
byte[] bytes = new byte[fileInputStream.available()];
fileInputStream.read(bytes);
return ResponseEntity
.status(HttpStatus.OK)
.header("Content-Disposition", "attachment;filename=test.jpg")
.body(bytes);
}
}
这段代码是一个基于Spring框架的简单的文件下载控制器。下面是对每一部分的解释:
-
@RestController
是一个Spring MVC的注解,用于标注该类为RESTful Web服务的控制器。这意味着返回的数据会自动转换为JSON或其他的HTTP Response Body内容类型。 -
public class FileController {
定义了一个名为FileController
的类。 -
public ResponseEntity download(HttpServletRequest request) throws IOException {
定义了一个名为download
的方法,该方法接收一个HttpServletRequest
对象,并抛出一个可能的IOException
。 -
ServletContext servletContext = request.getServletContext();
从HTTP请求中获取ServletContext
对象,这个对象提供了有关servlet上下文的信息。 -
String realPath = servletContext.getRealPath("456.jpg");
获取在servlet上下文中名为"456.jpg"的文件的真实路径。 -
FileInputStream fileInputStream = new FileInputStream(realPath);
使用得到的真实路径来创建一个FileInputStream
,准备读取文件。 -
byte[] bytes = new byte[fileInputStream.available()];
创建一个字节数组,大小是文件可用的字节数。 -
fileInputStream.read(bytes);
读取文件内容到前面创建的字节数组中。 -
return ResponseEntity
…
返回一个ResponseEntity
对象,这是Spring提供的一个类,用于构建HTTP响应。这里设置了HTTP状态为200(OK),并设置了一个名为"Content-Disposition"的HTTP头,其值为"attachment;filename=test.jpg",表示这是一个附件下载,文件名为"test.jpg"。响应体是文件的内容(字节数组)。
总结: 这个方法允许用户下载一个名为"456.jpg"的文件,但当用户下载时,文件名会显示为"test.jpg"。
2、文件上传
在进行文件上传时,务必确保前端form表单的请求方式为post,并添加属性enctype="multipart/form-data"
。需要特别注意的是,前端form表单中的button按钮会默认按照get方式提交,这不会受到form上的method属性的影响。因此,为了避免潜在的错误和混淆,建议不要在form表单中使用button按钮进行提交,而是使用input type submit来进行文件的提交操作。
在SpringMVC的框架中,上传的文件会被自动封装到MultipartFile对象中,这个对象提供了获取文件相关信息的便捷方式,如文件名、文件大小等。在处理文件上传的过程中,这个对象扮演着重要的角色。
对于具体的上传步骤,首先需要在前端构建符合要求的form表单,然后在后端通过SpringMVC来处理上传的文件。值得注意的是,在使用SpringMVC 5.3版本进行处理时,可以直接获取到上传文件的后缀名,这为文件处理提供了更多的便利性。
- 添加依赖:
commons-fileupload commons-fileupload 1.3.1
- 在SpringMVC的配置文件中添加配置:
multipartResolver
这个配置的bean的id必须是这个名字,大小写也要完全一致
这个bean的id必须叫做multipartResolver
, 类的名字是CommonsMultipartResolver
<!-- 添加文件上传的bean对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
3. 控制器方法:
/**
* 文件上传
* @return
*/
@PostMapping("/file")
public ResponseEntity uploadFile(MultipartFile upFile, HttpServletRequest request) throws IOException {
String originalFilename = upFile.getOriginalFilename();
System.out.println("originalFilename = " + originalFilename);
InputStream inputStream = upFile.getInputStream();
ServletContext servletContext = request.getServletContext();
//必须要关联一个已存在的文件或者文件夹
String realPath = servletContext.getRealPath("/image");
realPath += ("/" + originalFilename);
FileOutputStream fileOutputStream = new FileOutputStream(realPath);
IOUtils.copy(inputStream, fileOutputStream);
fileOutputStream.close();
return ResponseEntity.ok().build();
}
这段代码是一个基于Java的Spring框架用于上传文件的函数。下面是代码的逐行解释:
-
public ResponseEntity uploadFile(MultipartFile upFile, HttpServletRequest request) throws IOException {
定义了一个名为uploadFile
的公共方法,它接收两个参数:一个是MultipartFile
类型的upFile
(表示要上传的文件),另一个是HttpServletRequest
类型的request
(表示HTTP请求)。这个方法声明了抛出IOException
。 -
String originalFilename = upFile.getOriginalFilename();
获取上传文件的原始文件名,并将其存储在originalFilename
字符串变量中。 -
InputStream inputStream = upFile.getInputStream();
获取上传文件的输入流,并将其存储在inputStream
变量中。 -
ServletContext servletContext = request.getServletContext();
从HTTP请求中获取ServletContext
对象,该对象提供了有关Web应用程序的上下文信息。 -
String realPath = servletContext.getRealPath("/image");
获取Web应用程序中/image
目录的实际文件系统路径,并将其存储在realPath
字符串变量中。 -
realPath += ("/" + originalFilename);
修改realPath
,以包括上传文件的原始文件名,从而指定文件将存储的完整路径。 -
FileOutputStream fileOutputStream = new FileOutputStream(realPath);
创建一个指向指定路径(realPath
)的文件输出流,以便将文件写入该文件系统位置。 -
IOUtils.copy(inputStream, fileOutputStream);
使用IOUtils.copy
方法,将文件从输入流复制到输出流。 -
fileOutputStream.close();
关闭文件输出流。这是一个重要的步骤,因为它确保所有缓冲的数据都被写入文件,并释放与流相关联的任何系统资源。 -
return ResponseEntity.ok().build();
返回一个HTTP 200(OK)响应,表示文件已成功上传。
通常,在生产环境中,应该包含适当的错误处理(例如,如果上传的文件名已经存在,或者文件未能成功复制)。