Pell000
Pell000

Reputation: 77

How to get static resource (js, css) as ClassPathResource in Spring Boot?

I have a requirement to be able to generate PDFs from a Spring Boot Template. For this, I am using a PDF rendering library (FlyingSaucer) which mostly does the job correctly. There is one issue, however: when I have "href" tags on the page, they do not resolve correctly when the PDF renderer tries to render the HTML. For example, if I have the following code:

<link rel="stylesheet" type="text/css" th:href="@{/css/index.css}" />

It resolves correctly in the browser, but when I try to retrieve this as a ClassPath resource using the following code:

new ClassPathResource("/css/index").getInputStream()

Spring Boot says that the file does not exist. This is odd to me, as I thought that Spring Boot adds all static content to the classpath.

Below is the folder structure of my project, which (I think) follows the correct Spring Boot convetion:

Project Structure

Can I get a handle on some Spring resource (through autowiring, the application context, etc) to resolve these URLs just as it does when the browser requests them? I could probably get around this by hardcoding "resources/static/" to the beginning of the url string, but I'd prefer a more dynamic solution.

Upvotes: 0

Views: 3111

Answers (2)

Pell000
Pell000

Reputation: 77

After trying out various solutions, I managed to come up with one that, despite the answer given by Amant Simgh, doesn't require me to hardcode any paths. I threw a bunch of things at my solution (using images, deploying to a tomcat container, running "bootRun", using webjars), and it seemed to work in every case.

Internally, Spring Boot uses the ResourceHttpRequestHandler class to resolve resources. This allows Spring Boot applications to @Autowire a ResourceHttpRequestHandler bean. So, in order to get a static resource from the backend from java code, you can do the following:

@Autowired
ResourceHttpRequestHandler resourceHandler;

String uri = "/css/mycss.css";
Resource resource;
for (ResourceResolver resourceResolver : resourceHandler.getResourceResolvers())
{
    resource = resourceResolver.resolveResource(null, uri, resourceHandler.getLocations(), null);
    if (resource != null)
        break;
}

This is essentially what SpringBoot is doing when you request a static resource.

IMPORTANT: if your application has a context path (i.e., you deploy a "myapp" application, then the context path will be "/myapp/"), then you must remove the context path from the URI in the example above. Fortunately, this can be easily done through the following:

ServletContext context = // get servlet context somehow
String uriWithoutContext = uri.replace(context.getContextPath(), "");

Upvotes: 0

amant singh
amant singh

Reputation: 518

Use this:

new ClassPathResource("static/css/index.css").getInputStream();

Upvotes: 2

Related Questions