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

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until tomorrow:

>> GET ACCESS NOW

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. Introduction

In this tutorial, we'll demonstrate various ways to access and load the contents of a file that's on the classpath using Spring.

Further reading:

A Guide to the ResourceBundle

It's always challenging to maintain and extend multilingual applications. This article covers how to use the ResourceBundle to cope with the varieties that come up when you need to provide the same content to different cultures.

Load a Resource as a String in Spring

Learn how to inject the contents of a resource file into our beans as a String, with Spring's Resource class making this very easy.

2. Using Resource

The Resource interface helps in abstracting access to low-level resources. In fact, it supports the handling of all kinds of file resources in a uniform manner.

Let's start by looking at various methods to obtain a Resource instance.

2.1. Manually

For accessing a resource from the classpath, we can simply use ClassPathResource:

public Resource loadEmployeesWithClassPathResource() {
    return new ClassPathResource("data/employees.dat");
}

By default, ClassPathResource removes some boilerplate by selecting between the thread's context classloader and the default system classloader.

However, we can also indicate the classloader to use either directly:

return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());

Or indirectly through a specified class:

return new ClassPathResource(
  "data/employees.dat", 
  Employee.class.getClassLoader());

Note that from Resource, we can easily jump to Java standard representations like InputStream or File.

Another thing to note here is that the above method works only for absolute paths. If we want to specify a relative path, we can pass a second class argument. The path will be relative to this class:

new ClassPathResource("../../../data/employees.dat", Example.class).getFile();

The file path above is relative to the Example class.

2.2. Using @Value

We can also inject a Resource with @Value:

@Value("classpath:data/resource-data.txt")
Resource resourceFile;

@Value supports other prefixes too, like file: and url:.

2.3. Using ResourceLoader

If we want to lazily load our resource, we can use ResourceLoader:

@Autowired
ResourceLoader resourceLoader;

Then we retrieve our resource with getResource:

public Resource loadEmployeesWithResourceLoader() {
    return resourceLoader.getResource(
      "classpath:data/employees.dat");
}

Note too that ResourceLoader is implemented by all concrete ApplicationContexts, which means that we can also simply depend on ApplicationContext if that suits our situation better:

ApplicationContext context;

public Resource loadEmployeesWithApplicationContext() {
    return context.getResource("classpath:data/employees.dat");
}

3. Using ResourceUtils

As a caveat, there is another way to retrieve resources in Spring, but the ResourceUtils Javadoc is clear that the class is mainly for internal use.

If we see usages of ResourceUtils in our code:

public File loadEmployeesWithSpringInternalClass() 
  throws FileNotFoundException {
    return ResourceUtils.getFile(
      "classpath:data/employees.dat");
}

We should carefully consider the rationale, as it's probably better to use one of the standard approaches above.

4. Reading Resource Data

Once we have a Resource, it's easy for us to read the contents. As we have already discussed, we can easily obtain a File or an InputStream reference from the Resource.

Let's imagine we have the following file, data/employees.dat, on the classpath:

Joe Employee,Jan Employee,James T. Employee

4.1. Reading as a File

Now we can read its contents by calling getFile:

@Test
public void whenResourceAsFile_thenReadSuccessful() 
  throws IOException {
 
    File resource = new ClassPathResource(
      "data/employees.dat").getFile();
    String employees = new String(
      Files.readAllBytes(resource.toPath()));
    assertEquals(
      "Joe Employee,Jan Employee,James T. Employee", 
      employees);
}

Although, it should be noted that this approach expects the resource to be present in the filesystem and not within a jar file.

4.2. Reading as an InputStream

Let's say though, that our resource is inside a jar.

Then we can instead read a Resource as an InputStream:

@Test
public void whenResourceAsStream_thenReadSuccessful() 
  throws IOException {
    InputStream resource = new ClassPathResource(
      "data/employees.dat").getInputStream();
    try ( BufferedReader reader = new BufferedReader(
      new InputStreamReader(resource)) ) {
        String employees = reader.lines()
          .collect(Collectors.joining("\n"));
 
        assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
    }
}

5. Conclusion

In this brief article, we've examined a few ways to access and read a resource from the classpath using Spring. This includes eager and lazy loading, and on the filesystem or in a jar.

As always, all of these examples are available over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until tomorrow:

>> GET ACCESS NOW

Generic footer banner
Comments are closed on this article!