Spring boot + thymeleaf in IntelliJ: cannot resolve vars
Asked Answered
A

16

42

I'm writing a short web form application using spring boot and thymeleaf on IntelliJ, but it seems that in the html file, all fields in the model cannot be resolved. Here is my code:

Controller class:

@Controller
public class IndexController{

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(){
        return "index";
    }

    @RequestMapping(value="/", method = RequestMethod.POST)
    public String addNewPost(@Valid Post post, BindingResult bindingResult, Model model){
        if(bindingResult.hasErrors()){
            return "index";
        }
        model.addAttribute("title",post.getTitle());
        model.addAttribute("content",post.getContent());
        return "hello";
    }
}

Model Class:

public class Post {

    @Size(min=4, max=35)
    private String title;

    @Size(min=30, max=1000)
    private String content;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Then is the index.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Spring Framework Leo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>

<h3>Spring Boot and Thymeleaf</h3>


    <form action="#" th:action="@{/}"  th:object="${post}" method="post">
        <table>
            <tr>
                <td>Title:</td>
                <td><input type="text" th:field="*{title}" /></td>
                <td th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Title error message</td>
            </tr>
            <tr>
                <td>Content:</td>
                <td><input type="text" th:field="*{content}" /></td>
                <td th:if="${#fields.hasErrors('content')}" th:errors="*{content}">Content error message</td>
            </tr>
            <tr>
                <td><button type="submit">Submit post</button></td>
            </tr>
        </table>
    </form>

There are always red lines under "post", "title" and "content", but I don't know how to solve it. Is it a problem of IntelliJ or just a problem of my code?

Aceves answered 2/8, 2016 at 1:44 Comment(1)
This should be fixed in IntelliJ 2013.3, see my edited answer.Anneal
A
28

Prerequisites

  • Thymeleaf plugin is installed

  • The html element has an XML namespace declaration for th that is set to http://www.thymeleaf.org (with www.), for example:

    <html xmlns:th="http://www.thymeleaf.org">
    

IntelliJ version >= 2017.3

Detection should work automatically. However, some people complain that it still does not work for them), the issue IDEA-132738 should be fixed (@FloatOverflow: "I confirm that in version 2017.3 build 25.Oct.2017 the problem has been solved"):

Status 2017.3

Support for Spring Boot autoconfigured MVC applications is complete, all bundled autoconfiguration view types are supported.

Fix versions: 2017.3

If variables are not automatically detected you can still add the @thymesVar annotation as shown below.

IntelliJ version < 2017.3

It is, as Andrew wrote, a known error IDEA-132738. There is a workaround how to get rid of the error marks in the IDE. IntelliJ also supports the semi-automatic generation of the below mentioned code:

You can use Alt+Enter shortcut to invoke intention "Declare external variable in comment annotation" in order to get rid of "unresolved model attribute" in your views.

Add the following code to your html file:

<!--/* Workaround for bug https://youtrack.jetbrains.com/issue/IDEA-132738 -->
    <!--@thymesVar id="post" type="your.package.Post"-->
    <!--@thymesVar id="title" type="String"-->
    <!--@thymesVar id="content" type="String"-->
<!--*/-->

If you use extensions objects constructed automatically by ThymeLeaf, such as #temporals from thymeleaf-extras-java8time for conversion of java.time objects:

<span th:text="${#temporals.format(person.birthDate,'yyyy-MM-dd')}"></span>

and IntelliJ cannot resolve them, use similar code, and just add # in front of the object name:

<!--@thymesVar id="#temporals" type="org.thymeleaf.extras.java8time.expression.Temporals"-->
Anneal answered 28/6, 2017 at 13:35 Comment(6)
I confirm that in version 2017.3 build 25.Oct.2017 the problem has been solved!Joelynn
@Joelynn I'm running 2017.3 and my objects are still underlined. Any idea what I might be doing wrong? For example, in below code both test and name are underlined. <h1 th:text="'Thanks for helping us test, ' + ${test.name} + '!'"></h1>Ritch
@Ritch I recommend you to create a Minimal, Complete and Verifiable example (stackoverflow.com/help/mcve) and report it to Jetbrains. You may either add it to the above mentioned issue, or create a new one.Anneal
The answer is helpful with version IntelliJ IDEA 2017.3.4 UltimateG
In 2019.3.2 the bug still exists.Month
@Month I recommend you to create a Minimal, Complete and Verifiable example (stackoverflow.com/help/mcve) and report it to Jetbrains. You may either add it to the above mentioned issue, or create a new one.Anneal
W
54

