C.V.

 
 

      10.3.3 Clase Java ajutatoare MultipartRequest.java

      Nu sunt autorul acestor clase iar autorul nu si-a semnat fisierele. Cu parere de rau deoarece nu pot sa-i aduc un omagiu acestuia voi prezenta aceste clase asa cum sunt. Singurele interventii din partea mea au fost in primul rand comentarea in limba romana a surselor si apoi modificare clasei MultipartRequest pentru a salva fisierele incarcate sub forma i.tip, cu i numarul de ordine al fisierului(ordinea de upload). Acest fisier contine de fapt trei clase: MultipartRequest, class UploadedFile si MultipartInputStreamHandler. Aceste clase conlucreaza pentru realizarea upload-ului de fisiere de la calculatorul utilizatorului pe calculatorul server web, pe care ruleaza aplicatia adi. Fisierele sunt salvate initial sub forma 1.tip, 2.tip, .., n.tip unde tip este tip fisierului.
      Apelul claselor se face astfel:

      MultipartRequest multi = new MultipartRequest(req,".",15*1024);

unde al doilea parametru este directorul in care se salveaza fisierele iar al treilea parametru specifica dimensiunea maxima de incarcare (aici 15ko). Pentru a lucra formularul trebuie sa fie de tip ENCTYPE="multipart/form-data":

      



import java.io.*;
import java.util.*;
import javax.servlet.*;

