2016-06-16 14 views
6

Giao diện MultiPartResolver mặc định của Spring Boot xử lý việc tải lên các tệp nhiều phần bằng cách lưu chúng trên hệ thống tệp cục bộ. Trước khi phương thức điều khiển được nhập, toàn bộ tệp multipart phải hoàn tất việc tải lên máy chủ.Spring - Cách tải các tệp tải lên nhiều phần lớn lên cơ sở dữ liệu mà không lưu trữ trên hệ thống tệp cục bộ

Chúng tôi lưu trữ tất cả tệp được tải lên trực tiếp vào cơ sở dữ liệu và máy chủ của chúng tôi có dung lượng đĩa rất nhỏ, vì vậy nếu tệp lớn được tải lên, chúng tôi sẽ thấy IOExeption - Disk quota exceeded.

Có cách nào để nhận luồng trực tiếp từ yêu cầu gửi của khách hàng trước khi MultiPartResolver của Spring lưu trữ tệp trên hệ thống tệp cục bộ để chúng tôi có thể truyền trực tiếp tới db của chúng tôi không?

+0

cơ sở dữ liệu Những gì bạn đang sử dụng? – Songo

+0

Chúng tôi đang sử dụng AWS S3 – McLovin

Trả lời

5

Bạn có thể sử dụng apache trực tiếp, như được mô tả ở đây https://commons.apache.org/proper/commons-fileupload/streaming.html.

@Controller 
public class UploadController { 

    @RequestMapping("/upload") 
    public String upload(HttpServletRequest request) throws IOException, FileUploadException { 

     ServletFileUpload upload = new ServletFileUpload(); 

     FileItemIterator iterator = upload.getItemIterator(request); 
     while (iterator.hasNext()) { 
      FileItemStream item = iterator.next(); 

      if (!item.isFormField()) { 
       InputStream inputStream = item.openStream(); 
       //... 
      } 
     } 
    } 
} 

Đảm bảo tắt cơ chế giải quyết đa luồng lò xo.

application.yml:

spring: 
    http: 
     multipart: 
     enabled: false 
4

Thực ra nó không phải là nhiệm vụ tầm thường. Nếu bạn muốn viết luồng từ máy khách đến cơ sở dữ liệu, bạn phải xử lý yêu cầu theo cách thủ công. Có một số thư viện, có thể làm cho công việc này đơn giản hơn. Một trong số đó là "Apache Commons FileUpload". Dưới ví dụ rất đơn giản, làm thế nào bạn có thể xử lý yêu cầu multipart/form-data đến của thư viện này.

@Controller 
public class Controller{ 

    @RequestMapping("/upload") 
    public String upload(HttpServletRequest request){ 

     String boundary = extractBoundary(request); 

     try { 
      MultipartStream multipartStream = new MultipartStream(request.getInputStream(), 
       boundary.getBytes(), 1024, null); 
      boolean nextPart = multipartStream.skipPreamble(); 
      while(nextPart) { 
       String header = multipartStream.readHeaders(); 

       if(header.contains("filename")){ 
        //if input is file 
        OutputStream output = createDbOutputStream(); 
        multipartStream.readBodyData(output); 
        output.flush(); 
        output.close(); 
       } else { 
        //if input is not file (text, checkbox etc) 
        ByteArrayOutputStream output = new ByteArrayOutputStream(); 
        multipartStream.readBodyData(output); 
        String value = output.toString("utf-8"); 
        //... do something with extracted value 
       } 
       nextPart = multipartStream.readBoundary(); 
      } 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     }  
    } 

    private String extractBoundary(HttpServletRequest request) { 
     String boundaryHeader = "boundary="; 
     int i = request.getContentType().indexOf(boundaryHeader)+ 
      boundaryHeader.length(); 
     return request.getContentType().substring(i); 
    }  
} 

Tựa đề của lĩnh vực tập tin sẽ trông giống như:

Content-Disposition: form-data; name="fieldName"; filename="fileName.jpg" 
Content-Type: image/jpeg 

Tựa đề của lĩnh vực di chúc đơn giản trông giống như:

Content-Disposition: form-data; name="fieldName"; 

Lưu ý, rằng đoạn mã này chỉ được đơn giản hóa ví dụ cho thấy bạn hướng . Không có một số chi tiết như: trích xuất tên trường từ tiêu đề, tạo luồng đầu ra cơ sở dữ liệu, v.v. Bạn có thể tự mình triển khai tất cả các công cụ này. Ví dụ về các tiêu đề trường yêu cầu nhiều phần bạn có thể tìm thấy trong RFC1867. Thông tin về multipart/form-dataRFC2388.

+0

Tôi nhận được điều này chủ yếu là làm việc với tiêu đề '" Content-Type: multipart/form-data; ranh giới = ---- WebKitFormBoundary7MA4YWxkTrZu0gW "-F" filename = test "-F" file = @ myimage. jpg " – McLovin

Các vấn đề liên quan