Avatar billede svarrer Nybegynder
23. juni 2005 - 13:50 Der er 8 kommentarer og
1 løsning

upload af billeder til database

Hejsa..

Jeg sidder og forsøger mig med at uploade et jpeg billede til et blob felt i en oracle db, vha. java servlets.
filen bliver fundet ved hjælp af <input type=file> og formen er en multipart /form data.
Jeg henter parameterne ud vha. en MultipartParser fra oreilly.
Spørgsmålet går på om det er muligt at streame filen direkte til db-blob-feltet, eller man absolut skal lave en temp-fil på en server først?!
lidt kode:
//--------
MultipartParser mp = new MultipartParser(req, 1024*1024); // 1MB
Part part;
while ((part = mp.readNextPart()) != null)
{
String name = part.getName();
if (part.isParam())
{
// det er en alm parameter..
  ParamPart paramPart = (ParamPart) part;
  if(name.equals("filetype"))
    type = paramPart.getStringValue();
  else if(name.equals("dbid"))
    dbid = paramPart.getStringValue();         
  }
  else if (part.isFile())
  {
  // Det er billedet....
  FilePart filePart = (FilePart) part;
  String fileName = filePart.getFileName();
  if (fileName != null)
  {
      File image = new File(fileName);
      FileOutputStream fos = new FileOutputStream(image);
     
      try
      {
        long size = filePart.writeTo(fos);
//--via Db-framework uploades filen..--------                     
        controller.uploadPicture(image); 

      }catch(Exception b)
    {
      System.err.println("Error in uploadFileToTitanDb. b= "+b);
    }
  }
  }
}//end while..

Kode fra Controlleren (DB'en)
PrepareStatement ps;
ps = getConnection().prepareStatement(
"INSERT INTO PICTURES (URL, FILE_TYPE, DOKUMENT_TYPE, BLOB_DATA) VALUES( ?, ?, ?,? )" );
       
  FileInputStream fis = new FileInputStream( pic );
       
  ps.setString( 1, url );
  ps.setString( 2, fileType );
  ps.setString(3, docType);
  // Insert the image into the 4 Blob
  ps.setBinaryStream( 4, fis, ( int )pic.length());
       
    // Execute the INSERT
  int count = ps.executeUpdate();
//--------------------</code>----------------
Jeg får en fejl der hedder at:
"java.io.FileNotFoundException: worldmap.jpg (Access is denied)" inden jeg overhoved forsøger at sætte ind i db'en.

nogen ideer??! eller kan det slet ikk lade sig gøre at streame direkte til et blobfelt uden en temp?

På forhånd tak
/Christian
Avatar billede arne_v Ekspert
23. juni 2005 - 14:33 #1
MultipartParser mp = new MultipartParser(request, 1000000000);
Part p = mp.readNextPart();
FilePart fp = (FilePart)p;
InputStream is = fp.getInputStream();
Avatar billede arne_v Ekspert
23. juni 2005 - 14:34 #2
com.oreilly.servlet kan netop gøre det du vil

Jakarta FileUpload kan ikke
Avatar billede svarrer Nybegynder
23. juni 2005 - 14:49 #3
korrekt at det er muligt at få en inputstream fra multiparseren, men for at sætte min setBinaryStream skal jeg også bruge længden på "filen".. og det er lidt tricky at finde frem til den?!?
Avatar billede arne_v Ekspert
23. juni 2005 - 14:52 #4
hvad returnerer is.available() ?
Avatar billede svarrer Nybegynder
05. juli 2005 - 11:27 #5
Den returnere 0... så den kan ikke bruges..beklager den lange ventetid.. har åbenbart overset din kommentar..
Avatar billede svarrer Nybegynder
05. juli 2005 - 12:58 #6
Jeg har fundet en løsning på problemet!
Avatar billede arne_v Ekspert
05. juli 2005 - 13:06 #7
hvilken ?
Avatar billede svarrer Nybegynder
05. juli 2005 - 13:20 #8
Doh.. ja.. sikken en hjælp jeg ellers ville være til?!..:-)
here goes:
gør brug af en oracle.sql.BLOB klasse, (der dog ikke virker fuldt ud implementeret!?) til at loade bits'ene over i, og derefter bruger getBytes() fra blob-interfacet til at konvertere til et byte array. ved så at bruge en ByteArrayInputStream til at streame indholdet af arrayet til et preparedStatement, samt man har længden af arrayet(.length) kan de sidste parameter i ps.setBinaryStream(index, Stream, Size)

//---kode-----
byte[] image;     
InputStream is = filePart.getInputStream();
BLOB bl =  BLOB.createTemporary(controller.getConnection(),true, BLOB.DURATION_CALL);     
OutputStream os = bl.getBinaryOutputStream();  //os peger på bl nu!
byte[] chunk = new byte[1024];
int i=-1;
i = is.read(chunk,0,1023);
while(i!=-1)
{
  os.write(chunk,0,i); //Write the chunk into the blob
  i = is.read(chunk,0,1023);  //read a new piece of blob
}
// When done close the streams
os.close();
int size = (int) bl.length();
image = bl.getBytes(1,size);
ByteArrayInputStream bais = new ByteArrayInputStream(image);
storedFileId =
        controller.uploadPic(fileType,docType,fileName,bais,size);
//**********
Og her koden fra min Controller
//-------kode---------------

ps = getConnection().prepareStatement( "INSERT INTO MIS.GEN$STORED_FILE (FILE_ID, URL, FILE_TYPE, DOKUMENT_TYPE, BLOB_DATA) VALUES( ?, ?, ?, ?, ? )" );
         
ps.setInt(1,storedFileId);
ps.setString( 2, url );
ps.setString( 3, fileType );
ps.setString(4, docType);
// Insert the image into the 5 Blob
ps.setBinaryStream( 5, is, size);
----

Men tak for hjælpen og svarene..
Avatar billede svarrer Nybegynder
05. juli 2005 - 13:23 #9
storedFileId =
        controller.uploadPic(fileType,docType,fileName,BAIS,size);
-----bais = is------
i (controlleren) ps.setBinaryStream( 5, IS, size);
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester