I'm kind of stuck because according to the documentation this should work, but upon posting my form, all my model fields are null. If anyone could point out what I'm missing would be great.
Here's my model:
package hello.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class Post {
@Id
@NotNull
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotNull
private String email;
@NotNull
private String content;
public Post() { }
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Post{" +
"email='" + email + '\'' +
", content='" + content + '\'' +
'}';
}
}
my thymeleaf fragment with the form:
<div xmlns:th="http://www.thymeleaf.org" th:fragment="wysiwyg" class="panel-body">
<form class="form-horizontal" role="form" method="post" action="#" th:action="@{/post}" th:object="post">
<div class="form-group">
<label for="email">Email</label>
<input id="email" type="email" class="form-control" placeholder="Enter email..." th:field="*{email}"
required/>
<small id="emailHelp" class="form-text text-muted">Enter your email address just in case.</small>
</div>
<div class="form-group">
<label for="content">Post</label>
<textarea id="content" class="form-control" th:field="*{content}"></textarea>
<small id="bodyHelp" class="form-text text-muted">Type your post in here.</small>
</div>
<button id="btnPost" class="btn btn-primary" type="submit">Submit</button>
</form>
<script>
$(document).ready(function() {
$('#teszt2').summernote({
"height": 200
});
});
</script>
</div>
and the appropriate controller method:
@PostMapping("/post")
public String testPost(Post post, Model model) {
System.out.println(post);
return "index";
}
The expected behavior would be to have Post{email=$email, content=$content}, however the only thing I get is: Post{email=null, content=null} and I don't understand why. What am I doing wrong? What am I missing? All the online tutorials claim that this just works but it clearly doesn't work for me.
@Update:
A bit of update. So I can get it working, but only like this:
@GetMapping("/post")
public String openEditor(Model model) {
model.addAttribute("post", new Post());
model.addAttribute("content", "wysiwyg");
return "index";
}
So I create a new Empty post. In my fragment I change the form from th:object="post" to th:object="${post}". Then in my PostMapping:
@PostMapping("/post")
public String testPost(@ModelAttribute("post") Post post, Model model) {
System.out.println(post); // Works well
return "index";
}
Why doesn't it work if I don't use ModelAttribute and don't create an empty Post in the first place. I expected it to work... clearly I was wrong
In my opinion you should not tie your Entity object directly with submit form.
I suggest to follow a standard practice to create a PostRequest
class and use the fields you want to get from your form. Declare that in your @PostMapping
method signature as @RequestBody PostRequest postRequest
. Once you have the object in your controller method you can validate the input and create entity out of the object and then use it further for storing in your Database.
The practice is simple, do not mix your request/response objects with your database entity objects. That is risky too when you are storing any sensitive information in your database.
Not sure how this works with Thymeleaf templates, but there should be a way to follow this practice. Hope this helps.