Μεταφόρτωση και λήψη αρχείων JSP

⚡ Έξυπνη Σύνοψη

Οι λειτουργίες μεταφόρτωσης και λήψης αρχείων JSP είναι βασικές λειτουργίες εισόδου και εξόδου που επιτρέπουν σε μια διαδικτυακή εφαρμογή να λαμβάνει αρχεία από τους χρήστες και να τους τα επιστρέφει. Αυτός ο πόρος εξηγεί και τις δύο ροές χρησιμοποιώντας φόρμες ενεργειών JSP, Apache Commons FileUpload και κλάσεις servlet, με πλήρη λειτουργικό κώδικα.

  • 📤 Βασικά στοιχεία μεταφόρτωσης: Χρησιμοποιήστε τη μέθοδο POST και ορίστε την παράμετρο enctype σε multipart/form-data για οποιαδήποτε μεταφόρτωση αρχείου.
  • 🧩 Apache Commons: Τα DiskFileItemFactory και ServletFileUpload αναλύουν το αίτημα πολλαπλών τμημάτων σε στοιχεία αρχείου.
  • 🗂️ Χειρισμός Servlet: Η μέθοδος doPost επαναλαμβάνει τα στοιχεία του αρχείου και γράφει το καθένα σε έναν φάκελο προορισμού.
  • 📥 Ροή λήψης: Ένα servlet μεταδίδει ένα αρχείο χρησιμοποιώντας το FileInputStream και την κεφαλίδα Content-Disposition.
  • ⚙️ Διαμόρφωση: Οι διαδρομές αρχείων, τα όρια μεγέθους και ο τύπος περιεχομένου πρέπει να οριστούν πριν από την ανάγνωση ή την εγγραφή.

Μεταφόρτωση και λήψη αρχείων JSP

Μεταφόρτωση αρχείου JSP

  • Μπορούμε να ανεβάσουμε οποιαδήποτε αρχεία χρησιμοποιώντας JSP.
  • Μπορεί να είναι αρχείο κειμένου, δυαδικό αρχείο, αρχείο εικόνας ή οποιοδήποτε άλλο έγγραφο.
  • Εδώ σε περίπτωση μεταφόρτωσης αρχείου θα χρησιμοποιηθεί μόνο η μέθοδος POST και όχι η μέθοδος GET.
  • Το χαρακτηριστικό Enctype θα πρέπει να οριστεί σε multipart/form-data.

Παράδειγμα: Χρήση δράσης

Σε αυτό το παράδειγμα, ανεβάζουμε ένα αρχείο χρησιμοποιώντας το αντικείμενο IO.

Action_file.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Guru File</title>
</head>
<body>
<a>Guru File Upload:</a>
Select file: <br />
<form action="action_file_upload.jsp" method="post"
                        enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>

Action_file_upload.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.io.*,java.util.*, javax.servlet.*" %>
<%@ page import="javax.servlet.http.*" %>
<%@ page import="org.apache.commons.fileupload.*" %>
<%@ page import="org.apache.commons.fileupload.disk.*" %>
<%@ page import="org.apache.commons.fileupload.servlet.*" %>
<%@ page import="org.apache.commons.io.output.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Guru File Upload</title>
</head>
<body>
<%
   File file ;
   int maxFileSize = 5000 * 1024;
   int maxMemSize = 5000 * 1024;
   String filePath = "E:/guru99/data";

   String contentType = request.getContentType();
   if ((contentType.indexOf("multipart/form-data") >= 0)) {

      DiskFileItemFactory factory = new DiskFileItemFactory();
      factory.setSizeThreshold(maxMemSize);
      factory.setRepository(new File("c:\\temp"));
      ServletFileUpload upload = new ServletFileUpload(factory);
      upload.setSizeMax( maxFileSize );
      try{
         List fileItems = upload.parseRequest(request);
         Iterator i = fileItems.iterator();
         out.println("<html>");
         out.println("<body>");
         while ( i.hasNext () )
         {
            FileItem fi = (FileItem)i.next();
            if ( !fi.isFormField () )  {
                String fieldName = fi.getFieldName();
                String fileName = fi.getName();
                boolean isInMemory = fi.isInMemory();
                long sizeInBytes = fi.getSize();
                file = new File( filePath + "yourFileName") ;
                fi.write( file ) ;
                out.println("Uploaded Filename: " + filePath + fileName + "<br>");
            }
         }
         out.println("</body>");
         out.println("</html>");
      }catch(Exception ex) {
         System.out.println(ex);
      }
   }else{
      out.println("<html>");
      out.println("<body>");
      out.println("<p>No file uploaded</p>");
      out.println("</body>");
      out.println("</html>");
   }