Update

TL;DR: skip to accepted answer below: https://mcmap.net/q/382170/-spring-boot-thymeleaf-in-intellij-cannot-resolve-vars

As mentioned in the comments by multiple people, this solution is not correct. The Thymeleaf documentation (see http://thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html), have in all their examples a version with www. included:

<html xmlns:th="http://www.thymeleaf.org">

See also the Standard-Dialect.xml on Github, which declares namespace-uri as:

namespace-uri="http://www.thymeleaf.org" 

Original Answer

I had two different portions of code: the first was showing the error and the second was not doing it. I observed that there is a difference in the xmlns:th attribute.

First Page: Not working!

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">

Second Page: Working!

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://thymeleaf.org">

I removed the www. and it works for me!

Weiser answered 10/5, 2019 at 16:21 Comment(9)
This is what worked for me and i'm using IntelliJ 2018+Big
An unbelievable solution - but it works. I'm using IntelliJ 2019.1.3 UE.Mallette
This removes the underline of the variables, because the th namespace becomes invalid at all. With the above "solution" all th attributes should have an error now: Attribute th:**** is not allowed here.Talanta
lul, thanks for this xD Solved it for me with 2019.something, tooCarbaugh
This looks suspicious. It is against the Thymeleaf documentation (thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html), where they have in all their examples <html xmlns:th="http://www.thymeleaf.org">. You can see it also here: github.com/thymeleaf/thymeleaf/blob/3.0-master/src/main/…: namespace-uri="http://www.thymeleaf.org"Anneal
As @Talanta said, by doing that you just broke your namespace definition... Same results would be if you put there: xmlns:th="mybrokenuri.org">Verecund
I'm agree with @RiZKiT. This solution is not Correct!Purlieu
@RiZKiT, and yet, it works for me with IntelliJ 2019.1Campania
I agree with @RiZKiT.Opt
A
28

Prerequisites

  • Thymeleaf plugin is installed

  • The html element has an XML namespace declaration for th that is set to http://www.thymeleaf.org (with www.), for example:

    <html xmlns:th="http://www.thymeleaf.org">
    

IntelliJ version >= 2017.3

Detection should work automatically. However, some people complain that it still does not work for them), the issue IDEA-132738 should be fixed (@FloatOverflow: "I confirm that in version 2017.3 build 25.Oct.2017 the problem has been solved"):

Status 2017.3

Support for Spring Boot autoconfigured MVC applications is complete, all bundled autoconfiguration view types are supported.

Fix versions: 2017.3

If variables are not automatically detected you can still add the @thymesVar annotation as shown below.

IntelliJ version < 2017.3

It is, as Andrew wrote, a known error IDEA-132738. There is a workaround how to get rid of the error marks in the IDE. IntelliJ also supports the semi-automatic generation of the below mentioned code:

You can use Alt+Enter shortcut to invoke intention "Declare external variable in comment annotation" in order to get rid of "unresolved model attribute" in your views.

Add the following code to your html file:

<!--/* Workaround for bug https://youtrack.jetbrains.com/issue/IDEA-132738 -->
    <!--@thymesVar id="post" type="your.package.Post"-->
    <!--@thymesVar id="title" type="String"-->
    <!--@thymesVar id="content" type="String"-->
<!--*/-->

If you use extensions objects constructed automatically by ThymeLeaf, such as #temporals from thymeleaf-extras-java8time for conversion of java.time objects:

<span th:text="${#temporals.format(person.birthDate,'yyyy-MM-dd')}"></span>

and IntelliJ cannot resolve them, use similar code, and just add # in front of the object name:

