Java实现文件上传和下载的方法详解
文件上传
文件上传是通过HTTP协议中的POST方法进行实现的。在Java中,常见的实现方式有两种:
1. 使用Servlet API
Servlet API 提供了实现文件上传的类 javax.servlet.http.Part
。我们可以通过 request.getParts()
方法来获取所有上传的文件数据,然后进行处理。
@WebServlet("/upload")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
maxFileSize = 1024 * 1024 * 10, // 10MB
maxRequestSize = 1024 * 1024 * 50) // 50MB
public class FileUploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取上传的文件数据
Collection<Part> parts = request.getParts();
for (Part part : parts) {
String fileName = extractFileName(part);
InputStream partInputStream = part.getInputStream();
// 可以将文件数据写入到磁盘中
}
}
// 根据Part获取原始文件名
private String extractFileName(final Part part) {
final String partHeader = part.getHeader("content-disposition");
String[] parts = partHeader.split(";");
for (String partItem : parts) {
if (partItem.trim().startsWith("filename")) {
return partItem.substring(partItem.indexOf('=') + 1).trim()
.replace("\"", "");
}
}
return "";
}
}
上述代码中通过 request.getParts()
获取了所有上传的文件数据,然后遍历每个文件,从每个文件中获取文件名和数据流。可以将数据流写入到磁盘中,也可以将其存储到数据库。
需要注意的是,在实际应用中,我们应该对上传文件的类型、大小等进行限制和校验,避免上传恶意文件和文件过大导致磁盘空间不足等问题。示例中使用 @MultipartConfig
注解对文件大小和请求大小进行了限制。
2. 使用第三方库
在实际开发中,往往会使用一些第三方库来简化文件上传的实现。常见的库有 Apache Commons FileUpload 和 Spring Framework。
以 Apache Commons FileUpload 为例,代码如下:
public class FileUploadHandler extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String TEMP_DIRECTORY = "C:/temp";
private static final int MAX_UPLOAD_SIZE = 1024 * 1024 * 10; // 10MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
private static final int FILE_SIZE_THRESHOLD = 0;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(FILE_SIZE_THRESHOLD);
factory.setRepository(new File(TEMP_DIRECTORY));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_UPLOAD_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE);
try {
List<FileItem> items = upload.parseRequest(request);
if (items != null) {
for (FileItem item : items) {
if (!item.isFormField()) {
String fileName = item.getName();
InputStream is = item.getInputStream();
// 可以将文件数据写入到磁盘中或存储到数据库
}
}
}
} catch(FileUploadException e) {
// 处理文件上传异常
}
}
}
在上面的示例代码中,Apache Commons FileUpload 将文件上传的过程封装在了 ServletFileUpload
和 FileItem
类中,使得文件上传变得十分简便。需要注意的是,除了第一种方式中的检查之外,Apache Commons FileUpload 可以对上传的文件类型、大小等进行自动检查和处理。
文件下载
文件下载是通过向客户端发送 HTTP 响应实现的。在 Java 中,我们可以通过 Servlet API 中的 HttpServletResponse 类,设置文件下载时的 MIME 类型和文件名,然后将文件数据写入到 HTTP 响应的输出流中即可。
下面是一个简单的示例,展示如何实现文件下载:
public class ServletFileDownloadHandler extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filePath = request.getParameter("file");
File downloadFile = new File(filePath);
if (downloadFile.exists()) {
//设置文件类型
response.setContentType("application/octet-stream");
//设置Content-Disposition头以弹出文件下载对话框
response.setHeader("Content-Disposition", "attachment;filename=\"" + downloadFile.getName() + "\"");
byte[] buf = new byte[4096];
int len = -1;
try (InputStream is = new FileInputStream(downloadFile)) {
OutputStream os = response.getOutputStream();
while ((len = is.read(buf)) != -1) {
os.write(buf, 0, len);
}
os.flush();
} catch (IOException e) {
// 处理文件下载异常
}
} else {
response.getWriter().write("The file does not exist!");
}
}
}
在上面的示例中,Servlet 接收请求参数 file
,然后尝试读取该文件并将其写入 HTTP 响应的输出流中。需要注意的是,在实际应用中,我们应该对文件存在性进行校验,避免服务器内部错误和 XSS 等风险问题。
我们也可以使用第三方框架,如 Spring MVC 来实现复杂的文件下载,下面是一个示例:
@Controller
public class FileDownloadController {
@RequestMapping(value = "/download/{fileName:.+}", method = RequestMethod.GET)
public void downloadFile(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {
File downloadFile = new File("/path/to/file/" + fileName);
if (downloadFile.exists()) {
response.setContentType("application/octet-stream");
response.setContentLength((int) downloadFile.length());
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
try (InputStream is = new FileInputStream(downloadFile)) {
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
}
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
}
上面的示例中使用了 Spring MVC 的 @Controller
注解,灵活的请求路径和参数映射方式,以及更加简便的 IO 流处理方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现文件上传和下载的方法详解 - Python技术站