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?
TL;DR: skip to accepted answer below: https://stackoverflow.com/a/44804086/474034
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"
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!
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">
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.
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"-->
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.
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 eg 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!
Manually enabling it, worked for me in Intellij 2018.1.6 Ultimate Edition. Steps followed
Open the Project tool window (eg View | Tool Windows | Project).
Right-click the project or the module folder and select Add Framework Support.
Official reference : https://www.jetbrains.com/help/idea/thymeleaf.html#0c8052be
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
还有一种更有趣的情况,如果您不直接从控制器返回对象,Intellij 将无法识别该变量,但她仍然可以工作
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>
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.
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);
This feature is supported in the Ultimate edition only.
Click here for more details
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.