【问题标题】:css file not being found by thymeleaf百里香找不到css文件
【发布时间】:2019-03-26 12:30:03
【问题描述】:

我尝试做一个基于 HTML 模板生成 pdf 文件的简单 servlet。我尝试使用 Thymeleaf 和 FlyingSaucer,如example

在我的 template.hmtl 中,我的样式声明如下:

<link rel="stylesheet" type="text/css" media="all" href="style.css"/>

它永远不会被加载。没有错误,没有,只是导致 .pdf 缺少样式。如果我将样式文件的内容放入 template.HTML 它就像魅力一样。

如果我这样写:

<link rel="stylesheet" type="text/css" media="all" href="http://localhost:8080/MY_APP/resources/style.css"/>

它有效。

我所有的资源都在src/main/webapp/resources下。

【问题讨论】:

  • 你试过 Thymeleaf 的URL syntax 吗? (th:href="@{...}" 而不是普通的href
  • @JakubCh。没有运气
  • 我想指出,我并没有尝试将此模板显示为网页 - 我正在尝试基于该模板制作 pdf 文件并通过 servlet 将其提供给用户。
  • 我没有时间重现...但是您应该查看随附示例中的 cmets 部分。 2018 年 4 月 10 日和 4 月 25 日的这两个似乎解决了您正在努力解决的问题。
  • 嘿!已经做了。没有什么真正有用的。我找到了解决办法。

标签: servlets thymeleaf


【解决方案1】:

经过几个小时的研究,这就是我最终得到的结果。

对于 CSS - 我发现的唯一解决方案是将 CSS 放入 HTML 模板中。不优雅,但可以完成工作(至少现在是这样)。不是什么大问题,因为我使用这些模板来生成 pdf 文件。

但图像文件也存在同样的问题,但我能够以优雅的方式解决这个问题。就在这里!

问题是在 Web 容器中 Java 无法找到指向 .html 模板的文件。 所以我不得不编写自定义元素工厂扩展 ReplacedElementFactory。这是代码:

public class B64ImgReplacedElementFactory implements ReplacedElementFactory {

    public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
        Element e = box.getElement();
        if (e == null) {
            return null;
        }
        String nodeName = e.getNodeName();
        if (nodeName.equals("img")) {
            String attribute = e.getAttribute("src");
            FSImage fsImage;
            try {
                fsImage = buildImage(attribute);
            } catch (BadElementException e1) {
                fsImage = null;
            } catch (IOException e1) {
                fsImage = null;
            }
            if (fsImage != null) {
                if (cssWidth != -1 || cssHeight != -1) {
                    fsImage.scale(cssWidth, cssHeight);
                }
                return new ITextImageElement(fsImage);
            }
        }
        return null;
    }

    protected FSImage buildImage(String srcAttr) throws IOException, BadElementException {

            URL res = getClass().getClassLoader().getResource(srcAttr);
            if (res != null) {
                return new ITextFSImage(Image.getInstance(res));
            } else {
                return null;
        }
    }

    public void remove(Element e) {
    }

    public void reset() {
    }

    @Override
    public void setFormSubmissionListener(FormSubmissionListener listener) {
    }
}

代码生成PDF文件的用例:

ITextRenderer renderer = new ITextRenderer();
SharedContext sharedContext = renderer.getSharedContext();
sharedContext.setReplacedElementFactory(new B64ImgReplacedElementFactory());

自定义元素替换捕获所有出现的'img'节点,并使用ClasLoader获取资源路径,并基于返回FSImage,这就是我们所需要的。

希望有帮助!

【讨论】:

    猜你喜欢
    • 2021-01-09
    • 2018-02-03
    • 2020-12-30
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多