Gunnar Hillert

Gunnar Hillert

Java Champion, full-stack Spring + Angular aficionado & 2019 Kona IRONMAN Finisher.

From Spring's Resource to Micronaut's Readable

Spring Framework has the Resource abstraction that gives you a convenient way to load resources from the classpath (inside Jar files) or the filesystem in an implementaton-agnostic manner.

2-Minute Read

Kailua-Kona Coastline 2020

Spring Framework has the Resource abstraction that gives you a convenient way to load resources from the classpath (inside Jar files) or the filesystem in an implementaton-agnostic manner, e.g.:

  • classpath:some/amazing/resource/to-load.data

  • file:/some/cool/filesystem/resource.txt

Any object that can return Resources needs to implement the ResourceLoader interface. See the respective Spring documentation for details on Spring’s Resource abstraction.

This abstraction is extremly convenient when your application provides any type of configurable data that needs to be part of the classpath (inside your executable Jar) and/or in the general file-system such as:

  • Default data

  • Demo data

  • Configuration files

If your background is mostly in Spring, you will readily discover that Micronaut has the equivalent of Spring’s ResourceLoder, io.micronaut.core.io.ResourceLoader. But what about the Resource interface?

Readable to the rescue

Micronaut provides the io.micronaut.core.io.Readable interface that works similar and also provides an "Abstraction over File and URL based I/O". To illustrate how you can use Micronaut’s Readable, I have created a quick demo hosted on GitHub:

The super-simple demo has 2 REST endpoints:

The used images are fully configurable via the application.yml file. By default the images are served from the classpath and as such are part of the generated Jar file using the classpath: prefix.

micronaut:
  application:
    name: Loading Resources in Micronaut using Readable Demo
images:
  image-file: "classpath:images/bismarckia-nobilis.jpg"
  # image-file: "file:/path/to/images/bismarckia-nobilis.jpg"
  other-files:
    - "classpath:images/bismarckia-nobilis.jpg"
    - "classpath:images/bamboo.jpg"
    - "classpath:images/hibiscus.jpg"

If you like to use images from the filesystem, simply provide those image paths prefixed with file:. Additionally, you can also provide the paths to be used, e.g. via the command line:

java -jar target/resource-readable-demo-0.1.jar --images.image-file=file:/my/path/to/some/awesome-image.jpg

or

./mvnw mn:run -Dmn.appArgs="--images.image-file=file:/my/path/to/some/awesome-image.jpg"

In the app itself, you get access to the image data via my custom ImageConfig class that is annotated with @ConfigurationProperties.

The class provides 2 properties:

  • Readable imageFile

  • List<Readable> otherFiles

You can then simply inject ImageConfig into my services and retrive the corresponding InputStream. Mission accomplished!

comments powered by Disqus

Recent Posts

Categories

About

This is a blog of Gunnar Hillert.