140 votes

Lire le fichier du dossier des ressources dans Spring Boot

J'utilise Spring Boot et json-schema-validator . J'essaie de lire un fichier appelé jsonschema.json de la resources dossier. J'ai essayé plusieurs façons différentes mais je n'arrive pas à le faire fonctionner. Voici mon code.

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);

Il s'agit de l'emplacement du fichier.

enter image description here

Et ici je peux voir le fichier dans le classes dossier.

enter image description here

Mais lorsque j'exécute le code, j'obtiens l'erreur suivante.

jsonSchemaValidator error: java.io.FileNotFoundException: /home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json (No such file or directory)

Qu'est-ce que je fais de travers dans mon code ?

0 votes

Pouvez-vous essayer ? ClassLoader classLoader = getClass().getClassLoader(); JsonNode mySchema = JsonLoader.getJson(classLoader.getResourceAsStream("jsonsche‌​ma.json"));

128voto

John Points 467

Après avoir passé beaucoup de temps à essayer de résoudre ce problème, j'ai finalement trouvé une solution qui fonctionne. Cette solution fait appel aux ResourceUtils de Spring. Elle devrait également fonctionner pour les fichiers json.

Merci pour la page bien écrite de Lokesh Gupta : Blog

enter image description here

package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;

public class Utils {

    private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());

    public static Properties fetchProperties(){
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return properties;
    }
}

Pour répondre à quelques préoccupations sur les commentaires :

Je suis presque sûr de l'avoir fait fonctionner sur Amazon EC2 en utilisant java -jar target/image-service-slave-1.0-SNAPSHOT.jar

Regardez mon repo github : https://github.com/johnsanthosh/image-service pour trouver la bonne façon d'exécuter ça depuis un JAR.

1 votes

Merci John pour cet ajout. Cela fonctionne et c'est certainement une meilleure approche en utilisant le ResourceUtil.

2 votes

@Athar Heureux d'avoir pu aider.

51 votes

Cela ne fonctionnera que si vous essayez d'exécuter l'application depuis l'IDE, mais lorsque vous exécutez le jar, il ne trouvera pas le fichier pour vous.

58voto

Réponse très courte : vous recherchez la ressource dans la portée de la classe d'un classloader au lieu de votre classe cible. Cela devrait fonctionner :

File file = new File(getClass().getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);

Aussi, cela pourrait être une lecture utile :

P.S. Il existe un cas où un projet est compilé sur une machine et ensuite lancé sur une autre ou dans Docker. Dans un tel scénario, le chemin d'accès à votre dossier de ressources sera invalide et vous devrez l'obtenir dans le runtime :

ClassPathResource res = new ClassPathResource("jsonschema.json");    
File file = new File(res.getPath());
JsonNode mySchema = JsonLoader.fromFile(file);

Mise à jour à partir de 2020

En plus de cela, si vous voulez lire un fichier de ressources sous forme de chaîne, par exemple dans vos tests, vous pouvez utiliser ces méthodes statiques utils :

public static String getResourceFileAsString(String fileName) {
    InputStream is = getResourceFileAsInputStream(fileName);
    if (is != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        return (String)reader.lines().collect(Collectors.joining(System.lineSeparator()));
    } else {
        throw new RuntimeException("resource not found");
    }
}

public static InputStream getResourceFileAsInputStream(String fileName) {
    ClassLoader classLoader = {CurrentClass}.class.getClassLoader();
    return classLoader.getResourceAsStream(fileName);
}

Exemple d'utilisation :

String soapXML = getResourceFileAsString("some_folder_in_resources/SOPA_request.xml");

4 votes

getClass().getResource("jsonschema.json") renvoie à null . J'ai également essayé ClassPathResource res = new ClassPathResource("jsonschema.json") qui renvoie simplement jsonschema.json . Est-ce que cela a quelque chose à voir avec le fait que j'utilise Spring Boot ?

0 votes

@g3blv concernant getClass().getResource("jsonschema.json") renvoie à null Je pourrais me référer à ce sujet stackoverflow.com/questions/26328040/ . En plus de cela, essayez de reconstruire votre projet. Un retour d'information serait apprécié.

0 votes

@g3blv J'ai fourni une mise à jour de la réponse, veuillez vérifier.

36voto

Ismail Points 1

Si vous avez par exemple le dossier config sous le dossier Resources J'ai essayé cette classe qui fonctionne parfaitement.

File file = ResourceUtils.getFile("classpath:config/sample.txt")

//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);

11 votes

J'ai essayé votre solution, elle fonctionne dans l'IDE mais quand vous faites le jar de printemps le flux d'entrée vous aidera.

5voto

MostafaMashayekhi Points 4753

Créez un dossier json dans les ressources comme sous-dossier puis ajoutez le fichier json dans le dossier et vous pouvez utiliser ce code : enter image description here

import com.fasterxml.jackson.core.type.TypeReference;

InputStream is = TypeReference.class.getResourceAsStream("/json/fcmgoogletoken.json");

cela fonctionne dans Docker.

3voto

Erçin Akçay Points 250

Voici ma solution. Elle peut aider quelqu'un ;

Il renvoie un InputStream, mais je suppose que vous pouvez aussi lire à partir de celui-ci.

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jsonschema.json");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X