Voorbeeld van het downloaden van een bestand in een servlet

1. Overzicht

Een veelvoorkomend kenmerk van webapplicaties is de mogelijkheid om bestanden te downloaden.

In deze tutorial we zullen een eenvoudig voorbeeld geven van het maken van een downloadbaar bestand en het serveren vanuit een Java Servlet-applicatie.

Het bestand dat we gebruiken, komt uit de webapp-bronnen.

2. Maven afhankelijkheden

Als u Jakarta EE gebruikt, hoeven we geen afhankelijkheden toe te voegen. Als we echter Java SE gebruiken, hebben we de javax.servlet-api-afhankelijkheid nodig:

 javax.servlet javax.servlet-api 4.0.1 voorzien 

De laatste versie van de afhankelijkheid is hier te vinden.

3. Servlet

Laten we eerst de code bekijken en dan kijken wat er aan de hand is:

@WebServlet ("/ download") openbare klasse DownloadServlet breidt HttpServlet uit {private final int ARBITARY_SIZE = 1048; @Override beschermde void doGet (HttpServletRequest req, HttpServletResponse resp) gooit ServletException, IOException {resp.setContentType ("text / plain"); resp.setHeader ("Content-disposition", "attachment; filename = sample.txt"); probeer (InputStream in = req.getServletContext (). getResourceAsStream ("/ WEB-INF / sample.txt"); OutputStream out = resp.getOutputStream ()) {byte [] buffer = nieuwe byte [ARBITARY_SIZE]; int numBytesRead; while ((numBytesRead = in.read (buffer))> 0) {out.write (buffer, 0, numBytesRead); }}}}

3.1. Verzoek eindpunt

@WebServlet ("/ download") annotatie markeert de DownloadServlet klasse om verzoeken te dienen die zijn gericht aan de "/ Download" eindpunt.

Als alternatief kunnen we dit doen door de mapping in het web.xml-bestand te beschrijven.

3.2. Reactie Inhoudstype

De HttpServletResponse object heeft een methode genaamd setContentType die we kunnen gebruiken om de Inhoudstype header van het HTTP-antwoord.

Inhoudstype is de historische naam van de kopteksteigenschap. Een andere naam was het MIME-type (Multipurpose Internet Mail Extensions). We verwijzen nu eenvoudig naar de waarde als het mediatype.

Deze waarde kan zijn "applicatie / pdf", "tekst / gewoon", "tekst / html", "afbeelding / jpg", enz., de officiële lijst wordt bijgehouden door de Internet Assigned Numbers Authority (IANA) en is hier te vinden.

Voor ons voorbeeld gebruiken we een eenvoudig tekstbestand. De Inhoudstype voor een tekstbestand is "text / plain".

3.3. Reactie Content-Disposition

Instellen van de Content-Disposition header in het responsobject vertelt de browser hoe hij het bestand waartoe hij toegang heeft, moet behandelen.

Browsers begrijpen het gebruik van Content-Disposition als een conventie, maar het maakt eigenlijk geen deel uit van de HTTP-standaard. W3 heeft een memo over het gebruik van Content-dispositie beschikbaar om hier te lezen.

De Content-dispositie waarden voor de hoofdtekst van een antwoord zijn ofwel "inline" (voor webpagina-inhoud die moet worden weergegeven) of "bijlage" (voor een downloadbaar bestand).

Indien niet gespecificeerd, is het default Content-Disposition is "inline".

Met behulp van een optionele header-parameter kunnen we de bestandsnaam “sample.txt” specificeren.

Sommige browsers zullen het bestand onmiddellijk downloaden met de opgegeven bestandsnaam en andere zullen een downloaddialoogvenster tonen met onze vooraf gedefinieerde waarde.

De exacte actie die wordt ondernomen, is afhankelijk van de browser.

3.4. Lezen van bestand en schrijven naar outputstroom

In de overige coderegels nemen we de ServletContext van het verzoek, en gebruik het om het bestand op “/WEB-INF/sample.txt” te verkrijgen.

Gebruik makend van HttpServletResponse#getOutputStream (), lezen we vervolgens uit de invoerstroom van de bron en schrijven naar de antwoorden OutputStream.

De grootte van de byte-array die we gebruiken is willekeurig. We kunnen beslissen dat de grootte op basis van de hoeveelheid geheugen redelijk is om toe te wijzen voor het doorgeven van de gegevens van het InputStream naar de OutputStream; hoe kleiner de nuber, hoe meer lussen; hoe groter het getal, hoe hoger het geheugengebruik.

Deze cyclus gaat door tot numByteRead is 0 omdat dat het einde van het bestand aangeeft.

3.5. Sluiten en doorspoelen

Stroom instanties moeten na gebruik worden gesloten om bronnen vrij te geven die het momenteel in bezit heeft. auteur instanties moeten ook worden leeggemaakt om resterende gebufferde bytes naar hun bestemming te schrijven.

Gebruik maken van een probeer-met-middelen verklaring, de applicatie zal automatisch dichtbij ieder AutoCloseable instantie gedefinieerd als onderdeel van de proberen uitspraak. Lees hier meer over proberen met bronnen.

We gebruiken deze twee methoden om geheugen vrij te maken en ervoor te zorgen dat de gegevens die we hebben voorbereid, vanuit onze applicatie worden verzonden.

3.6. Het bestand downloaden

Nu alles op zijn plaats is, zijn we nu klaar om onze Servlet uit te voeren.

Als we nu het relatieve eindpunt bezoeken "/ Download", zal onze browser proberen het bestand te downloaden als "simple.txt".

4. Conclusie

Het downloaden van een bestand van een Servlet wordt een eenvoudig proces. Door streams te gebruiken, kunnen we de gegevens als bytes doorgeven en de mediatypen laten de clientbrowser weten welk type gegevens we kunnen verwachten.

Het is aan de browser om te bepalen hoe het antwoord moet worden afgehandeld, maar we kunnen enkele richtlijnen geven met de Content-Disposition koptekst.

Alle code in dit artikel is te vinden op GitHub.