Comment sauvegarder le fichier téléchargé dans JSF

je télécharge un fichier dans JSF. J'utilise le <t:inputFileUpload> de Tomahawk pour cela, mais la même question s'applique par exemple sur les PrimeFaces <p:fileUpload> et JSF 2.2 <h:inputFile> .

j'ai le code de la fève de soutien ci-dessous:

private UploadedFile uploadedFile; // +getter+setter

public String save() throws IOException {
    String name = uploadedFile.getName();
    System.out.println("File name: " + name);

    String type = uploadedFile.getContentType();
    System.out.println("File type: " + type);

    long size = uploadedFile.getSize();
    System.out.println("File size: " + size);  

    InputStream stream = uploadedFile.getInputStream();
    byte[] buffer = new byte[(int) size];  
    stream.read(buffer, 0, (int) size);  
    stream.close();  
}

je suis capable d'obtenir le nom, le type et la taille du fichier, mais je ne peux pas enregistrer ce fichier à un chemin spécifique. Je ne peux pas comprendre la bonne façon de sauvegarder le fichier téléchargé. Comment puis-je y parvenir?

15
demandé sur BalusC 2013-01-08 13:27:53

2 réponses

la méthode getInputStream() du fichier téléchargé représente le contenu du fichier.

InputStream input = uploadedFile.getInputStream();

vous devez le copier dans un fichier. Vous devez d'abord préparer un dossier sur le système de fichiers Disque local où les fichiers téléchargés doivent être stockés. Par exemple, /path/to/uploads (sur Windows, ce serait sur le même disque que là où le serveur tourne). Notez que vous devriez absolument pas stocker les fichiers dans le dossier de guerre élargi en utilisant un chemin relatif ou getRealPath() pour les raisons mentionnées ici image téléchargée seulement disponible après rafraîchissement de la page .

ensuite, vous devez autogénérer le nom du fichier. Sinon, quand quelqu'un télécharge un fichier avec par coïncidence, le même nom plus tard, il serait écrasé. Vous pouvez utiliser Files#createTempFile() facilité pour obtenir un nom de fichier autogénéré.

Path folder = Paths.get("/path/to/uploads");
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);

le chemin vers les uploads pourrait si nécessaire soyez paramétré en fonction de l'une des nombreuses façons indiquées dans cette Q&R: méthode recommandée pour sauvegarder les fichiers téléchargés dans une application servlet . Le FilenameUtils fait partie d'Apache Commons IO que vous devriez déjà avoir dans votre classpath car il s'agit d'une dépendance du composant de téléchargement de fichiers Tomahawk.

enfin, il suffit de streamer le fichier téléchargé vers ce fichier (en supposant Java 7):

try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

System.out.println("Uploaded file successfully saved in " + file);

alors, pour le télécharger en arrière, le plus facile serait pour enregistrer /path/to/uploads comme un nouveau contexte webapp ou un hôte virtuel afin que tous ces fichiers soient disponibles par une URL. Voir aussi charger des images depuis l'extérieur du dossier webapps / webcontext / deploy en utilisant la balise ou .

50
répondu BalusC 2017-05-23 10:31:20

PrimeFaces utilise deux décodeurs de téléchargement de fichiers pour télécharger le contenu de P: fileupload

  1. NativeFileUploadDecoder
  2. CommonsFileUploadDecoder

NativeFileUploadDecoder est le décodeur de téléchargement par défaut et il nécessite servlet container 3.0. Donc, si votre conteneur de servlet est inférieur à 3, alors il ne fonctionnera pas avec vous. Aussi certains serveurs d'application font une restriction sur l'utilisation de contenu multi-pièces

donc si vous avez un problème avec le décodeur de téléchargement natif pour une raison quelconque, vous devez utiliser l'autre décodeur qui est "CommonsFileUploadDecoder"

CommonsFileUploadDecoder dépend de Apache commune de la lib donc, vous avez à mettre le commons fileupload et commons-io pots dans votre chemin de classe la version dépend de votre version primefaces mais 1.3 et 2.2 fonctionnent respectivement pour moi.

à utiliser Vous devez utiliser le filtre

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

attendre que le filtre ne fonctionnera pas parce que à l'intérieur du filtre, il vérifie à propos de l'uploader si elle n'est pas fournie et détecter au moins JSF 2.2 de sorte qu'il sera de contourner la demande pour le décodeur par défaut "Natif" et puis, il ne fonctionnera pas pour votre aussi

pour forcer le filtre à utiliser le décodeur commun, vous devez mettre le contexte suivant param dans votre web.XML

<context-param>
<param-name>primefaces.UPLOADER</param-name>
   <param-value>commons</param-value>
</context-param>
1
répondu HMoussa 2018-05-16 06:48:24