2024-05-05 11:16 Doba čtení: 10 min

Příklad nahrávání a stahování souborů v servletu

Úvod do problematiky

Servlety představují klíčovou komponentu webových aplikací postavených na platformě Java EE. Umožňují efektivní zpracování HTTP požadavků a dynamické generování odpovědí. Častým úkolem, který servlety musí řešit, je manipulace se soubory – zejména jejich nahrávání na server a stahování z něj. Tento článek detailně popisuje, jak implementovat obě tyto funkce v servletech na praktickém příkladu.

Nahrávání souborů krok za krokem

1. Příprava HTML formuláře

Pro umožnění nahrávání souborů je nezbytné vytvořit HTML formulář s prvkem <input type="file">. Tento prvek poskytne uživateli možnost vybrat soubor z jeho lokálního zařízení. Níže je uveden příklad jednoduchého formuláře pro nahrávání:

<form action="UploadServlet" method="POST" enctype="multipart/form-data">
<input type="file" name="soubor">
<input type="submit" value="Nahrát">
</form>

2. Vytvoření servletu pro zpracování nahrávání

Po odeslání formuláře se požadavek odešle na servlet, který se postará o zpracování nahrávaného souboru. V servletu je nutné získat referenci na nahrávanou část (prvek <input type="file">) pomocí metody request.getPart() a následně uložit soubor do systému souborů serveru.

// Importy
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet {

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Získání části souboru
javax.servlet.http.Part filePart = request.getPart("soubor");
String fileName = filePart.getSubmittedFileName();

// Kontrola, zda byl vybrán soubor
if (fileName != null && !fileName.isEmpty()) {
// Získání cesty k souboru
Path uploadPath = Paths.get("C:\\uploads\\" + fileName);

// Získání vstupního streamu pro soubor
InputStream fileContent = filePart.getInputStream();

// Uložení souboru do systému souborů
Files.copy(fileContent, uploadPath);

// Přesměrování zpět na počáteční stránku
response.sendRedirect("index.jsp");
} else {
// Nevybrán žádný soubor, zobrazení chybové zprávy
response.getWriter().write("Nebyl vybrán žádný soubor k nahrání.");
}
}
}

Stahování souborů z pohledu servletů

1. Vytvoření odkazu pro stažení

Pro zahájení stahování je třeba poskytnout odkaz, který směřuje k požadovanému souboru na serveru. Odkaz lze vygenerovat dynamicky pomocí servletů nebo ho lze natvrdo zakódovat do HTML kódu. Následuje příklad jednoduchého odkazu na stažení:

<a href="DownloadServlet?file=soubor.pdf">Stáhnout soubor</a>

2. Implementace servletu pro stahování

Po kliknutí na odkaz se odešle HTTP požadavek na servlet, který zajistí odeslání souboru klientovi. Servlet musí získat referenci na soubor z lokálního systému souborů a následně poslat soubor uživateli s příslušnými HTTP hlavičkami.

// Importy
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Získání názvu souboru z parametru požadavku
String fileName = request.getParameter("file");

// Kontrola, zda byl zadán soubor
if (fileName != null && !fileName.isEmpty()) {
// Získání cesty k souboru
File downloadFile = new File("C:\\downloads\\" + fileName);

// Kontrola, zda soubor existuje
if (downloadFile.exists()) {
// Nastavení typu obsahu odpovědi
response.setContentType("application/octet-stream");

// Nastavení hlavičky odpovědi pro připojení
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

// Získání výstupního streamu pro odpověď
OutputStream out = response.getOutputStream();

// Získání vstupního streamu pro stahovaný soubor
FileInputStream in = new FileInputStream(downloadFile);

// Kopírování obsahu souboru do výstupního streamu
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}

// Zavření vstupního a výstupního streamu
in.close();
out.close();
} else {
// Soubor neexistuje, zobrazení chybové zprávy
response.getWriter().write("Požadovaný soubor neexistuje.");
}
} else {
// Nezadán soubor, zobrazení chybové zprávy
response.getWriter().write("Nebyl zadán žádný soubor ke stažení.");
}
}
}

Závěrem

Nahrávání a stahování souborů představují základní operace ve webových aplikacích Java EE. Servlety nabízejí jednoduchý a efektivní přístup k implementaci těchto funkcí. Díky metodám popsaným v tomto článku můžete snadno integrovat obě tyto operace do vašich servletových aplikací.

Často kladené dotazy (FAQ)

1. Jaký je limit velikosti pro nahrávané soubory? Limit velikosti souboru se konfiguruje v anotaci @MultipartConfig.
2. Jak mohu soubory ukládat do databáze, namísto souborového systému? Pro ukládání souborů do databáze doporučujeme použít ORM knihovny jako je například Hibernate.
3. Jakým způsobem můžu ochránit soubory před neoprávněným přístupem? Pro ochranu souborů můžete použít zabezpečení na úrovni souborů nebo šifrování.
4. Jak mohu sledovat průběh nahrávání souboru? K monitorování průběhu nahrávání lze využít rozhraní ServletProgressListener.
5. Jak povolit nahrávání více souborů najednou? V anotaci @MultipartConfig nastavte parametry maxFileSize a maxRequestSize na hodnotu -1.
6. Jak omezit typy souborů, které se mohou nahrávat? V anotaci @MultipartConfig použijte parametry fileExtensions nebo fileSizeThreshold.
7. Jak nastavit dobu platnosti odkazu pro stahování? V servletu, který se stará o stahování, nastavte hlavičku Cache-Control.
8. Jak se bránit útokům přímým odkazem na soubory? Zabraňte neoprávněnému přístupu k souborům pomocí časově omezených tokenů nebo digitálních podpisů.
Tomáš Dvořák
Autor
Czechia

Píše o bezpečnosti, webu a chytrých službách s důrazem na srozumitelnost.

Předchozí článek
Analyzátor XML v Javě
Další článek
Otázky a odpovědi na pohovor Scala