Charger une ressource en tant que chaîne au printemps

1. Vue d'ensemble

Dans ce didacticiel, nous examinerons différentes façons d' injecter le contenu d'une ressource contenant du texte sous forme de chaîne dans nos beans Spring .

Nous allons chercher à localiser la ressource et à lire son contenu.

Nous montrerons également comment partager les ressources chargées sur plusieurs beans. Nous allons le montrer à travers l'utilisation d'annotations liées à l'injection de dépendances, bien que la même chose puisse également être obtenue en utilisant l'injection basée sur XML et en déclarant les beans dans le fichier de propriétés XML.

2. Utilisation de la ressource

Nous pouvons simplifier la localisation d'un fichier de ressources en utilisant l' interface Resource . Spring nous aide à trouver et à lire une ressource à l'aide du chargeur de ressources, qui décide quelle implémentation de ressource choisir en fonction du chemin fourni. La ressource est en fait un moyen d'accéder au contenu de la ressource, plutôt qu'au contenu lui-même.

Voyons quelques moyens d'acquérir une instance Resource pour les ressources sur le chemin de classe.

2.1. Utilisation de ResourceLoader

Nous pouvons utiliser la classe ResourceLoader si nous préférons utiliser le chargement paresseux:

ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("classpath:resource.txt");

Nous pouvons également injecter le ResourceLoader dans notre bean avec @Autowired :

@Autowired private ResourceLoader resourceLoader;

2.2 Utiliser @Resource

Nous pouvons injecter une ressource directement dans un bean Spring avec @Value :

@Value("classpath:resource.txt") private Resource resource;

3. Conversion de ressource en chaîne

Une fois que nous avons accès à la ressource, nous devons pouvoir la lire dans une chaîne . Créons une classe utilitaire ResourceReader avec une méthode statique asString pour le faire pour nous.

Tout d'abord, nous devons acquérir un InputStream :

InputStream inputStream = resource.getInputStream();

Notre prochaine étape consiste à prendre ce InputStream et à le convertir en String . Nous pouvons utiliser la propre méthode FileCopyUtils # copyToString de Spring :

public class ResourceReader { public static String asString(Resource resource) { try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) { return FileCopyUtils.copyToString(reader); } catch (IOException e) { throw new UncheckedIOException(e); } } // more utility methods }

Il y a beaucoup d' autres façons d' y parvenir, par exemple, en utilisant copyToString de Spring StreamUtils classe

Créons également une autre méthode utilitaire readFileToString, qui récupérera la ressource pour un chemin, et appelons la méthode asString pour la convertir en String .

public static String readFileToString(String path) { ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource(path); return asString(resource); }

4. Ajout d'une classe de configuration

Si chaque bean devait injecter des ressources String s individuellement, il y a une chance à la fois de duplication de code et d'utilisation accrue de la mémoire par les beans ayant leur propre copie individuelle de String .

Nous pouvons obtenir une solution plus soignée en injectant le contenu de la ressource dans un ou plusieurs beans Spring lors du chargement du contexte d'application. De cette façon, nous pouvons masquer les détails d'implémentation pour lire la ressource à partir des différents beans qui ont besoin d'utiliser ce contenu.

@Configuration public class LoadResourceConfig { // Bean Declarations }

4.1. Utilisation d'un bean contenant la chaîne de ressources

Déclarons des beans pour contenir le contenu de la ressource dans une classe @Configuration :

@Bean public String resourceString() { return ResourceReader.readFileToString("resource.txt"); }

Injectons maintenant les beans enregistrés dans les champs en ajoutant une annotation @Autowired :

public class LoadResourceAsStringIntegrationTest { private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content @Autowired @Qualifier("resourceString") private String resourceString; @Test public void givenUsingResourceStringBean_whenConvertingAResourceToAString_thenCorrect() { assertEquals(EXPECTED_RESOURCE_VALUE, resourceString); } }

Dans ce cas, nous utilisons l' annotation @Qualifier et le nom du bean, car nous pouvons avoir besoin d'injecter plusieurs champs du même type - String .

We should note that the bean name used in the qualifier is derived from the name of the method that creates the bean in the configuration class.

5. Using SpEL

Finally, let's see how we can use the Spring Expression Language to describe the code needed to load a resource file directly into a field in our class.

Let's use the @Value annotation to inject the file content into the field resourceStringUsingSpel:

public class LoadResourceAsStringIntegrationTest { private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content @Value( "#{T(com.baeldung.loadresourceasstring.ResourceReader).readFileToString('classpath:resource.txt')}" ) private String resourceStringUsingSpel; @Test public void givenUsingSpel_whenConvertingAResourceToAString_thenCorrect() { assertEquals(EXPECTED_RESOURCE_VALUE, resourceStringUsingSpel); } }

Here we have called ResourceReader#readFileToString describing the location of the file by using a “classpath:” –prefixed path inside our @Value annotation.

To reduce the amount of code in the SpEL, we've created a helper method in the class ResourceReader which uses Apache Commons FileUtils to access the file from the path provided:

public class ResourceReader { public static String readFileToString(String path) throws IOException { return FileUtils.readFileToString(ResourceUtils.getFile(path), StandardCharsets.UTF_8); } }

6. Conclusion

In this tutorial, we've reviewed some of the ways to convert a resource to a String.

First of all, we saw how to produce a Resource to access the file, and how to read from Resource to String.

Next, we also showed how to hide the resource loading implementation, and allow the string contents to be shared across beans by creating qualified beans in an @Configuration, allowing the strings to be autowired.

Enfin, nous avons utilisé SpEL, qui fournit une solution compacte et immédiate, même si elle nécessitait une fonction d'assistance personnalisée pour l'empêcher de devenir trop complexe.

Comme toujours, le code des exemples se trouve à l'adresse over sur GitHub