2010-01-26 2 views
4

J'écris un petit utilitaire de téléchargement de fichiers dans le cadre d'un projet plus vaste. A l'origine, je le manipulais à partir d'une servlet en utilisant les classes d'utilitaires de fichiers communes Apache. Voici un extrait d'un client de test rapide je l'ai écrit pour le service:Création d'une source de données à partir d'un tableau InputStream ou Byte

public static void main(String[] args) { 

    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 

factory.getInInterceptors().add(new LoggingInInterceptor()); 
factory.getOutInterceptors().add(new LoggingOutInterceptor()); 
factory.setServiceClass(FileUploadService.class); 
factory.setAddress("http://localhost:8080/FileUploadService/FileUploadService"); 
FileUploadService client = (FileUploadService) factory.create(); 

FileType file = new FileType(); 
file.setName("statemo_1256144312279"); 
file.setType("xls"); 

DataSource source = new FileDataSource(new File("c:/development/statemo_1256144312279.xls")); 
file.setHandler(new DataHandler(source)); 
Boolean ret = client.uploadFile(file); 
System.out.println (ret); 
System.exit(0); 

}

Cela fonctionne tout à fait bien. Maintenant, le problème vient quand j'essaye de remplacer les utilités communes d'Apache. Dans le code ci-dessus, je crée un DataSource à partir d'un fichier avec un nom de chemin absolu. Dans mon servlet, je ne peux cependant pas obtenir un nom de chemin absolu et le fichier que j'envoie sur le fil est vide.

Voici le code de servlet:

@SuppressWarnings("unchecked") 
    protected void doPost (final HttpServletRequest request, final HttpServletResponse response) 
     throws ServletException, IOException { 

    // form should have enctype="multipart/form-data" as an attribute 
if (!ServletFileUpload.isMultipartContent (request)) { 
    LOG.info("Invalid form attribute"); 
    return; 
} 

//DataInputStream in = new DataInputStream(request.getInputStream()); 

final DiskFileItemFactory factory = new DiskFileItemFactory(); 
factory.setSizeThreshold(FILE_THRESHOLD_SIZE); 

final ServletFileUpload sfu = new ServletFileUpload (factory); 
sfu.setSizeMax(MAX_FILE_SIZE); 

final HttpSession session = request.getSession(); 

final List<FileItem> files = new ArrayList<FileItem>(); 

final List<String> filesToProcess = new ArrayList<String>(); 

try { 
     final List<FileItem> items = sfu.parseRequest(request); 

     for (final FileItem f : items) { 
      if (!f.isFormField()) 
       files.add(f); 
     } 

     /*for (final FileItem f : files) { 
     final String absoluteFileName = UPLOAD_DESTINATION + FilenameUtils.getName(f.getName()); 

      //f.write(new File (absoluteFileName)); 
      filesToProcess.add(absoluteFileName); 
     }*/ 

     FileItem f = files.get(0); 

     LOG.info("File: " + FilenameUtils.getName(f.getName())); 
     LOG.info("FileBaseName: " + FilenameUtils.getBaseName(f.getName())); 
     LOG.info("FileExtension: " + FilenameUtils.getExtension(f.getName())); 

     FileUploadServiceClient client = new FileUploadServiceClient(); 

     DataSource source = new FileDataSource(new File(f.getName())); 

     FileType file = new FileType(); 
     file.setHandler(new DataHandler(source)); 
     file.setName(FilenameUtils.getBaseName(f.getName())); 
     file.setType(FilenameUtils.getExtension(f.getName())); 

     Boolean ret = client.uploadFile(file); 

     LOG.info("File uploaded - " + ret); 

     filesToProcess.add(UPLOAD_DESTINATION + FilenameUtils.getName(f.getName())); 
     session.setAttribute("filesToProcess", filesToProcess); 

    final RequestDispatcher dispatcher = request.getRequestDispatcher("Validate"); 
     if (null != dispatcher) { 
     dispatcher.forward(request, response); 
     } 
    } catch (FileUploadException e) { 
     LOG.info("Exception " + e.getMessage()); 
     e.printStackTrace(); 
    } catch (Exception e) { 
     LOG.info("Exception " + e.getMessage()); 
     e.printStackTrace(); 
    } 

}

Je travaille sur ce pour la plus grande partie de ce matin et je ne reçois nulle part. Même si je me débarrasse complètement du fichier Apache Commons et que je gère moi-même l'analyse de la requête, je ne peux toujours pas construire le DataSource correctement.

Merci!

Répondre

3

C'était assez simple en fait, je viens de copier sur les octets du InputStream au DataSource:

FileItem f = files.get(0); 

// there is a problem here where the file being created is empty, since we only have a 
// partial path: 
DataSource source = new FileDataSource(new File(f.getName())); 

// because of the above problem, we are going to copy over the data ourselves: 
byte[] sourceBytes = f.get(); 
OutputStream sourceOS = source.getOutputStream(); 
sourceOS.write(sourceBytes); 
+0

Exactement. Vous devez envoyer le fichier ** contents **, pas seulement le fichier ** handle **;) – BalusC

1
  • This est le code des communes-email ByteArrayDataSource
  • il semble étrange d'essayer de remplacer apache communes - ne sont pas, sauf si vous avez une très bonne raison
  • vous peut obtenir des chemins absolus dans une servlet. Vous pouvez appeler getServletContext().getRealPath("/") qui renverra le chemin absolu de votre application, et vous pourrez ensuite obtenir des fichiers relatifs à celle-ci.
+0

Oui, je ne voulais pas remplacer les communs apache. Je n'ai même pas pensé à juste obtenir le chemin du contexte et à obtenir le fichier de cette façon. L'autre partie de ce projet rendrait cela difficile. – Casey

+0

Je regarderai le code ByteArrayDataSource demain et je pourrais l'utiliser dans ma solution. Merci! – Casey

1

Dans notre application, il y a des objets qui ont des propriétés et InputStream Nom. Nous utilisons next class pour construire DataSource avec ces propriétés.

public class InputStreamDataSource implements DataSource { 

    ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
    private final String name; 

    public InputStreamDataSource(InputStream inputStream, String name) { 
     this.name = name; 
     try { 
      int nRead; 
      byte[] data = new byte[16384]; 
      while ((nRead = inputStream.read(data, 0, data.length)) != -1) { 
       buffer.write(data, 0, nRead); 
      } 
      inputStream.close(); 
      buffer.flush(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public String getContentType() {    
     return new MimetypesFileTypeMap().getContentType(name); 
    } 

    @Override 
    public InputStream getInputStream() throws IOException { 
      return new ByteArrayInputStream(buffer.toByteArray()); 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 

    @Override 
    public OutputStream getOutputStream() throws IOException { 
     throw new IOException("Read-only data"); 
    } 

} 
Questions connexes