Activitats

Càrrega de fitxers

L’objectiu d’aquesta activitat és aprofundir en l’aprenentatge de la comunicació client-servidor utilitzant formularis i servlets per permetre a l’usuari pujar un fitxer al servidor d’aplicacions.

Implementeu una pàgina web que estigui associada a un servlet i que permeti a l’usuari pujar un fitxer al servidor.

La solució de l’exercici la podeu descarregar en aquest

enllaç ( 5.4 KB )
.

Començarem l’activitat creant un nou projecte Maven. Aneu a File / New Project / Maven / Web Application. No esborreu el fitxer index.html, ja que el necessitarem per implementar la vista amb el formulari web.

A continuació, creeu un servlet nou anomenat CarregaFitxerServlet.java i modifiqueu-lo perquè contingui el següent codi:

  1. @WebServlet(name = "CarregaFitxerServlet", urlPatterns = {"/CarregaFitxerServlet"})
  2. @MultipartConfig(location = "/tmp")
  3. public class CarregaFitxerServlet extends HttpServlet {
  4.  
  5. protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  6. throws ServletException, IOException {
  7. response.setContentType("text/html;charset=UTF-8");
  8.  
  9. try (PrintWriter out = response.getWriter()) {
  10. out.println("<!DOCTYPE html>");
  11. out.println("<html>");
  12. out.println("<head>");
  13. out.println("<title>Servlet CarregaFitxerServlet</title>");
  14. out.println("</head>");
  15. out.println("<body>");
  16. out.println("<h1>Càrrega de Fitxers</h1>");
  17. Part p = request.getPart("fitxer");
  18. p.write(p.getSubmittedFileName());
  19. out.println("<p>S'ha pujat el fitxer.</p>");
  20. out.println("</body>");
  21. out.println("</html>");
  22. }
  23. }
  24.  
  25. @Override
  26. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  27. throws ServletException, IOException {
  28. processRequest(request, response);
  29. }
  30.  
  31. @Override
  32. public String getServletInfo() {
  33. return "Short description";
  34. }
  35. }

Si utilitzeu Windows com a sistema operatiu canvieu la línia @MultipartConfig(location = ”/tmp”) per @MultipartConfig(location = “C:\Users\nomuser\tmp”).

Primer de tot, vegeu que s’ha introduït la notació @MultipartConfig després de la declaració del servlet. Aquesta notació indica que el servlet espera el tipus MIME multipart/form-data en la petició de l’usuari, és a dir, dintre de l’objecte request.

El tipus multipart/form-data indica que el client pot enviar un fitxer amb un input del tipus file. El formulari del client web també ha d’incloure aquests tipus MIME en la seva codificació en enviar el formulari.

Un paràmetre que admet aquesta notació és la ubicació del servidor, location, on es volen dipositar els fitxers pujats pel client web. En aquest cas hem escollit la carpeta temporal /tmp, on sabem que tothom té permisos per escriure. La ubicació subministrada ha de ser una ruta absoluta; no podem indicar la ruta utilitzant rutes relatives a la ubicació del servlet en el servidor.

Un altre paràmetre que podem afegir és el MaxFileSize, que indica la mida màxima del fitxer en el disc (en bytes). Si la mida del fitxer és superior a la indicada, el contenidor web llençarà una excepció (IllegalStateException). Per defecte, la mida del fitxer és il·limitada.

En comptes d’utilitzar aquesta notació també es pot introduir en el fitxer web.xml les etiquetes corresponents a aquesta funcionalitat. Aquestes etiquetes han d’estar dintre de les etiquetes del servlet al qual pertany la funcionalitat de rebre un fitxer des d’un client web.

  1. <multipart-config>
  2. <location>/tmp</location>
  3. <max-file-size>20848820</max-file-size>
  4. </multipart-config>

A continuació s’ha d’implementar la manera per recuperar el fitxer enviat per l’usuari. Vegeu el següent codi:

  1. Part p = request.getPart("fitxer");
  2. p.write(p.getSubmittedFileName());

El codi anterior utilitza el mètode getPart() de l’objecte request. Com que en un formulari web podem pujar més d’un fitxer, a aquests fitxers se’ls anomena parts. Podem accedir a les parts amb el nom que s’ha definit a l’input del formulari web. En aquest cas, el nom de l’input que rep un fitxer s’anomena fitxer.

Una vegada hem accedit al fitxer (Part9) s’escriu on toca dintre del servidor.

  1. p.write(p.getSubmittedFileName());

El nom del fitxer s’obté amb el mètode getSubmittedFileName(), però podríem haver utilitzat un altre nom. Penseu que en escriure fitxers dels usuaris en un servidor web ens hem d’assegurar que no se sobreescriu un altre que té el mateix nom. Per evitar-ho és normal l’ús d’identificadors únics.

Només ens queda modificar el fitxer index.html creat amb el projecte Maven per afegir un formulari que contingui un input que permeti a l’usuari pujar un fitxer:

  1. <!DOCTYPE html>
  2. <head>
  3. <title>Càrrega de fitxers</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. </head>
  6. <body>
  7. <h1>Pujar un fitxer</h1>
  8. <form action="CarregaFitxerServlet"
  9. enctype="multipart/form-data"
  10. method="POST">
  11. <input type="file" name="fitxer"><br>
  12. <input type="Submit" value="Pujar fitxer"><br>
  13. </form>
  14. </body>
  15. </html>

Vegeu que s’ha afegit l’atribut enctype en formular. Aquest atribut indica al servidor web que s’envia un fitxer com a part de les dades del formulari. Per tant, el servlet CarregaFitxerServlet ha de contenir la notació @MultipartConfig associada.

L’únic que s’ha afegit al formulari és l’input per pujar fitxers. Fixeu-vos que el seu nom, fitxer, correspon al nom utilitzat en el servlet anterior per recuperar-lo.

  1. //al formulari
  2. <input type="file" name="fitxer"><br>
  3. //i al servlet
  4. Part p = request.getPart("fitxer");

Anar a la pàgina anterior:
Formularis amb 'servlets' i EJB
Anar a la pàgina següent:
Exercicis d'autoavaluació