<!--@thymesVar id="#temporals" type="org.thymeleaf.extras.java8time.expression.Temporals"-->
Anneal answered 28/6, 2017 at 13:35 Comment(6)
I confirm that in version 2017.3 build 25.Oct.2017 the problem has been solved!Joelynn
@Joelynn I'm running 2017.3 and my objects are still underlined. Any idea what I might be doing wrong? For example, in below code both test and name are underlined. <h1 th:text="'Thanks for helping us test, ' + ${test.name} + '!'"></h1>Ritch
@Ritch I recommend you to create a Minimal, Complete and Verifiable example (stackoverflow.com/help/mcve) and report it to Jetbrains. You may either add it to the above mentioned issue, or create a new one.Anneal
The answer is helpful with version IntelliJ IDEA 2017.3.4 UltimateG
In 2019.3.2 the bug still exists.Month
@Month I recommend you to create a Minimal, Complete and Verifiable example (stackoverflow.com/help/mcve) and report it to Jetbrains. You may either add it to the above mentioned issue, or create a new one.Anneal
M
17

This is a problem with IntelliJ: IDEA-132738.

Basically IntelliJ is unable to locate the model variables when Spring Boot has been used to autoconfigure everything.

Mills answered 2/8, 2016 at 12:35 Comment(5)
I'm using IntelliJ 2017.2 and this issue still exists in the IDE. This is so dominating when I visit my html files. Why JetBrains guys haven't yet fixed this for Thymeleaf support?Communist
@MAC This should be fixed in IntelliJ 2013.3, see my edited answer.Anneal
@HonzaZidek I still have it in 2019.2 for some reason... Also, I've checked thier bug tracker website, and it seems that there are still users who have the smae problem with newer versions like 2017, etc.Valuator
@HaimLvov I recommend you to create a Minimal, Complete and Verifiable example (stackoverflow.com/help/mcve) and report it to Jetbrains. You may either add it to the issue youtrack.jetbrains.com/issue/IDEA-132738, or create a new one.Anneal
@HaimLvov I think they will ignore your comment under IDEA-132738. See what Yann Cebron commented on 13 Nov 2017 10:08: PLEASE stop adding comments to this issue. If you encounter problems, please file a NEW ISSUE with attached minimal sample project. Please note that static web resource directories currently still have to be setup manually in Web Facet once, see IDEA-121038.Anneal
A
13

I want to add one more thing. As stated above, the issue has been fixed in IntelliJ 2017.3. I can also confirm this.

However, I noticed that this is only true if you define all your attributes directly inside the responsible controller function, like e.g. this:

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

If you are using a sub-function in which you define the model attributes (see Example below), IntelliJ can still not find the attributes in the HTML template.

Example:

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    return doIt(model);
}

