Search code examples
javahtmlspring-bootthymeleaf

logo is not displayed in thymleaf html template especially while downloading the pdf file


I am using thymleaf html template for generating pdf using java in spring boot. The logo and image are not loading. It throws an error. Refer to the code and error attached below.

Note: But the image is loading for preview and print interface. For download alone, I am facing a problem. File location: user:/src/main/resources/static/images$ ls logo.png user-image-2.jpg

// code

<div class="logo">
   <img th:src="@{/images/logo.png}" />
</div> 
   <img class="profilepic" th:src="@{/images/user-image-2.jpg}">

// code for generating pdf

 public File generatePdf(String id) throws Exception {
        Context context = initProfileContext(id);
        String html = loadAndFillTemplate(context);
        return renderPdf(id, html);
    }

    private File renderPdf(String id, String html) throws Exception {
        File file = File.createTempFile("profile_" + id, ".pdf");
        OutputStream outputStream = new FileOutputStream(file);
        ITextRenderer renderer = new ITextRenderer(20f * 4f / 3f, 20);
        renderer.setDocumentFromString(html);
        renderer.layout();
        renderer.createPDF(outputStream);
        outputStream.close();
        file.deleteOnExit();
        return file;
    }

    private Context initProfileContext(String id) {
        Context context = new Context();
        context.setVariable("profile", profileService.findById(id));
        return context;
    }

    private String loadAndFillTemplate(Context context) {
        return templateEngine.process("profile", context);
    }

// error

2020-10-29 16:53:13.799 ERROR 26176 --- [nio-5555-exec-2] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-5555-exec-2] Exception processing template "profile": Link base "/images/logo.png" cannot be context relative (/...) unless the context used for executing the engine implements the org.thymeleaf.context.IWebContext interface (template: "profile" - line 66, col 6)

org.thymeleaf.exceptions.TemplateProcessingException: Link base "/images/logo.png" cannot be context relative (/...) unless the context used for executing the engine implements the org.thymeleaf.context.IWebContext interface (template: "profile" - line 66, col 6)
        at org.thymeleaf.linkbuilder.StandardLinkBuilder.computeContextPath(StandardLinkBuilder.java:493) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.linkbuilder.StandardLinkBuilder.buildLink(StandardLinkBuilder.java:126) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.context.AbstractEngineContext.buildLink(AbstractEngineContext.java:167) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.standard.expression.LinkExpression.executeLinkExpression(LinkExpression.java:290) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:85) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.standard.expression.Expression.execute(Expression.java:109) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.standard.expression.Expression.execute(Expression.java:138) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:144) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:592) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1059) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1048) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
        at com.palmtree.matrimony.service.ProfilePdfService.loadAndFillTemplate(ProfilePdfService.java:50) ~[main/:na]
        at com.palmtree.matrimony.service.ProfilePdfService.generatePdf(ProfilePdfService.java:27) ~[main/:na]
org.thymeleaf.exceptions.TemplateProcessingException: Link base "/images/logo.png" cannot be context relative (/...) unless the context used for executing the engine implements the org.thymeleaf.context.IWebContext interface (template: "profile" - line 66, col 6)
        at org.thymeleaf.linkbuilder.StandardLinkBuilder.computeContextPath(StandardLinkBuilder.java:493)
        at com.palmtree.matrimony.controller.ProfileController.download(ProfileController.java:93) ~[main/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.9

Solution

  • Use Springboot classpath prefix.

    example:

    <img class="profilepic" th:src="@{classpath:images/user-image-2.jpg}">
    

    Ref: https://stackoverflow.com/a/47907375/3427462