0

I am building a Spring web application with thymeleaf. I made the configurations based on xml and everything works except css resource reference. I am using spring version 5.0.1.RELEASE and thymeleaf version 3.0.1.RELEASE.

The login page is working but the css does not load. I think the problem is from the configurations.

Here is the project layout:

Spring
|- src/main/java/
|  |- com.web
|  |
|- WebContent
|  |- META-INF
|  |
|  |- WEB-INF
|     |- WEB-INF
|        |- lib
|        |- resources
|           |- css
|              |- style.css
|           |- views
|              |- login
|                 |- login.html
|        |- web.xml
|        |- applicationConfig-mvc.xml
|        |- applicationContext.xml

My web.xml is

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>

</web-app>

My applicationContext.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <import resource="applicationConfig-mvc.xml" />

    <context:annotation-config />
    <tx:annotation-driven transaction-manager="transactionManager" />

    <context:component-scan base-package="com.web" />

</beans>

And my applicationConfig-mvx.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                           http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <mvc:annotation-driven />
    <mvc:resources location="/resources/" mapping="/resources/**" />
    <mvc:resources location="/resources/css/" mapping="/resources/css/**" />
    <bean id="templateResolver"
        class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
        <property name="prefix" value="/WEB-INF/resources/views/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML5" />
        <property name="cacheable" value="true" />
    </bean>
    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
    </bean>
    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="order" value="1" />
        <property name="viewNames" value="*" />
    </bean>
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
    </bean>
</beans>

Login.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login page</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../../css/style.css"
    th:href="@{/resources/css/style.css}" />
</head>
<body>
    <h1>Login page</h1>
    <p th:if="${loginError}" class="error">Wrong user or password</p>
    <form th:action="@{/login}" method="post">
        <label for="username">Username</label>:
        <input type="text" id="username" name="username" autofocus="autofocus" />
        <br />
        <label for="password">Password</label>:
        <input type="password" id="password" name="password" />
        <br />
        <input type="submit" value="Log in" />
    </form>
    <p>
        <a href="../index.html" th:href="@{/}">Back to home page</a>
    </p>
</body>
</html>

If you any comments on the structure, configurations or naming, please help me because I am learning how to do it right now. Thank you!

2
  • Perhaps putting a type would help? <link rel="stylesheet" href="../../css/style.css" type="text/css" th:href="@{/resources/css/style.css}" /> Commented Nov 8, 2017 at 23:32
  • No, this not working. I think the problem is from the configurations where I am declaring resource mapping in applicationConfig-mvx.xml. Commented Nov 9, 2017 at 7:36

1 Answer 1

2

I had the same problem in the beginning :)

Put your css, js, images, ... inside a "static" folder within the resources directory. Otherwise thymeleaf can't find it.
It should look like this: resources -> static -> css -> style.css
You can now access the css via href="css/style.css"
The same goes for js, images, etc.

EDIT: Added pictures of a sample project

Project structure

Html page

Check out the demo project under Github ! :)

Sign up to request clarification or add additional context in comments.

4 Comments

Can you tell me what must be in the configuration file for <mvc:resources location="/resources/" mapping="/resources/**" /> and what will be the href in the html. Something like <link rel="stylesheet" href="css/style.css" type="text/css" th:href="@{/resources/static/css/style.css}" /> ? Thank you
You don't need to specify the location with my suggested configuration. You can either use th:href=... or href=... Using both doesn't make sense in my eyes.
Please see the edit of my original answer. I added images of my project structure and a sample html file. I tested it and it works on my setup. Try to specify your stylesheet only with href="css/style.css" (remove the th:href="...") and see if that works. If not, tell me and we will find another solution. Cheers
Thank you so much. You are perfect, really! I found another solution if the project is Dynamic Web Project and if you are using WebContent and WEB-INF, the resource directory should be in the root on the WebContent dir and in the html <link th:href="@{/resources/css/style.css}" rel="stylesheet" /> So the project structure is: WebContent META-INF WEB-INF templates/* resources css/*

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.