9 Temmuz 2018 Pazartesi

SpringMVC MultipartFile Arayüzü - Yüklenen (Upload) Tek Bir Dosyayı Temsil Eder

Giriş
Şu satırı dahil ederiz. Bu arayüzü gerçekleştiren CommonsMultipartFile sınıfı
import org.springframework.web.multipart.MultipartFile;
- Dosya indirmek (download) için Resource arayüzü kullanılır

Örnek
JSP ile şöyle yaparız.
<form:form id="imageForm" action="..."
  method="post" commandName="product" enctype="multipart/form-data">
  ..

  <div class="form-group">
    <label for="productImage" class="control-label">Upload Image</label>
    <form:input path="imageFile" id="productImage" type="file" class="form:input-large"/>
  </div>

  <br><br>
  <input type="submit" value="Submit" class="btn btn-success"/>
  <a href="<c:url value="/admin/productInventory"/>" class="btn btn-warning">Cancel</a>
</form:form>
Controller tarafında şöyle yaparız. Burada tek dosya yükleniyor. Eğer çok dosya olsaydı metod imzasında MultipartFile[] file olurdu
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity create(@RequestPart(name = "imagefile") MultipartFile file) {
  ...
}
application.properties
Örnek
Şöyle yaparız. Bir dosyanın büyüklüğü 2MB'yi geçemez. Toplam yükleme büyüklüğü de 20MBy'yi geçemez.
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=20MB
Kullanım
İki temel kullanım şekli var.
1. File.copy(MultipartFile.getInputStream()) ile bir hedefe kopyalamak
2. MultipartFile.transferTo () ile bir File'a kopyalamak
3. Eğer bir seferde tek dosya yüklenecekse POST isteğinin imzasına sadece MultipartFile yazılır
Bir seferde çoklu dosya yüklenecekse POST isteğinin imzasına MultipartFile[] yazılır
4. Birim testi için MockMultipartFile kullanılır

Örnek - consumes Kullanmıyor
Şöyle yaparız
//Upload single file to database.
@PostMapping("/upload")
public ImageResponse uploadSingleFile(@RequestParam("file") MultipartFile file) {
  ...
}

//Upload multiple files to database.
@PostMapping("/uploads")
public List<ImageResponse> uploadMultiFiles(@RequestParam("files") MultipartFile[] files) {
  return Arrays.asList(files)
    .stream()
    .map(file -> uploadSingleFile(file))
    .collect(Collectors.toList());
}
Yükleme için şöyle yaparız
curl -X POST -H "Content-Type: multipart/form-data"
  -F "file=@image1.jpg" http://localhost:8080/api/upload

curl -X POST -H "Content-Type: multipart/form-data"
  -F "files=@image1.jpg" -F "files=@image2.jpg"
-F "files=@image3.jpg"  http://localhost:8080/api/uploads
Örnek - consumes İçin Enum Kullanıyor
Şöyle yaparız.
@PostMapping(value = "/payment-files", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) 
public PaymentFileStatus postPaymentFile(
         @RequestParam("paymentFile") MultipartFile[] file
) {
  byte[] fileBytes;
  try {
    fileBytes = file.getBytes();
  } catch (IOException e) {
    ...
  }
  return foo(fileBytes);
}
Örnek - consumes İçin String Kullanıyor
Şöyle yaparız.
@PostMapping(value = "/upload", consumes = {"multipart/form-data"})
public ResponseEntity<Object> upload(
  @RequestParam(required = false, value = "document") MultipartFile document,
  @Valid @RequestParam("userDTOString") String userDTOString) throws JSONException {

    UserDTO userDTO = new ObjectMapper().readValue(userDTOString, UserDTO.class);
    return documentService.uploadFile(document, userDTO);
}
getBytes metodu
Şöyle yaparız.
MultipartFile multipartImageFile = ...;

product.setImageFile(multipartImageFile.getBytes());
getInputStream metodu
Şöyle yaparız
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.web.multipart.MultipartFile;

private final Path root = Paths.get("uploads");

@Override
public void save(MultipartFile file) {
  try {
    Files.copy(file.getInputStream(), this.root.resolve(file.getOriginalFilename()));
  } catch (Exception e) {
    throw new RuntimeException("Could not store the file. Error: " + e.getMessage());
  }
}
getOriginalFilename metodu
Örnek
Şöyle yaparız
public static File convertMultipartFileToFile(MultipartFile file) throws IOException {
  File convFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
  boolean fileCreated = convFile.createNewFile();
  if (!fileCreated) {
     boolean fileDeleted = convFile.delete();
     if (fileDeleted)
       org.apache.commons.io.FileUtils.writeByteArrayToFile(convFile, file.getBytes());
     } else {
        org.apache.commons.io.FileUtils.writeByteArrayToFile(convFile, file.getBytes());
     }
  }
  return convFile;
}
getResource metodu
Dosya indirmek (download) için Resource arayüzü kullanılır

Örnek
Şöyle yaparız
public void put(String name, MultipartFile file) throws IOException {
  var length = (int) file.getSize();
  var byteBuffer = ByteBuffer.allocateDirect(length);
  try (var channel = file.getResource().readableChannel()) {
    IOUtils.readFully(channel, byteBuffer);
  }
  byteBuffer.position(0);
  ...
}

isEmpty metodu
Şöyle yaparız.
MultipartFile multipartImageFile = ...

if (multipartImageFile != null && !multipartImageFile.isEmpty()) {
  ...
}
transferTo metodu - File
Metodun içi şöyle
public void transferTo(File dest) throws IOException, IllegalStateException {
  this.part.write(dest.getPath());
}
Örnek
Şöyle yaparız.
MultipartFile multipart = ...;
File convFile = ...;

multipart.transferTo(convFile);



Hiç yorum yok:

Yorum Gönder