public class MultipartRequest {

private static final int DEFAULT_MAX_POST_SIZE = 1024 * 1024;

private ServletRequest req;
private File dir;
private int maxSize;
private int nr;

private Hashtable parameters = new Hashtable();
private Hashtable files = new Hashtable();

public MultipartRequest(ServletRequest request,	String saveDirectory) throws IOException {
  this(request,saveDirectory,DEFAULT_MAX_POST_SIZE);
}

public MultipartRequest(ServletRequest request,	String saveDirectory, int maxPostSize) throws IOException {

  nr=0;
  
//Test de nulitate
  if(request == null) throw new IllegalArgumentException(" Trebuie sa fie furnizati parametrii");
  if(saveDirectory == null)  throw new IllegalArgumentException("Directorul in care se salveaza nu poate fi null");
  if(maxPostSize <= 0) throw new IllegalArgumentException("Dimensiunea maxima de dowload trebuie sa fie un nr. pozitiv");

  req=request;
  dir=new File(saveDirectory);
  maxSize=maxPostSize;

// saveDirectory este director ?
  if(!dir.isDirectory())
    throw new IllegalArgumentException("Nu este director: " + saveDirectory);

//saveDirectory este protejat la scriere?
  if(!dir.canWrite())
    throw new IllegalArgumentException("Director protejat la scriere:" + saveDirectory );

//se citesc parametrii
  readRequest();
}

//functii pentru accesul la campuri private

//denumirile parametrilor
public Enumeration getParameterNames() {  return parameters.keys(); }

//denumirile fisierelor
public Enumeration getFileNames() { return files.keys(); }

//valoarea unui parametru
public String getParameter(String name) {
  try{
    String param = (String)parameters.get(name);
    if(param.equals(""))return null;
  return param;
  }
  catch(Exception e){return null;}
}

//numele unui fisier din lista
public String getFilesystemName(String name) {
  try {
    UploadedFile file = (UploadedFile)files.get(name);
    return file.getFilesystemName();
  }
  catch(Exception e) {return null;}
}

//tipul unui fisier din lista
public String getContentType(String name) {
  try {
    UploadedFile file = (UploadedFile)files.get(name);
    return file.getContentType();
  }
  catch(Exception e) {return null;}
}

//fisierul de pe discul local
public File getFile(String name) {
  try {
    UploadedFile file=(UploadedFile)files.get(name);
    return file.getFile(); 
  }
  catch(Exception e) {return null;}
}

//citirea 
protected void readRequest() throws IOException {
//Se verifica daca metoda utilizata la criptarea este "multipart/form-data"
  String type=req.getContentType();
  if(type == null || !type.toLowerCase().startsWith("multipart/form-data")) {
    throw new IOException("Metoda de criptare nu este multipart/form-data");
  }

//verificarea dimensiunii contextului
  int length = req.getContentLength();
  if(length > maxSize) {
    throw new IOException("Dimensiunea " + length + " depaseste limita maxima admisa " + maxSize);
  }

//se ia sirul separator, de forma  "--AaB03x--" din continut 
  String boundary=extractBoundary(type);
  if(boundary == null) {
    throw new IOException("Sirul separator nespecificat");
  }

//se asociaza continutul 
  MultipartInputStreamHandler in = new MultipartInputStreamHandler(req.getInputStream(),boundary,length);

//se citeste prima linie; trebuie sa fie sirul separator
  String line =in.readLine();
  if(line == null) {
    throw new IOException("Sfarsit prematur!!");
  }
//se verifica daca prima linie este sirul separator
  if(!line.startsWith(boundary)) {
    throw new IOException("Date corupte; sirul separator nu este in cap");
  }
//se citeste continutul dintre sirurile separatoare
  boolean done=false;
  while(!done) {
    done=readNextPart(in,boundary);
  }
}

//continutul dintre doua siruri separatoare 
protected boolean readNextPart(MultipartInputStreamHandler in,String boundary)throws IOException {
//prima linie; ar tebui sa fie: content-disposition:form-data;name="field1";filename="file1.txt"

  String line=in.readLine();
  if(line == null) {return true;}

//se extrag specificatiile de context
  String[] dispInfo=extractDispositionInfo(line);
  String disposition=dispInfo[0];
  String name=dispInfo[1];
  String filename=dispInfo[2];

//linie urmatoare ori este goala ori contine content-type si o linie goala
  line=in.readLine();
  if(line == null) {return true;}
  String contentType=extractContentType(line);
  if(contentType != null) {//se asteapta o linie goala
    line=in.readLine();
    if(line == null||line.length() > 0) {
      throw new IOException("Linie corupta dupa content-type: " + line);
    }
  }
  else {//content-type implicit
    contentType = "application/octet-stream";
  }

  //se citeste continutul
  if(filename == null) {  
    String value=readParameter(in,boundary); 
    parameters.put(name,value); 
  }
  else {//este fisier
    //new  

    if(filename.equals("unknown")) {
	  readAndSaveFile(in,boundary,filename);
      files.put(name,new UploadedFile(null,null,null));
    }
    else {
	  nr++; 
	  filename= nr + filename.substring(filename.indexOf("."),filename.length());
	  readAndSaveFile(in,boundary,filename);
      files.put(name,new UploadedFile(dir.toString(),filename,contentType));///aici denumirea fisierului
    }
  }
  return false;
}

//citirea parametrilor
protected String readParameter(MultipartInputStreamHandler in,String boundary) throws IOException {
  StringBuffer sbuf = new StringBuffer();
  String line;

  while((line = in.readLine()) != null) {
    if(line.startsWith(boundary)) break;//la intalnirea sirului separator
    sbuf.append(line + "\r\n");//la citirea mai multor linii
  }
  if(sbuf.length() == 0) {return null;}

  sbuf.setLength(sbuf.length() - 2);//cut off the last line's \r\n
  return sbuf.toString();  //no URL decoding is needed
}

//citirea si salvarea fisierului
protected void readAndSaveFile(MultipartInputStreamHandler in,String boundary,String filename) throws IOException{
  File f=new File(dir + File.separator + filename);
  FileOutputStream fos=new FileOutputStream(f);
  BufferedOutputStream out=new BufferedOutputStream(fos,8 * 1024);//maxim 8k, pentru citirea unei linii

  byte[]  bbuf=new byte[8 * 1024];
  int result;
  String line;

//ServletInputSteam.readLine() adauga \r\n la sfarsitul ultimei linii; le taiem

  boolean rnflag= false;
  while((result=in.readLine(bbuf,0,bbuf.length)) != -1 ){//se citesc octetii, cate o linie de 8k
    if(result > 2 && bbuf[0] == '-' && bbuf[1] == '-') {
      line=new String(bbuf,0,result,"ISO-8859-1");
	if(line.startsWith(boundary))break;//la intalnirea separatorului se opreste citirea
    }

    //? \r\n la ultima iteratie ?
    if(rnflag) {
      out.write('\r');
      out.write('\n');
      rnflag=false; 
    }
    //se scrie ceea ce s-a citit fara \r\n
    if(result >= 2 && bbuf[result - 2 ] == '\r' && bbuf[result - 1] == '\n' ) {
      out.write(bbuf,0,result - 2);
      rnflag=true;
    }
    else{
      out.write(bbuf,0,result);
    }
  }
  out.flush();
  out.close();
  fos.close();
}

//separatorul
private String extractBoundary(String line){
  int index=line.indexOf("boundary=");
  if (index==-1){return null;}//nu a gasit separator
  String boundary =line.substring(index+9);
  boundary="--"+boundary;
  return boundary;
}

//specificatiile de continut
private String[] extractDispositionInfo(String line) throws IOException {
  String[] retval=new String[3];
  String origline=line;
  line=origline.toLowerCase();

  int start =line.indexOf("content-disposition");
  int end =line.indexOf(";");
  if (start==-1||end==-1){
    throw new IOException("Specificatii de continut corupte" + origline);
  }

  String disposition=line.substring(start+21,end);
  if (!disposition.equals("form-data")){
    throw new IOException ("Specificatii de continut invalide"+disposition);
  }

  //se verifica daca valoare parametrului este incadrata de ghilimele: "value"
  start=line.indexOf("name=\"",end);
  end=line.indexOf("\"",start+7);
  if (start==-1||end==-1){
    throw new IOException("Specificatiile de continut corupte"+origline);
  }
  //se citeste valoare lui nume dintre ghilimele
  String name=origline.substring(start+6,end);

  //se citeste numele fisierului atasat; se elimina calea
  String filename=null;
  start =line.indexOf("filename=\"",end+2);
  end=line.indexOf("\"",start+10);
  if (start!=-1 && end!=-1){
    filename=origline.substring(start+10,end);
    int slash=Math.max(filename.lastIndexOf('/'),filename.lastIndexOf('\\'));
    if (slash >-1){
      filename=filename.substring(slash+1);
    }
    if (filename.equals("")) filename="unknown";
  }
  retval[0]=disposition;
  retval[1]=name;
  retval[2]=filename;
  return retval;
}

//tipul continutului (pentru fisiere)
private String extractContentType(String line) throws IOException {

  String contentType=null;
  String origline = line;
  line = origline.toLowerCase();
  if(line.startsWith("content-type")) {
    int start=line.indexOf(" ");
    if(start == -1) {
       throw new IOException("Tipul continutului corupt: " + origline);
    }
    contentType=line.substring(start + 1);
  }
  else
    if(line.length() != 0) {
      throw new IOException("Dupa specificatii linie corupta:" + origline);
    }
  return contentType;
}
}//end classe


