0

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.

2 Answers 2

2

Use this:

new ClassPathResource("static/css/index.css").getInputStream();
Sign up to request clarification or add additional context in comments.

3 Comments

Is there some way that I dont have to hard code "/static"?
In spring, the standard classpath for resources is "src/main/resources". So you will have to append the full path after that. Obviously you can get advantage of pattern matching etc but in the end you will have to provide it anyway.
See my answer. I managed to do this without providing the full path by using some Spring components. I think "src/main/resources/static" is also put on the class path. If my understanding is wrong, however, please let me know.
0

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(), "");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.