java如何导出附件
导出附件的方法
使用Java导出附件通常涉及从服务器或数据库读取文件数据,并通过HTTP响应将文件发送给客户端。以下是几种常见的方法。
使用Servlet导出附件
通过Servlet实现文件下载是最常见的方式。需要设置响应头信息,指定内容类型和附件名称。
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filePath = "/path/to/file.pdf";
File file = new File(filePath);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
try (InputStream in = new FileInputStream(file);
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
}
}
使用Spring Boot导出附件
在Spring Boot中,可以通过ResponseEntity和Resource实现文件下载。
@RestController
@RequestMapping("/api")
public class FileDownloadController {
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile() throws IOException {
Path filePath = Paths.get("/path/to/file.pdf");
Resource resource = new UrlResource(filePath.toUri());
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
导出数据库中的附件
如果附件存储在数据库中,通常以BLOB或LONGBLOB形式存在,可以通过JDBC读取并写入响应流。
@WebServlet("/downloadFromDB")
public class DatabaseDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileId = request.getParameter("fileId");
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "password");
PreparedStatement stmt = conn.prepareStatement("SELECT file_name, file_content FROM attachments WHERE id = ?")) {
stmt.setString(1, fileId);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
String fileName = rs.getString("file_name");
Blob blob = rs.getBlob("file_content");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
try (InputStream in = blob.getBinaryStream();
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
}
} catch (SQLException e) {
throw new ServletException("Database error", e);
}
}
}
处理大文件导出
对于大文件,建议使用分块传输或异步处理,避免内存溢出。

@GetMapping("/downloadLargeFile")
public void downloadLargeFile(HttpServletResponse response) throws IOException {
Path filePath = Paths.get("/path/to/largefile.zip");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filePath.getFileName() + "\"");
try (InputStream in = Files.newInputStream(filePath);
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
}
注意事项
- 确保文件路径或数据库查询参数经过验证,防止路径遍历攻击。
- 设置合适的缓存控制头,避免浏览器缓存敏感文件。
- 对于大文件,考虑使用
Range请求支持断点续传。