%>
</body>
</html>

Επεξήγηση του κώδικα:

Action_file.jsp

Code Γραμμή 12-18: Εδώ δημιουργούμε μια φόρμα με ένα πεδίο αρχείου, το οποίο θα ανεβάσει ένα αρχείο στον διακομιστή και η ενέργεια θα μεταβιβαστεί στο action_file_upload.jsp.

Action_file_upload.jsp

Code Γραμμή 20: Εδώ δίνουμε τη διαδρομή του αρχείου προς μια συγκεκριμένη διαδρομή.

Code Γραμμή 23-38: Εδώ ελέγχουμε αν ο τύπος περιεχομένου είναι multipart/form-data. Εάν συμβαίνει αυτό, τότε το περιεχόμενο είναι τύπου αρχείου και διαβάζεται. Αφού διαβαστεί το αρχείο, εγγράφεται στο προσωρινό αρχείο και στη συνέχεια το προσωρινό αρχείο μετατρέπεται στο κύριο αρχείο.

Όταν εκτελείτε τον παραπάνω κώδικα, λαμβάνετε την ακόλουθη έξοδο:

Μεταφόρτωση αρχείου JSP

Παραγωγή:

Ανεβάζουμε ένα αρχείο χρησιμοποιώντας την επιλογή κουμπιού επιλογής αρχείου και το κουμπί μεταφόρτωσης αρχείου θα ανεβάσει το αρχείο στον διακομιστή στη διαδρομή που παρέχεται.

Παράδειγμα: Χρήση λειτουργιών JSP

Σε αυτό το παράδειγμα, θα ανεβάσουμε ένα αρχείο χρησιμοποιώντας λειτουργίες JSP. Θα πάρουμε μια φόρμα που θα έχει ένα κουμπί "μεταφόρτωσης" και όταν κάνετε κλικ στο κουμπί μεταφόρτωσης, το αρχείο θα μεταφορτωθεί.

Uploading_1.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Guru Uploading File</title>
</head>
<body>
File: <br />
<form action="guru_upload" method="post"
                        enctype="multipart/form-data">
<input type="file" name="guru_file" size="50" />
<br />
<input type="submit" value="Upload" />
</form>
</body>
</html>

Επεξήγηση του κώδικα:

Code Γραμμή 11-12: Εδώ παίρνουμε μια φόρμα που έχει μια ενέργεια στο servlet guru_upload, η οποία θα περάσει από μια μέθοδο POST. Επίσης, εδώ το χαρακτηριστικό enctype καθορίζει τον τρόπο με τον οποίο τα δεδομένα της φόρμας πρέπει να κωδικοποιούνται και να αποστέλλονται στον διακομιστή και χρησιμοποιείται μόνο με τη μέθοδο POST. Εδώ το ορίζουμε ως multipart/form-data, το οποίο είναι για το αρχείο (καθώς τα δεδομένα θα είναι μεγάλα).

Code Γραμμή 13: Εδώ καθορίζουμε το στοιχείο guru_file με τύπο file και δίνουμε το μέγεθος 50.

Code Γραμμή 15: Αυτό είναι ένα κουμπί τύπου υποβολής με το όνομα "Upload" (Μεταφόρτωση), μέσω του οποίου θα κληθεί το servlet ενέργειας και το αίτημα θα υποβληθεί σε επεξεργασία σε αυτό, και το αρχείο θα διαβαστεί και θα εγγραφεί στο servlet.

Guru_upload.java

package demotest;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class guru_upload extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public guru_upload() {
        super();
        // TODO Auto-generated constructor stub
    }
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		        if(ServletFileUpload.isMultipartContent(request)){
		            try {
		                List <FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
		                for(FileItem item : multiparts){
		                    if(!item.isFormField()){
		                        String name = new File(item.getName()).getName();
		                        item.write( new File("c:/guru/upload" + File.separator + name));
		                    }
		                }
		               //File uploaded successfully
		               request.setAttribute("gurumessage", "File Uploaded Successfully");
		            } catch (Exception ex) {
		               request.setAttribute("gurumessage", "File Upload Failed due to " + ex);
		            }
		        }else{

		            request.setAttribute("gurumessage","No File found");
 }
		        request.getRequestDispatcher("/result.jsp").forward(request, response);

		    }


}

Επεξήγηση του κώδικα:

Code Γραμμή 12-14: Εδώ θα πρέπει να εισαγάγουμε τη βιβλιοθήκη org.apache.commons στη διαμόρφωση του κώδικα. Θα πρέπει να εισαγάγουμε την κλάση fileupload από τη βιβλιοθήκη org.apache.commons.