private String doIt(Model model) {
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

So, always make sure you put your code directly inside the view function!

Adriannaadrianne answered 15/12, 2017 at 8:35 Comment(3)
And/Or if your RequestMappings are in Kotlin, the IDE doesn't see the attributes much like using the private method.Unveiling
@Unveiling do you know if there is any way around this problem? I just ran into this issue.Interphase
I can confirm that as of IntelliJ 2019.3.2 Ultimate, this workaround (using model.addAttribute()) is still necessary to get IntelliJ to recognize the form object. Or the other workaround suggested by Honza Zidek, using a @thymesVar comment annotation.Month
U
5

Manually enabling it, worked for me in Intellij 2018.1.6 Ultimate Edition. Steps followed

  1. Open the Project tool window (e.g. View | Tool Windows | Project).

  2. Right-click the project or the module folder and select Add Framework Support.

  3. In the left-hand pane of the Add Frameworks Support dialog that opens, select the Thymeleaf checkbox.

Official reference : https://www.jetbrains.com/help/idea/thymeleaf.html#0c8052be

Urceolate answered 1/4, 2019 at 14:5 Comment(2)
I'm here because the Add Frameworks Support dialog doesn't show thymeleaf, only groovy and mavenDebouch
This is what ultimately worked for me. One thing to note, once I added the framework support I had to do FIle->Invalidate Caches and Restart.Uniformitarian
B
1

In my case the problem was that I had the following in my application.properties:

spring.thymeleaf.prefix=file:src/main/resources/templates/

spring.thymeleaf.cache=false

Once I removed these properties, the spring mvc mappings are detected by Intellij again (in the Ultimate version, I'm using 2018.1). Also the thymeleaf objects are working now.

I used these properties to support fast development where a refresh would reload the thymeleaf template files.

To solve this issue, I use the following -D option in my run configuration of my spring boot application to tell spring boot where my property files are during development:

-Dspring.config.location=/dev/application/conf/application.properties
Bangweulu answered 3/5, 2018 at 11:58 Comment(0)
C
1

There is one more interesting situation ,if you DONT return directly the object from your controller ,Intellij will not recognize the variable ,but she will still work

Crossrefer answered 28/3, 2019 at 10:50 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker.Cornwall
E
1

This problem comes from thymeleaf web link.

The problem:xmlns:th="http://www.thymeleaf.org"

This is problem link:

This is error area:

The solution: xmlns:th="http://thymeleaf.org"

Solution link

Error is gone

Elevenses answered 16/6, 2021 at 21:1 Comment(1)
now you have warning about invalid th:style attribute, so not really solutionScar
D
0

For those who come from ReactJS and want to use Springboot as a backend.

I forgot to add html boilerplate code in the html, that's why I'm seeing this error. don't forget adding boilerplate code.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <script src="index.js"></script>
  </body>
</html>
Dincolo answered 30/8, 2021 at 15:10 Comment(0)
S
0

This was happening to me on Ultimate 2021.2.1.

In one @GetMapping method, I used @ModelAttribute('transactionForm'). The Thymeleaf page for that method didn't have errors.

But in another @GetMapping method, I didn't use @ModelAttribute('newCustomerForm'). The Thymeleaf page for that method had the errors. When I added the @ModelAttribute to the method, the errors went away. And when I took it out, the errors came back.

I know Spring MVC doesn't require the @ModelAttribute if the name of the model is the same as the class name. So I shouldn't have to do this, and I'm only doing this to appease the IDE.

Slily answered 10/9, 2021 at 6:18 Comment(0)
S
0

I had the same problem and fixed it (ultimate 2021.3.2). Intellij has a hard time guessing the type of the attribute(s).

Keep www in the namespace xmlns:th="http://www.thymeleaf.org" otherwise Intellij won't parse thymeleaf tags

If you initialize one model in a controler,

  • don't use a method's return, declare a variable

    String titre=post.getTitle();
    model.addAttribute("title",titre);
    
  • don't add attributes through sub methods, keep it in the main block

    @GetMapping("/book")
    public String ver(Model model) {
    ...
    model.addAttribute("title", title);
    return "frontpage";
    }
    
  • and don't use complex operator like the ternary one

    model.addAttribute("titles", titles.size() > 0 ? titles : null);
    

If you initialize 2 or 3 models in you controler, don't push null values

model.addAttribute("employees", null); 
Soupandfish answered 9/2, 2022 at 0:9 Comment(0)
T
0

I was resolve like following click Alt + Enter

Lets try it!!!

enter image description here

Timmie answered 25/4, 2022 at 15:14 Comment(0)
H
0

In spring boot + thymeleaf, after adding a custom bean, everything worked. Hope it helps someone!

https://i.sstatic.net/M8Z6l.png

Histogen answered 12/3, 2023 at 19:44 Comment(0)
N
0

I was able to fix this with using another spring-boot-parent version

(2.3.2 working version) previously was 2.7.15 (not working)

<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
Neale answered 20/9, 2023 at 11:48 Comment(0)
F
0

All problems can be fixed this bean related to Thymeleaf

@Bean
public ClassLoaderTemplateResolver templateResolver() {
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    templateResolver.setPrefix("classpath:/templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode(TemplateMode.HTML);
    templateResolver.setCharacterEncoding("UTF-8");
    templateResolver.setCheckExistence(true);
    return templateResolver;
}
Freestanding answered 7/10, 2023 at 7:27 Comment(0)
G
-2

This feature is supported in the Ultimate edition only.

Click here for more details

Gascon answered 6/4, 2018 at 8:54 Comment(2)
This does not provide a complete answer to the question, although it may be relevant. When you have earned enough reputation, you will be able to post information such as this as comments to the question or other answers, but you should not post answers unless they address the question that was asked directly.Cordeelia
this is look like Comment. this not right way to paste your answer refer how to write good answer stackoverflow.com/help/how-to-answerKinna

© 2022 - 2025 — McMap. All rights reserved.