Reputation: 77
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:
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
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
Reputation: 518
Use this:
new ClassPathResource("static/css/index.css").getInputStream();
Upvotes: 2