Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

In this tutorial, we’ll look at various ways to inject the contents of a resource containing text as a String into our Spring beans.

We'll look at locating the resource and reading its contents.

Also, we'll demonstrate how to share the loaded resources across several beans. We'll show this through the use of annotations related to dependency injection, though the same can also be achieved by using XML-based injection and declaring the beans in the XML property file.

2. Using Resource

We can simplify locating a resource file by using the Resource interface. Spring helps us find and read a resource using the resource loader, which decides which Resource implementation to pick depending on the path provided. The Resource is effectively a way of accessing the content of the resource, rather than the content itself.

Let's see some ways to acquire a Resource instance for resources on the classpath.

2.1. Using ResourceLoader

We can use the class ResourceLoader if we prefer to use lazy loading:

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

We can also inject the ResourceLoader into our bean with @Autowired:

@Autowired
private ResourceLoader resourceLoader;

2.2. Using @Value

We can inject a Resource directly into a Spring bean with @Value:

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

3. Converting from Resource to String

Once we have access to the Resource we need to be able to read it into a String. Let's create a ResourceReader utility class with a static method asString to do this for us.

First, we have to acquire an InputStream:

InputStream inputStream = resource.getInputStream();

Our next step is to take this InputStream and convert it to a String. We can use Spring's own FileCopyUtils#copyToString method:

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
}

There are many other ways of achieving this, for example, using copyToString of Spring's StreamUtils class

Let's also create another utility method readFileToString, which will retrieve the Resource for a path, and call the asString method to convert it to a String.

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

4. Adding a Configuration Class

If each bean had to inject resource Strings individually, there's a chance of both code duplication and more use of memory by beans having their own individual copy of the String.

We can achieve a neater solution by injecting the resource's content to one or multiple Spring beans upon loading the application context. In this way, we can hide the implementation details for reading the resource from the various beans which need to use this content.

@Configuration
public class LoadResourceConfig {

    // Bean Declarations
}

4.1. Using a Bean Holding the Resource String

Let's declare beans to hold the resource content in an @Configuration class:

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

Let's now inject the registered beans to the fields by adding an @Autowired annotation:

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);
    }
}

In this case, we use the @Qualifier annotation and the name of the bean, as we may need to inject multiple fields of the same typeString.

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.

Finally, we used SpEL, which provides a compact and immediate solution, though it required a custom helper function to stop it from becoming too complex.

As always, the code for the examples can be found over on GitHub

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Generic footer banner
Comments are closed on this article!