Code Γραμμή 23: Εδώ έχουμε τη μέθοδο doPost(), η οποία θα καλείται καθώς περνάμε τη μέθοδο POST σε JSP, και θα δέχεται αντικείμενα request και response ως παραμέτρους της.

Code Γραμμή 26: Εδώ δημιουργούμε ένα αντικείμενο της κλάσης ServletFileUpload από το πακέτο fileUpload της βιβλιοθήκης org.apache.commons, το οποίο θα ελέγξει εάν υπάρχουν αντικείμενα αρχείου στο JSP. Εάν βρεθούν, τότε αυτά τα αντικείμενα αρχείου θα ληφθούν από το αίτημα.

Code Γραμμή 27-32: Θα επαναλάβουμε τον αριθμό των αρχείων ελέγχοντας πόσα στοιχεία αρχείου υπάρχουν στο αντικείμενο multiparts, το οποίο είναι ένα αντικείμενο λίστας (αν ανεβάσουμε περισσότερα από ένα αρχεία), και θα το αποθηκεύσουμε στον φάκελο c:/guru/upload με το όνομα αρχείου που έχει δοθεί. Εγγράφουμε το αρχείο χρησιμοποιώντας τη μέθοδο write του αντικειμένου file στον φάκελο που έχει αναφερθεί.

Code Γραμμή 34: Εάν δεν υπάρχει εξαίρεση, τότε ορίζουμε ένα χαρακτηριστικό στο αίτημα ως gurumessage με την τιμή "Το αρχείο μεταφορτώθηκε με επιτυχία".

Code Γραμμή 35-36: Εάν προκύψει κάποια εξαίρεση, τότε εμφανίζεται το μήνυμα "Η μεταφόρτωση αρχείου απέτυχε".

Code Γραμμή 40: Εάν το αρχείο δεν βρεθεί, τότε ορίζουμε το μήνυμα ως "Δεν βρέθηκε αρχείο".

Code Γραμμή 42: Προώθηση του αιτήματος χρησιμοποιώντας το αντικείμενο requestdispatcher στο result.jsp με αντικείμενα request και response.

Αποτέλεσμα.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Guru Result</title>
</head>
<body>
<% String msg = (String)request.getAttribute("message");
   out.println(msg);
%>
</body>
</html>

Επεξήγηση του κώδικα:

Code Γραμμή 10: Εδώ λαμβάνουμε το χαρακτηριστικό από το αντικείμενο αιτήματος με την τιμή gurumessage σε ένα αντικείμενο συμβολοσειράς.

Code Γραμμή 11: Εδώ τυπώνουμε αυτό το μήνυμα.

Όταν εκτελούμε τον παραπάνω κώδικα, έχουμε την ακόλουθη έξοδο:

Παραγωγή:

Λαμβάνουμε μια φόρμα όπου υπάρχουν πεδία για να επιλέξουμε ένα αρχείο από τον κατάλογο. Μόλις επιλεγεί το αρχείο, πρέπει να κάνουμε κλικ στο κουμπί μεταφόρτωσης.

Μεταφόρτωση αρχείου με χρήση λειτουργιών JSP

Μόλις πατήσουμε το κουμπί μεταφόρτωσης, λαμβάνουμε το μήνυμα ότι το αρχείο μεταφορτώθηκε με επιτυχία.

Μεταφόρτωση αρχείου με χρήση λειτουργιών JSP

Στο παρακάτω διάγραμμα, μπορούμε να δούμε ότι το αρχείο είχε μεταφορτωθεί στον φάκελο c:/guru/upload.

Μεταφόρτωση αρχείου με χρήση λειτουργιών JSP

Λήψη αρχείου JSP

Σε αυτό το παράδειγμα, πρόκειται να κατεβάσουμε ένα αρχείο από έναν κατάλογο κάνοντας κλικ στο κουμπί.

Downloading_1.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Downloading Guru Example</title>
</head>
<body>
Guru Downloading File<a href="guru_download">Download here!!!</a>
</body>
</html>

Επεξήγηση του κώδικα:

Code Γραμμή 10: Εδώ έχουμε δώσει έναν σύνδεσμο για να κατεβάσετε ένα αρχείο από τον φάκελο c:/guru/upload χρησιμοποιώντας το servlet guru_download.

Guru_download.java

package demotest;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class guru_download
 */
