web-dev-qa-db-fra.com

Comment télécharger un fichier en utilisant JSF 2.2 <h: inputFile>? Où est le fichier enregistré?

J'aimerais pouvoir télécharger des fichiers dans mon application Web JSF2.2, j'ai donc commencé à utiliser le nouveau <h:inputFile> composant.

Ma seule question est, comment puis-je spécifier l'emplacement, où les fichiers seront enregistrés sur le serveur? Je voudrais les contacter en tant que Java.io.File instances. Cela doit être implémenté dans le bean de sauvegarde, mais je ne comprends pas clairement comment.

12
t3s0

JSF n'enregistrera pas le fichier dans un emplacement prédéfini. Il vous proposera simplement le fichier téléchargé sous la forme d'une instance javax.servlet.http.Part qui se trouve dans les coulisses temporairement stocké dans la mémoire du serveur et/ou dans un emplacement de stockage sur disque temporaire que vous ne devriez pas vous inquiéter sur.

Afin de l'enregistrer à l'emplacement souhaité, vous devez obtenir le contenu par Part#getInputStream() puis copier le dans Path représentant l'emplacement. Vous pouvez le faire dans une méthode d'action (ajax) (écouteur) de la manière habituelle. Voici un exemple qui le fait avec un écouteur ajax lors de l'événement HTML DOM change:

<h:form enctype="multipart/form-data">
    <h:inputFile value="#{bean.file}">
        <f:ajax listener="#{bean.save}" />
    </h:inputFile>
</h:form>
private Part file; // +getter+setter

public void save() {
    try (InputStream input = file.getInputStream()) {
        Files.copy(input, new File(uploads, filename).toPath());
    }
    catch (IOException e) {
        // Show faces message?
    }
}

Le dossier uploads et le filename sont entièrement sous votre contrôle. Par exemple. "/path/to/uploads" Et Part#getSubmittedFileName() respectivement. Gardez à l'esprit que tout fichier existant serait écrasé, vous pouvez utiliser File#createTempFile() pour générer automatiquement un nom de fichier.

N'utilisez pas Part#write() comme certains suggèrent. Il renommera essentiellement le fichier dans l'emplacement de stockage temporaire identifié par @MultipartConfig(location). N'utilisez pas non plus ExternalContext#getRealPath() pour enregistrer le fichier téléchargé dans le dossier de déploiement. Le fichier sera perdu lorsque le WAR est redéployé pour la simple raison que le fichier n'est pas contenu dans le WAR d'origine. Enregistrez-le toujours sur un chemin absolu en dehors du dossier de déploiement.

Pour une démonstration en direct, consultez le dernier élément de <o:graphicImage> Démo sur la vitrine OmniFaces .

Voir également:

32
BalusC