Thymeleaf + Boot + AngularJS directives parser error

All we need is an easy explanation of the problem, so here it is.

this should be an easy one but I can’t find any solution for it.

I’m using Spring Boot 1.0.2 with Thymeleaf on Jetty to support my AngularJS application. But parser throws an exception when attribute directives are used.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
    <groupId>net.sourceforge.nekohtml</groupId>
    <artifactId>nekohtml</artifactId>
    <version>1.9.20</version>
</dependency>

Thymeleaf config

@Configuration
public class ThymeleafConfig {

    @Bean
    public ServletContextTemplateResolver templateResolver() {
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/templates/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("LEGACYHTML5");
        resolver.setCacheable(false);
        return resolver;
    }

    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");

        return messageSource;
    }
}

Thymeleaf is working ok but it has a problem with attribute directives like this Bootstrap UI example:

<div class="btn-group" dropdown is-open="true">
    <button type="button" class="btn btn-primary dropdown-toggle">
        Button dropdown<span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Action</a></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Another action</a></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Something else here</a></li>
        <li class="divider"></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Separated link</a></li>
    </ul>
</div>

I receive this error

org.xml.sax.SAXParseException: Attribute name "dropdown" associated with an element type "div" must be followed by the ' = ' character.

Where can I tweak Thymeleaf to accept those kind of attributes?

EDIT

I’ve added nekoHTML parser for LEGACYHTML5 but still no result.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

An even easier way to enable to LEGACYHTML5 in Spring Boot (at least for version 1.1.3.RELEASE that I checked) is to simply add the property

spring.thymeleaf.mode=LEGACYHTML5

in one of the places Spring Boot looks for properties

(the first that comes to mind is application.properties).

Spring Boot’s ThymeleafAutoConfiguration will take care of the rest

Method 2

In Spring Boot,

to use legacy HTML5 mode for Thymeleaf,

adding the following property in your ‘application.properties’:

spring.thymeleaf.mode=LEGACYHTML5

and adding the following dependency

in your ‘build.gradle’ (if you’re using Gradle):

compile(“net.sourceforge.nekohtml:nekohtml:1.9.21”)

will be sufficient.

You can find a working example as follows:

https://github.com/izeye/samples-spring-boot-branches/tree/thymeleaf

and a related post as follows:

http://izeye.blogspot.kr/2015/02/orgxmlsaxsaxparseexception-attribute.html

Method 3

Change your

@Bean
public ServletContextTemplateResolver templateResolver() { ... }

with

@Bean
public ServletContextTemplateResolver defaultTemplateResolver() { ... }

(notice default).

In your case, spring (boot) is not using your configuration for Thymeleaf thus you’re getting this “strange” error about parsing non-standard attribute (since default parser is XHTML).

Method 4

Without changing anything just make it XML compatible:

<div class="btn-group" dropdown="dropdown" is-open="true">
    <button type="button" class="btn btn-primary dropdown-toggle">Button dropdown <span       class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Action</a></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Another action</a></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Something else here</a></li>
        <li class="divider"></li>
        <li><a href="#" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Separated link</a></li>
    </ul>
</div>

Regards

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply