javaspringintellij-ideathymeleaf

Spring boot + thymeleaf in IntelliJ: cannot resolve vars


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?


Solution

  • Prerequisites

    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"-->