Spring Boot + Thymeleaf CSS不适用于模板

时间:2018-11-08 08:28:59

标签: css spring-boot thymeleaf

我正在评估从模板生成pdf的Thymeleaf和飞碟,并且在将CSS应用于Thymeleaf模板时遇到问题。我已经阅读了相关的问题和答案hereherehere;但是没有建议的解决方案可以解决我的问题。

这是我的资源文件夹的样子:

enter image description here

因此,我正在使用Spring将要查找的默认目录。这就是head标签在我的template.html中的样子:

<head>
    <title>Spring Boot and Thymeleaf Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" type="text/css" href="../static/css/style.css" th:href="@{/css/style.css}"/> 
</head>

如果我在template.html中内联css,则生成的pdf文件将被正确设置样式(因此,生成pdf的方式应该没有问题)。但是,当我尝试如上所述链接到css文件时,未对生成的pdf进行样式设置(因此未应用css)。

最后,我可以在http://localhost:8080/css/style.css访问我的css文件,因此Spring提供静态内容似乎没有问题。

为完整起见,这就是我生成pdf的方式:

private final SpringTemplateEngine templateEngine;
private final Log log;

@Autowired
public PdfGenerator(SpringTemplateEngine templateEngine) {
    this.templateEngine = templateEngine;
    log = LogFactory.getLog(getClass());
}

public void generate(HttpServletRequest servletRequest, HttpServletResponse servletResponse, ServletContext servletContext) {
    // Parse the pdf template with Thymeleaf
    Locale locale = getLocale(servletRequest);
    WebContext context = new WebContext(servletRequest, servletResponse, servletContext, locale);
    context.setVariable("user", buildDummyUser());
    context.setVariable("discounts", buildDummyDiscounts());
    String html = templateEngine.process("template", context);

    // Create the pdf with Flying Saucer
    try (OutputStream outputStream = new FileOutputStream("generated.pdf")) {
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(html);
        renderer.layout();
        renderer.createPDF(outputStream);
    } catch (IOException | DocumentException e) {
        log.error("Error while generating pdf", e);
    }
}

我使用的是WebContext而不是Context,因为我遇到了Context的以下错误:

org.thymeleaf.exceptions.TemplateProcessingException: Link base "/css/style.css" cannot be context relative (/...) unless the context used for executing the engine implements the org.thymeleaf.context.IWebContext interface

我在这里缺少什么,为什么我的style.css不适用于template.html

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,并且我也尝试使用thymeleaf模板解析器生成pdf。我对百里香和Spring框架做了很多研究,尝试了WebContext,尝试了HttpServletRequest,还尝试了一些也不起作用的Spring Thymeleaf集成解决方案。因此,我认为这不是语法错误,最终我最终使用了绝对路径而不是相对路径。 Url for reference

这就是我假设的原因,可以说我们的资源是在localhost:8080/myapp/css/style.css上提供的。请求资源的相对路径实际上取决于它所相对的上下文。 例如,普通的百里香叶模型Veiw在浏览器中以html页面形式返回给客户端,因此在这种情况下,上下文将是请求主机名,端口和应用程序上下文(例如:localhost:8080 / myapp)。相对路径将基于此。因此,如果相对路径为/css/style.css,则上下文+相对路径将为localhost:8080/myapp/css/style.css

与Web上下文不同,在我们的示例中,脱机模板位于服务器后端,因此我认为上下文是服务器运行上下文,即本地服务器路径+ appcontext(例如:D:/ myServer / apps / myapp ),相对路径/css/style.css就是D:/myServer/apps/myapp/css/style.css,这没有意义。为了使用静态资源,我必须通过它的绝对路径。

我开始使用:

<link rel="stylesheet" type="text/css" th:href="@{http://localhost:8080/myapp/css/style.css}"/>

工作正常,但是如果有多个主机名或服务器在代理上运行,那将是一个硬编码的解决方案。最好知道用户请求的实际基本URL是什么。所以我们真的不能摆脱HttpSevletRequest。

这是我的代码:

1.Config资源处理程序:

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/css/**")
    .addResourceLocations("classpath:/css/")
            .setCachePeriod(31556926);
}
  1. 从HttpServletRequest获取基本URL,您可以将其注入方法或自动连接到服务类中,或者从RequestContextHolder获取。我在Service类中编写了此代码:

    private static String getCurrentBaseUrl() {
    ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest req = sra.getRequest();
    return req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath();
    } 
    
  2. 这是我在课堂上使用模板引擎的地方:

        Context context = new Context();
        context.setVariable("variales", variables);
        context.setVariable("baseUrl", getCurrentBaseUrl());
        String content = springTemplateEngine.process("myTemplate",context);
    
  3. 在我的模板中,我使用绝对的CSS网址,如下所示:

    <link type="stylesheet" th:src="@{|${baseUrl}/css/style.css|}" />
    

答案 1 :(得分:0)

语法看起来不错,所以问题不在语法上。

此外,如果没有pop up the modal接口,就不能使用@{...}语法,因此您会遇到此异常。

答案 2 :(得分:0)

我有一个类似的问题-我的CSS没有应用到我的模板页面。

我的问题是css文件为css sass格式

.table
   margin: 0 0 40px 0

当我将其转换为普通的CSS格式时

 .table {
  margin: 0 0 40px 0;
  }

有效

答案 3 :(得分:0)

我通过更改 href 中的路径结构解决了这个问题。我和你有相同的目录结构(html文件在模板文档中,css文件在静态文档中)。

<head>
    <title>Spring Boot and Thymeleaf Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" type="text/css" href="/css/style.css"/> 
</head>

它可能会帮助您将 css 应用到您的 html 页面。