public class guru_download extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		String gurufile = "test.txt";
		String gurupath = "c:/guru/upload/";
		response.setContentType("APPLICATION/OCTET-STREAM");
		response.setHeader("Content-Disposition", "attachment; filename=\""
				+ gurufile + "\"");

		FileInputStream fileInputStream = new FileInputStream(gurupath
				+ gurufile);

		int i;
		while ((i = fileInputStream.read()) != -1) {
			out.write(i);
		}
		fileInputStream.close();
		out.close();
	}


	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

}

Επεξήγηση του κώδικα:

Code Γραμμή 3-5: Εδώ εισάγουμε τα FileInputStream, IOException και PrintWriter από το πακέτο java.io.

Code Γραμμή 15: Ορίζουμε το guru_download servlet που επεκτείνει το HttpServlet.

Code Γραμμή 18: Όπως έχουμε ορίσει ένα href, το οποίο θα περικλείεται σε ένα URL, επομένως η μέθοδος GET θα υποβληθεί σε επεξεργασία (η μέθοδος doGet θα κληθεί στο servlet), η οποία επίσης περικλείει αντικείμενα αιτήματος και απόκρισης.

Code Γραμμή 19-20: Ορίζουμε τον τύπο περιεχομένου στο αντικείμενο απόκρισης και επίσης λαμβάνουμε το αντικείμενο συγγραφέα από την απόκριση.

Code Γραμμή 21-22: Ορισμός μιας μεταβλητής ως gurufile με τιμή test.txt και gurupath ως c:/guru/upload/.

Code Γραμμή 23-25: Ορίζουμε τον τύπο περιεχομένου χρησιμοποιώντας το αντικείμενο απόκρισης και χρησιμοποιούμε τη μέθοδο setHeader, η οποία ορίζει την κεφαλίδα στο αντικείμενο απόκρισης ως το όνομα αρχείου που έχει μεταφορτωθεί.

Code Γραμμή 27-28: Δημιουργούμε ένα FileInputStream στο οποίο θα προσθέσουμε το gurupath+gurufile.

Code Γραμμή 31-33: Εδώ έχουμε πάρει ένα ενώ βρόχος η οποία θα εκτελείται μέχρι να διαβαστεί το αρχείο, επομένως έχουμε δώσει τη συνθήκη ως != -1. Σε αυτήν την συνθήκη, γράφουμε χρησιμοποιώντας το αντικείμενο printwriter out.

Όταν εκτελέσετε τον παραπάνω κώδικα, θα λάβετε την ακόλουθη έξοδο:

Παραγωγή:

Λήψη αρχείου

Πρέπει να κάνουμε κλικ στο downloading_1.jsp και θα εμφανιστεί ένας υπερσύνδεσμος με την ένδειξη "Λήψη από εδώ". Όταν κάνετε κλικ σε αυτό το αρχείο υπερσυνδέσμου, θα γίνει λήψη του στο σύστημα.

Συχνές Ερωτήσεις

Ναι. Οι βοηθοί τεχνητής νοημοσύνης μπορούν να δημιουργήσουν υποστηρίγματα για servlets και φόρμες JSP για μεταφόρτωση και λήψη αρχείων, να προσθέσουν λογική Apache Commons FileUpload και να προτείνουν επικύρωση. Θα πρέπει να δοκιμάσετε τον κώδικα και να ελέγξετε τις διαδρομές αρχείων και τα όρια μεγέθους.

Ναι. Οι σαρωτές που βασίζονται στην τεχνητή νοημοσύνη μπορούν να ελέγξουν τα αρχεία που έχουν μεταφορτωθεί για κακόβουλο λογισμικό, μη αναμενόμενους τύπους ή υπερμεγέθη ωφέλιμα φορτία πριν φτάσουν στον χώρο αποθήκευσης. Αυτό προσθέτει ένα επίπεδο προστασίας, αν και η επικύρωση τύπου και μεγέθους από την πλευρά του διακομιστή παραμένει απαραίτητη.

Η κωδικοποίηση πολλαπλών τμημάτων/δεδομένων φόρμας χωρίζει το αίτημα σε μέρη, έτσι ώστε τα δεδομένα δυαδικού αρχείου να είναι transmitted άθικτο. Χωρίς αυτό, το πρόγραμμα περιήγησης στέλνει στον διακομιστή μόνο το όνομα του αρχείου, όχι το πραγματικό περιεχόμενο του αρχείου.

Το Apache Commons FileUpload, μαζί με το Commons IO, χρησιμοποιείται ευρέως. Αναλύει αιτήματα πολλαπλών τμημάτων, εκθέτει κάθε FileItem και γράφει το περιεχόμενο που έχει μεταφορτωθεί σε έναν επιλεγμένο κατάλογο στον διακομιστή.

Συνοψίστε αυτήν την ανάρτηση με: