Spring dan Apache FileUpload

1. Ikhtisar

The Apache Commons Upload File Library membantu kita meng-upload file besar melalui protokol HTTP menggunakan multipart / form-data jenis konten.

Dalam tutorial singkat ini, kita akan melihat bagaimana mengintegrasikannya dengan Spring.

2. Ketergantungan Maven

Untuk menggunakan pustaka, kita membutuhkan artefak commons-fileupload :

 commons-fileupload commons-fileupload 1.3.3 

Versi terbaru dapat ditemukan di Maven Central.

3. Mentransfer Semua Sekaligus

Untuk tujuan demonstrasi, kami akan membuat permintaan pemrosesan Pengontrol dengan muatan file:

@PostMapping("/upload") public String handleUpload(HttpServletRequest request) throws Exception { boolean isMultipart = ServletFileUpload.isMultipartContent(request); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository( new File(System.getProperty("java.io.tmpdir"))); factory.setSizeThreshold( DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD); factory.setFileCleaningTracker(null); ServletFileUpload upload = new ServletFileUpload(factory); List items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); if (!item.isFormField()) { try ( InputStream uploadedStream = item.getInputStream(); OutputStream out = new FileOutputStream("file.mov");) { IOUtils.copy(uploadedStream, out); } } } return "success!"; } 

Pada awalnya, kita perlu memeriksa apakah permintaan berisi konten multi bagian menggunakan metode isMultipartContent yang ditemukan di kelas ServletFileUpload dari perpustakaan.

Secara default, Spring menampilkan MultipartResolver yang harus kami nonaktifkan untuk menggunakan pustaka ini. Jika tidak, itu akan membaca konten permintaan sebelum mencapai Pengontrol kami .

Kita dapat mencapai ini dengan memasukkan konfigurasi ini dalam file application.properties kita :

spring.http.multipart.enabled=false

Sekarang, kita dapat mengatur direktori tempat file kita akan disimpan, ambang batas di mana perpustakaan memutuskan untuk menulis ke disk dan jika file harus dihapus setelah permintaan berakhir.

Pustaka menyediakan kelas DiskFileItemFactory itumengambil tanggung jawab konfigurasi untuk menyimpan dan membersihkan file . The setRepository metode menetapkan target direktori, dengan default yang ditampilkan dalam contoh.

Selanjutnya, setSizeThreshold menetapkan ukuran file maksimum.

Kemudian, kami memiliki metode setFileCleaningTracker yang, jika disetel ke null, membiarkan file sementara tidak tersentuh. Secara default, ini menghapusnya setelah permintaan selesai .

Sekarang kita dapat melanjutkan ke penanganan file yang sebenarnya.

Pertama, kami membuat ServletFileUpload kami dengan memasukkan pabrik yang kami buat sebelumnya; kemudian kami melanjutkan untuk mengurai permintaan dan membuat daftar FileItem yang merupakan abstraksi utama pustaka untuk bidang formulir.

Sekarang jika kita tahu itu bukan bidang formulir normal, maka kita melanjutkan untuk mengekstrak InputStream dan memanggil metode salin yang berguna dari IOUtils (untuk lebih banyak opsi, Anda dapat melihat tutorial ini) .

Sekarang kami memiliki file kami yang disimpan di folder yang diperlukan. Ini biasanya cara yang lebih nyaman untuk menangani situasi ini karena memungkinkan akses mudah ke file, tetapi juga efisiensi waktu / memori tidak optimal.

Di bagian selanjutnya, kita akan melihat API streaming.

4. API Streaming

API streaming mudah digunakan, menjadikannya cara terbaik untuk memproses file besar hanya dengan tidak menyalin ke lokasi sementara:

ServletFileUpload upload = new ServletFileUpload(); FileItemIterator iterStream = upload.getItemIterator(request); while (iterStream.hasNext()) { FileItemStream item = iterStream.next(); String name = item.getFieldName(); InputStream stream = item.openStream(); if (!item.isFormField()) { // Process the InputStream } else { String formFieldValue = Streams.asString(stream); } } 

Kita dapat melihat di potongan kode sebelumnya bahwa kita tidak lagi menyertakan DiskFileItemFactory . Ini karena, saat menggunakan streaming API, kami tidak membutuhkannya .

Selanjutnya, untuk memproses bidang, pustaka menyediakan FileItemIterator , yang tidak membaca apa pun sampai kita mengekstraknya dari permintaan dengan metode selanjutnya .

Akhirnya, kita bisa melihat bagaimana mendapatkan nilai dari bidang formulir lainnya.

5. Kesimpulan

Pada artikel ini, kami telah meninjau bagaimana kami dapat menggunakan Perpustakaan Unggahan File Apache Commons dengan Spring untuk mengunggah dan memproses file besar.

Seperti biasa, kode sumber lengkap dapat ditemukan di GitHub.