2013-07-29 48 views
7

Tôi có một ứng dụng web. Tôi đang sử dụng java và spring. Ứng dụng có thể tạo một tập tin và gửi nó đến trình duyệt, điều này hoạt động tốt. Cách tôi làm là:Cách xóa tệp sau khi gửi tệp trong ứng dụng web?

Tôi tạo tệp trong lớp Dịch vụ và phương thức trả về địa chỉ cho bộ điều khiển. Bộ điều khiển sau đó gửi tệp và tệp được tải xuống chính xác. Mã cho phương thức điều khiển là cái này.

@RequestMapping("/getFile") 
public @ResponseBody 
FileSystemResource getFile() { 

    String address = Services.createFile(); 
    response.setContentType("application/vnd.ms-excel"); 
    return new FileSystemResource(new File (address)); 
} 

Sự cố là tệp được lưu trong máy chủ và sau nhiều yêu cầu, tệp sẽ được lưu trữ nhiều tệp. Tôi phải xóa chúng bằng tay. Câu hỏi đặt ra là: Làm cách nào để xóa tệp này sau khi gửi? hoặc Có cách nào để gửi tệp mà không lưu tệp trong máy chủ không?

Trả lời

13

Không sử dụng @ResponseBody. Để Xuân tiêm HttpServletResponse và viết trực tiếp vào OutputStream.

@RequestMapping("/getFile") 
public void getFile(HttpServletResponse response) { 
    String address = Services.createFile(); 
    File file = new File(address); 
    response.setContentType("application/vnd.ms-excel"); 
    response.setHeader("Content-disposition", "attachment; filename=" + file.getName()); 

    OutputStream out = response.getOutputStream(); 
    FileInputStream in = new FileInputStream(file); 

    // copy from in to out 
    IOUtils.copy(in,out); 

    out.close(); 
    in.close(); 
    file.delete(); 
} 

Tôi chưa thêm bất kỳ xử lý ngoại lệ nào. Tôi để điều đó cho bạn.

FileSystemResource thực sự chỉ là trình bao bọc cho FileInputStream được Spring sử dụng.

Hoặc, nếu bạn muốn trở thành hardcore, bạn có thể làm FileSystemResource thực hiện của riêng bạn với getOutputStream() phương pháp riêng của mình mà trở về thực hiện của riêng bạn FileOutputStream đó xóa các tập tin tiềm ẩn khi bạn gọi close() trên đó.

+0

cảm ơn. Làm thế nào để bạn sao chép từ trong ra ngoài? –

+0

Trong vòng lặp while, bạn đọc một byte [] từ trong và viết nó ra. Hãy tìm một hướng dẫn Java IO. –

+0

Tốt hơn không đóng luồng đầu ra phản hồi. – rec

2

Vì vậy, tôi quyết định lấy đề xuất của Sotirious cho một cách "hardcore". Nó khá đơn giản, nhưng có một vấn đề. Nếu người dùng của lớp đó mở luồng đầu vào một lần để kiểm tra thứ gì đó và đóng nó lại, nó sẽ không thể mở lại nó vì tệp bị xóa khi đóng. Mùa xuân dường như không làm điều đó, nhưng bạn sẽ cần phải kiểm tra sau mỗi lần nâng cấp phiên bản.

public class DeleteAfterReadeFileSystemResource extends FileSystemResource { 
    public DeleteAfterReadeFileSystemResource(File file) { 
     super(file); 
    } 

    @Override 
    public InputStream getInputStream() throws IOException { 
     return new DeleteOnCloseFileInputStream(super.getFile()); 
    } 

    private static final class DeleteOnCloseFileInputStream extends FileInputStream { 

     private File file; 
     DeleteOnCloseFileInputStream(File file) throws FileNotFoundException { 
      super(file); 
      this.file = file; 
     } 

     @Override 
     public void close() throws IOException { 
      super.close(); 
      file.delete(); 
     } 
    } 
}