Wysyłanie plików na serwer przez Spring Boot

Często tworząc aplikacje, potrzebujemy dać możliwość użytkownikom przesyłania plików na serwer (upload). Mogą to być przykładowo zdjęcia przesłane przez użytkowników. W tym wpisie pokażę jak można to łatwo zrobić.

Zakładam, że wiesz już jak stworzyć podstawową aplikację w Spring Boocie, więc pomijam etap dodawania zależności i tworzenia głównej klasy. Jeśli chcesz się tego nauczyć możesz przeczytać o tym w poprzednim wpisie: Spring Boot – Szybkie tworzenie aplikacji web w Javie.

Na początek będziemy potrzebowali formularza HTML w którym damy użytkownikowi możliwość wybrania pliku. Tworzymy plik index.html w resources/static i tworzymy w nim formularz.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>File upload</title>
</head>
<body>

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="fileupload"/>
    <button type="submit">Wyślij</button>
</form>

</body>
</html>

Ważne aby w elemencie form ustawić method=”post” oraz enctype=”multipart/form-data”. Bez tych atrybutów, upload nie zadziała. Action ustawiłem na /upload, pod ten endpoint zostanie przesłany nasz plik.

Po uruchomieniu aplikacji i wejściu na stronę http://localhost:8080 powinniśmy ujrzeć nasz formularz, będzie on wyglądał mniej więcej tak:

Podstawowy formularz

Mając już formularz, musimy obsłużyć odbieranie pliku po stronie serwera. Potrzebujemy controller, który będzie obsługiwał endpoint /upload:

@Controller
public class UploadController {

    @PostMapping("/upload")
    @ResponseBody            // 1
    public String handleFile(@RequestPart(name = "fileupload") MultipartFile file) { // 2
        File uploadDirectory = new File("uploads");
        uploadDirectory.mkdirs();    // 3

        try {
            File oFile = new File("uploads/" + file.getOriginalFilename());
            OutputStream os = new FileOutputStream(oFile);
            InputStream inputStream = file.getInputStream();
            
            IOUtils.copy(inputStream, os); // 4
            
            os.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return "Wystąpił błąd podczas przesyłania pliku: " + e.getMessage();
        }

        return "ok!";
    }
}

To cały kod potrzebny do odebrania pliku i zapisania go na serwerze. W miejscu oznaczonym jako // 1 mówimy, że zwrócimy z metody odpowiedź, normalnie Spring szukałby widoku o nazwie którą zwracamy. Następnie jako parametr metody przyjmujemy MultipartFile (// 2) o nazwie fileupload (nazwa ta musi być taka sama jak nazwa pola w formularzu. W miejscu // 3 upewniam się, że katalog do którego chcę zapisać plik istnieje, a jeśli nie, to go tworzę. Ostatnie co nam pozostało, to stworzyć strumień wyjściowy, pobrać strumień wejściowy z przesłanego pliku i przekopiować zawartość jednego do drugiego (//4). I to wszystko.

Jeżeli uruchomimy teraz aplikację, wybierzemy plik przez formularz i klikniemy wyślij, powinien się on pojawić w katalogu uploads w głównym katalogu aplikacji. W przeglądarce powinniśmy otrzymać napis „ok!”.

Podsumowanie

Prosty upload plików możemy stworzyć bardzo szybko przy pomocy niewielkiej ilości kodu. Jednak przed zapisaniem pliku na dysku należałoby go zweryfikować, czy rzeczywiście przesłany plik to obrazek, czy może ktoś próbuje wrzucić nam na serwer jakieś nieporządane pliki. Jest to jednak temat na oddzielny post. 

Michał Autor

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.