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 .fichier war (application web packagée).
Quel chemin relatif donner pour le fichier. J'ai essayé ./filename.csv
mais ça n'a pas marché.
========
Mise à Jour
========Je vais livrer un fichier WAR
(application web packagée) à mon client. Ce site web l'application 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 le WAR
ou non) pour que l'application web puisse lire ce fichier.
Remarque:
Je n'utilise pas le SuppliedFile.csv
dans un servlet... Je l'utilise dans une classe Java simple...
6 réponses
Avez-vous vraiment besoin de le charger à partir d'un fichier? Si vous le placez le long de vos classes (dans WEB-INF/classes), vous pouvez obtenir un InputStream à l'aide du chargeur de classe:
InputStream csv =
SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");
Vous pouvez simplement accéder à un chemin de fichier pré-arrangé sur le système. Ceci est préférable car les fichiers ajoutés au répertoire webapp peuvent être perdus ou la webapp 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 du serveur D'applications qui pointe vers le "répertoire personnel" pour les données externes de notre application. Bien sûr, cela nécessite une modification de la configuration du serveur D'applications (- DAPP_HOME=... ajouté à JVM_OPTS au démarrage), nous le faisons principalement pour faciliter les tests de code exécuté en dehors du contexte d'un serveur D'applications.
Vous pouvez tout aussi facilement récupérer un chemin depuis la configuration du 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 webapps peut préparer tous les 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 à certains webapps.
Quel que soit le code dans lequel vous devez accéder à ce fichier, puisque vous exécutez dans une application web, vous êtes assuré que ceci est initialisé en premier, et peut stocker sa valeur quelque part pratique pour le reste de votre code, comme dans mon exemple ou mieux encore, passez simplement le chemin en tant que paramètre au code qui en a besoin.
Si vous avez un chemin pour ce fichier dans 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 dans chaque contenant (comme un conteneur n'est pas nécessaire de décompresser le fichier WAR et de stocker le contenu dans le système de fichiers plus à faire). 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' file:', mais il n'y a aucune garantie pour cela.
De nombreuses webapps Java populaires, y compris Jenkins et Nexus , utilisent ce mécanisme:
En Option, Vérifiez un servlet context-param / init-param. Cela permet de configurer plusieurs instances webapp par conteneur de servlet, en utilisant
context.xml
ce qui peut être fait en modifiant le WAR ou en modifiant les paramètres du serveur (dans le cas de Tomcat).Vérifiez une variable d'environnement (en utilisant le système .getenv ), s'il est défini, utilisez-le dossier comme dossier de données d'application. par exemple, Jenkins utilise
JENKINS_HOME
et Nexus utilisePLEXUS_NEXUS_WORK
. Cela permet une configuration flexible sans aucune modification de la guerre.-
Sinon, utilisez un sous-dossier dans le dossier personnel de l'utilisateur , par exemple
$HOME/.yourapp
. Dans le code Java, ce sera:final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
, L'alternative serait d'utiliser ServletContext.getResource () qui renvoie un URI. Cette URI peut être une URL' file:', mais il n'y a aucune garantie pour cela.
Vous n'avez pas besoin que ce soit un fichier:... URL. Vous avez juste besoin que ce soit une URL que votre JVM peut lire--et il sera.
, Il existe une autre façon, si vous utilisez un conteneur comme Tomcat:
String textPath = "http://localhost:8080/NameOfWebapp/resources/images/file.txt";