//clasa folosita pentru extragerea informatiilor despre fisier
class UploadedFile {
  private String dir;
  private String filename;
  private String type;

  //constructorul
  UploadedFile(String dir,String filename,String type) {
    this.dir=dir;
    this.filename=filename;
    this.type=type;
  }
  
  //returneaza valorile datelor private
  public String getContentType() {return type;}
  public String getFilesystemName() {return filename;}
  public File getFile() {//datele despre fisiere acum de pe harddisc-ul local
    if(dir == null || filename == null) {return null;} 
    else {return new File(dir + File.separator + filename);
  }
}
}



//aceasta clasa este utila pentru citirea multipart/form-data de la ServletInputStream
//contorizeaza cati octeti s-au citit si detecteaza cand s-a atins limita 
//content-Length; necesar pt. ca unele containere pt. servlet-uri nu detecteaza rapid sf. de fisier

class MultipartInputStreamHandler {

  ServletInputStream in;
  String boundary;
  int totalExpected;
  int totalRead=0;
  byte[] buf = new byte[8*1024];

  public MultipartInputStreamHandler(ServletInputStream in,	String boundary,int totalExpected) {
     this.in=in;
     this.boundary=boundary;
     this.totalExpected=totalExpected;
  }

  public String readLine() throws IOException {
    StringBuffer sbuf=new StringBuffer();
    int result;
    String line;
    do {
      result=this.readLine(buf,0,buf.length);
	if(result != -1){
	   sbuf.append(new String(buf,0,result,"ISO-8859-1"));
      }
    }while(result == buf.length);
    if(sbuf.length() == 0 ) {return null;}

    sbuf.setLength(sbuf.length() - 2);//fara \r\n
    return sbuf.toString();
  }

  public int readLine(byte b[],int off,int len) throws IOException {
    if(totalRead >= totalExpected) {
      return -1;
    }
    else {
      int result=in.readLine(b,off,len);
    if(result > 0) {
      totalRead += result;
    }
    return result;
  }
}
}






 
 
C.V.
 
Hosted by www.Geocities.ws

1