Question Java - Chemin relatif d'un fichier dans une application Web Java


Je veux lire un fichier à partir d'une application Web Java. Je ne veux pas donner le chemin absolu du fichier. Je veux juste mettre le fichier dans un répertoire de mon application Web.

Ou

Il peut être placé avec le fichier .war (application Web packagée).

Quel chemin relatif à donner pour le fichier. j'ai essayé ./filename.csv mais ça n'a pas marché.

========

Actualisé

========

Je vais livrer un WAR fichier (application Web packagée) à mon client. Cette application web va lire un fichier (disons SuppliedFile.csv) qui sera copié sur le serveur par le client. J'ai donc besoin d'un mécanisme (qui fonctionnera indépendamment du fait que le serveur d'applications décompresse WAR ou non) afin que l'application Web puisse lire ce fichier.

Remarque: Je n'utilise pas le SuppliedFile.csv dans une servlet ... je l'utilise dans une classe Java simple ...


31
2018-03-07 09:21


origine


Réponses:


Devez-vous vraiment le charger depuis un fichier? Si vous le placez dans vos classes (dans WEB-INF / classes), vous pouvez lui envoyer un InputStream à l'aide du class loader:

InputStream csv = 
   SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");

25
2018-03-07 09:50



Vous pourrez peut-être simplement accéder à un chemin de fichier pré-arrangé sur le système. Cela est préférable car les fichiers ajoutés au répertoire webapp peuvent être perdus ou l'application Web peut ne pas être décompressée en fonction de la configuration du système.

Dans notre serveur, nous définissons une propriété système définie dans la JVM de l'App Server, qui pointe vers le "répertoire de base" des données externes de notre application. Bien sûr, cela nécessite une modification de la configuration de l'App Server (-DAPP_HOME = ... ajouté à JVM_OPTS au démarrage), nous le faisons principalement pour faciliter le test du code exécuté en dehors du contexte d'un serveur d'applications.

Vous pouvez tout aussi facilement récupérer un chemin à partir de la configuration de servlet:

<web-app>
<context-param>
    <param-name>MyAppHome</param-name>
    <param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>

Récupérez ensuite ce chemin et utilisez-le comme chemin de base pour lire le fichier fourni par le client.

public class MyAppConfig implements ServletContextListener {

    // NOTE: static references are not a great idea, shown here for simplicity
    static File appHome;
    static File customerDataFile;

    public void contextInitialized(ServletContextEvent e) {

        appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
        File customerDataFile = new File(appHome, "SuppliedFile.csv");
    }
}

class DataProcessor {
    public void processData() {
        File dataFile = MyAppConfig.customerDataFile;
        // ...
    }
}

Comme je l'ai mentionné, le problème le plus probable que vous rencontrerez est les restrictions de sécurité. Rien ne garantit que les applications Web puissent préparer des fichiers au-dessus de leur racine Webapp. Mais il existe généralement des méthodes simples pour accorder des exceptions pour des chemins spécifiques à des applications Web spécifiques.

Quel que soit le code dans lequel vous devez accéder à ce fichier, vous êtes assuré qu’il est initialisé en premier, car vous exécutez une application Web. Par exemple ou mieux encore, il suffit simplement de passer le chemin en tant que paramètre au code qui en a besoin.


14
2018-03-07 13:32



Si vous avez un chemin pour ce fichier sur le serveur Web, vous pouvez obtenir le chemin réel dans le système de fichiers du serveur en utilisant ServletContext.getRealPath (). Notez qu'il n'est pas garanti qu'il fonctionne dans tous les conteneurs (car il n'est pas nécessaire qu'un conteneur décompresse le fichier WAR et stocke le contenu dans le système de fichiers, mais la plupart le font). Et je suppose que cela ne fonctionnera pas avec les fichiers dans / WEB-INF, car ils n'ont pas de chemin virtuel.

L'alternative serait d'utiliser ServletContext.getResource () qui renvoie un URI. Cet URI peut être une URL de type "fichier", mais il n’ya aucune garantie pour cela.


9
2018-03-07 11:23



De nombreuses applications Web Java populaires, y compris Jenkins et Lien, utilisez ce mécanisme:

  1. Éventuellement, vérifier une servlet context-param / init-param. Cela permet de configurer plusieurs instances Webapp par conteneur de servlets, en utilisant context.xml Cela peut être fait en modifiant le fichier WAR ou en modifiant les paramètres du serveur (dans le cas de Tomcat).

  2. Vérifier une variable d'environnement (en utilisant System.getenv), s'il est défini, utilisez ce dossier comme dossier de données d'application. par exemple. Jenkins utilise JENKINS_HOME et Nexus utilise PLEXUS_NEXUS_WORK. Cela permet une configuration flexible sans aucune modification de WAR.

  3. Autrement, utiliser un sous-dossier dans le dossier personnel de l'utilisateur, par exemple. $HOME/.yourapp. En code Java ce sera:

    final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
    

3
2017-08-23 23:16



L'alternative serait d'utiliser ServletContext.getResource () qui renvoie un URI. Cet URI   peut être une URL de type "fichier", mais il n'y a aucune garantie pour cela.

Vous n'avez pas besoin qu'il s'agisse d'un fichier: ... URL. Vous avez juste besoin que ce soit une URL que votre JVM peut lire - et ce sera.


1
2018-01-30 21:36



il y a un autre moyen, Si vous utilisez un conteneur tel que Tomcat:

String textPath = "http://localhost:8080/NameOfWebapp/resources/images/file.txt";

-9
2018-01-24 08:54