I followed a tutorial to handle form submission in Spring. I wanted to populate my TaskEntity
bean with the form and have this bean's values available in my controller's taskSubmit
method. However, all of the properties of task
in this method are null when I fill out the form and hit submit. The relevant code is as follows:
TaskEntity.java
public class TaskEntity {
private String title;
private String description;
private Date dueDate;
private TaskPriority priority;
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return this.title;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return this.description;
}
public void setDueDate(Date dueDate)
{
this.dueDate = dueDate;
}
public Date getDueDate()
{
return this.dueDate;
}
public void setPriority(String priority)
{
this.priority = TaskPriority.valueOf(priority);
}
public TaskPriority getPriority()
{
return this.priority;
}
}
addTask.jsp
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>To Do List - Add Task</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/stylesheet.css">
</head>
<body>
<form action="tasks" th:action="@{/tasks}" th:object="${taskEntity}" method="post">
<p>Title: <input type="text" th:field="*{title}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p>Due Date: <input type="text" th:field="*{dueDate}" /></p>
<p>Priority: <input type="text" th:field="*{priority}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
TaskController.java
@Controller
public class TaskController {
private static final String TASKS = "/tasks";
private static final String ADD_TASK = "/addTask";
@Autowired
private TaskEntityDao taskEntityDao;
ObjectMapper mapper = new ObjectMapper();
@RequestMapping(value = TASKS, method = RequestMethod.GET)
public ModelAndView readTasks()
{
return new ModelAndView("tasks");
}
@RequestMapping(value = ADD_TASK, method = RequestMethod.GET)
public String addTask(Model model)
{
model.addAttribute("taskEntity", new TaskEntity());
return "addTask";
}
@RequestMapping(value = TASKS, method = RequestMethod.POST)
public void taskSubmit(@ModelAttribute TaskEntity task)
{
// Fields for 'task' are all null!
taskEntityDao.createTask(task);
readTasks();
}
}
I expected the TaskEntity
passed to the view with model.addAttribute("taskEntity", new TaskEntity());
was going to have the form values mapped to it's fields, but I must have missed something.
Update:
I am adding the view resolver code from my Spring config:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
With your edit you've confirmed that your view resolution is for JSPs.
You have a JSP page with <input>
elements that look like
<input type="text" th:field="*{description}" />
Presumably th:field
is a Thymeleaf element , but your page isn't processed by Thymeleaf, it's processed by the JSP Servlet. The JSP Servlet doesn't care about th:field
, it's not special to it in any way. It just copies it literally. Furthermore, your input
doesn't have a name
attribute. As such, when you submit the form
, your browser doesn't send a corresponding value. (Even if it did, it wouldn't have a name that Spring MVC recognizes and can bind to your model attribute.)
Set up your MVC configuration to properly render Thymeleaf views instead of JSP views.
Or if you really want to use JSPs, use the corresponding technologies: EL, JSTL, and Spring's tag library. There are tons of tutorials online, like this one .
You have a GET
/ POST
for the same URL, in this case represented by TASKS = "/tasks"
Thus according with the following:
@RequestMapping(value = TASKS, method = RequestMethod.GET)
public ModelAndView readTasks()
{
return new ModelAndView("tasks");
}
Where was created the TaskEntity
object?
You have model.addAttribute("taskEntity", new TaskEntity());
in the addTask
method, but works with other URL, in this case ADD_TASK = "/addTask"
.
You need understand that the web form is loaded according a model created through the GET
event and then when the submit event happens (web form was filled) the POST
event happens. In this scenario is normal that GET
/ POST
(handled by @RequestMapping
) share the 'same' URL.
Observation: Thymeleaf
does not work with a UrlBasedViewResolver
, it has its own ViewResolver
for Thymeleaf
, furthermore, Thymeleaf
works with a .html
file, not with .jsp
. Thus I am assuming the POST
event is not working how should be expected for the Model
.
Note : is a bad practice that a @Controller
has a direct dependency with a @Repository
, it should be for a @Service
.
According with:
@RequestMapping(value = TASKS, method = RequestMethod.POST)
public void taskSubmit(@ModelAttribute TaskEntity task)
{
// Fields for 'task' are all null!
taskEntityDao.createTask(task);
readTasks();
}
Fields for 'task' are all null!
, how you are confirming that? readTasks()
. Is not very common that a @RequestMapping
calls other @RequestMapping
.
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.