Începem prin a aduce câteva completari privind cererile HTTP.
Am mentionat ca în cazul unei cereri de tipul GET datele sunt adaugate URL-ului. Aceasta constituie o restrictie, deoarece mult 18318f518s e servere de Web limiteaza un URL la 256 de caractere. În plus, GET admite un singur protocol MIME si anume cel implicit: application/x-www-form-urlencoded
În cazul cererilor de tipul POST, datele transmise sunt înglobate în antetele cererii. Ele sunt accesibile prin metoda getParameterValues sau prin citire din fluxul de intrare asociat servlet-ului. Volumul datelor transmise este nelimitat, ceea ce permite de exemplu transmiterea de fisiere de orice lungime. De asemenea protocolul MIME (specificat prin ContentType) nu este restrictionat.
Descriem în continuare modalitatile prin care browser-ul si serverul de Web îsi pot transmite unul altuia fisiere.
Transmiterea unui fisier de la browser catre server (upload)
Este necesara transmiterea "multipla" (multipart), pentru care trebuie folosit tipul MIME multipart/form-data Tipul de cerere va fi bineînteles POST. Începem prin descrierea informatiei primite de server în acest caz.
Exemplul 1. Structura informatiei transmise cu multipart
Documentul Multipart.html urmator precizeaza tipul MIME prin ENCTYPE, contine un câmp de text cu numele desc, un nume de fisier cu numele filename, precum si un buton cu numele Submit si eticheta Buton_Submit
<FORM ACTION="https://localhost:8080/User/servlet/Multipart"
METHOD="POST" ENCTYPE="multipart/form-data">
Camp de text <INPUT TYPE="TEXT" NAME="desc" value=""> <p>
Fisier catre server <INPUT TYPE="FILE" NAME="filename" value="">
<p> <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Buton_Submit">
</FORM>
Browser-ul afiseaza acest document sub forma:
invitându-ne sa introducem un sir de caractere în câmpul de text si sa precizam fisierul ce urmeaza a fi transmis serverului (fie prin înscrierea numelui sau complet în al doilea câmp de text, fie prin selectare actionând butonul Browse
Servlet-ul Multipart are forma:
import java.io.*; import java.util.*;
import javax.servlet.*; import javax.servlet.http.*;
public class Multipart extends HttpServlet
}
dos.close();
}
else System.out.println("Error");
out.println("Gata");
out.println("</body></html>");
out.close();
}
La executare vom completam câmpul de text cu abcd si alegem (prin actionarea lui Browse) fisierul text C:\f_client format din 5 linii, cu continutul:
Serverul de Web va afisa în fereastra sa si în fisierul C:\f_server urmatoarele:
multipart/form-data; boundary=----- ----- -----------------7d6c6170168
----- ----- --------- ----- -----7d6c6170168
Content-Disposition: form-data; name="desc"
abcd
----- ----- --------- ----- -----7d6c6170168
Content-Disposition: form-data; name="filename"; filename="C:\f_client"
Content-Type: text/plain
----- ----- --------- ----- -----7d6c6170168
Content-Disposition: form-data; name="Submit"
Buton_Submit
----- ----- --------- ----- -----7d6c6170168--
Explicatii. Rezultatul întors de invocarea metodei getContentType() contine tipul MIME specificat (multipart/form-data), dar si sirul de caractere ce constituie linia separatoare (alta la fiecare executare), ce delimiteaza sectiunile. În fiecare sectiune apar informatii despre continut (Content-Disposition si eventual Content-Type), urmate de o linie vida si de continutul propriu-zis. De toate aceste informatii vom tine cont în exemplul care urmeaza.
Exemplul 2. Transmiterea unui fisier catre server.
Documentul MP.html este identic cu Multipart.html din exemplul precedent, cu exceptia numelui servlet-ului:
<FORM ACTION="https://localhost:8080/User/servlet/Multipart"
METHOD="POST" ENCTYPE="multipart/form-data">
Camp de text <INPUT TYPE="TEXT" NAME="desc" value=""> <p>
Fisier catre server <INPUT TYPE="FILE" NAME="filename" value="">
<p> <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Buton_Submit">
</FORM>
Vom tine seama de structura de mai sus a informatiei transmise. sirul de caractere ce constituie linia separatoare apare în sirul întors de metoda getContentType, dupa informatia "boundary=". Ţinând cont de documentul HTML de mai sus (conform caruia fisierul apare în a doua sectiune dupa trei linii de informatii), vom identifica linia separatoare (notata prin separator) si vom actiona asupra fluxului de intrare astfel:
avansam câte o linie, aflând lungimea ei lung prin invocarea metodei readLine si continutul ei în tabloul de octeti octeti, pîna când ajungem pe a doua linie separatoare;
trecem de linia separatoare si de urmatoarele 3 linii, ajungând astfel la începutul fisierului de trebuie primit;
citim continutul fisierului transmis de client (fie el C:\aaa.doc) pâna la urmatoarea linie separatoare si îl trecem în fisierul C:\bbb.doc de pe server. În acest scop este folosit tabloul de octeti fisier, la care se adauga succesiv câte o linie citita din fluxul de intrare, pâna la întâlnirea primei linii separatoare.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MP extends HttpServlet
}
// 2)
for (int k=0; k<4; k++)
// 3)
byte fisier[]=new byte[50000]; int depl=0;
FileOutputStream fis =
new FileOutputStream("C:\\bbb.doc");
DataOutputStream dos = new DataOutputStream (fis);
while(linie.indexOf(separator)<0)
for(int i=0;i<depl-2;i++)
dos.writeByte( fisier[i] );
dos.close();
} //end if POST
out.println("GATA"+"</body></html>"); out.close();
}
Transmiterea unui fisier de la server catre browser (download)
Documentul Attachm.html are continutul:
<FORM ACTION="https://localhost:8080/User/servlet/Attachm"
METHOD="POST" >
<INPUT TYPE="SUBMIT" VALUE="Submit" NAME="Submit">
</FORM>
Vom folosi urmatorul servlet prin care serverul de Web transmite browserului fisierul Excel C:\Book1.xls, sub numele Excel.xls
import java.io.*;
import javax.servlet.*; import javax.servlet.http.*;
public class Attachm extends HttpServlet
}
unde:
prin metoda setContentType este indicat tipul MIME al raspunsului;
prin metoda addHeader este introdus un antet prin care precizam numele sub care este primit fisierul si faptul ca el este transmis ca attachment: browserul va deschide o fereastra de dialog prin care întreaba daca dorim sa deschidem sau sa salvam fisierul primit; în acest al doilea caz este deschisa o fereastra în care putem alege directorul în care va fi salvat si numele sub care va fi salvat (deci nu neaparat cel precizat) fisierul. Putem de asemena folosi inline în loc de attachment si atunci browserul afiseaza (deschide) direct fisierul;
dupa introducerea în raspuns a antetului introducem octet cu octet continutul sau în raspuns, mai precis în fluxul de iesire.
|