Issue
I'm very new to Thymeleaf and I'm trying to make a registration form but it keeps giving me error 500's when I try to add th: attributes to my form. I assume it has something to do with the form not seeing the UserModel but I can't be sure. I feel like I've tried everything so any help would be greatly appreciated!
Here's my registration form:
<!DOCTYPE html>
<html xmlns:th=”http://www.thymeleaf.org” xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="layouts/defaultTemplate">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Register - AZSnowSports</title>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="@{doRegister}" th:object="${userModel}" method="POST">
<table>
<tr>
<td>First Name:</td><td><input type="text" th:field="*{firstName}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}">First Name Error</h5></td>
</tr>
<tr>
<td>Last Name:</td><td><input type="text" th:field="*{lastName}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}">Last Name Error</h5></td>
</tr>
<tr>
<td>EMail:</td><td><input type="email" th:field="*{email}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">EMail Error</h5></td>
</tr>
<tr>
<td>Address:</td><td><input type="text" th:field="*{address}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('address')}" th:errors="*{address}">Address Error</h5></td>
</tr>
<tr>
<td>Phone Number:</td><td><input type="number" th:field="*{phoneNumber}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('phoneNumber')}" th:errors="*{phoneNumber}">Phone Number Error</h5></td>
</tr>
<tr>
<td>Username:</td><td><input type="text" th:field="*{username}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username Error</h5></td>
</tr>
<tr>
<td>Password:</td><td><input type="password" th:field="*{password}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</h5></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
Here's my controller:
package com.azsnowsports.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.azsnowsports.model.UserModel;
@Controller
@RequestMapping("/register")
public class RegisterController {
@GetMapping("/")
public String display(Model model)
{
// Display the login form view
model.addAttribute("title", "Register Form");
return "register";
}
@PostMapping("/doRegister")
public String doRegister(@Valid UserModel userModel, BindingResult bindingResult, Model model)
{
//Check for validation errors
if (bindingResult.hasErrors())
{
model.addAttribute("title", "Register Form");
return "register";
}
return "registerSuccess";
}
}
And here's my user model:
package com.azsnowsports.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class UserModel {
/**
* The user's first name
*/
@NotNull(message="FirstName is a required field.")
@Size(min = 1, max = 32, message="First Name must be between 1 and 32 characters.")
private String firstName;
/**
* The user's last name
*/
@NotNull(message="Last name is a required field.")
@Size(min = 1, max = 32, message="Last name must be between 1 and 32 characters.")
private String lastName;
/**
* The user's email
*/
@NotNull(message="EMail is a required field.")
private String email;
/**
* The user's address
*/
@NotNull(message="Address is a required field.")
private String address;
/**
* The user's phone number
*/
@NotNull(message="Phone Number is a required field.")
private int phoneNumber;
/**
* The user's username
*/
@NotNull(message="Username is a required field.")
@Size(min = 1, max = 32, message="Username must be between 1 and 32 characters.")
private String username;
/**
* The user's password
*/
@NotNull(message="Password is a required field.")
@Size(min = 1, max = 32, message="Password must be between 1 and 32 characters.")
private String password;
/**
* Constructor
*
* @param firstNameVal The first name of the user
* @param lastNameVal The last name of the user
* @param emailVal The email of the user
* @param addressVal The address of the user
* @param phoneNumber The phone number of the user
* @param usernameVal The username for the user
* @param passwordVal The password for the user
*/
public UserModel(String firstNameVal, String lastNameVal, String emailVal, String addressVal,
int phoneNumberVal, String usernameVal, String passwordVal)
{
this.firstName = firstNameVal;
this.lastName = lastNameVal;
this.email = emailVal;
this.address = addressVal;
this.phoneNumber = phoneNumberVal;
this.username = usernameVal;
this.password = passwordVal;
}
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* @return the email
*/
public String getEmail() {
return email;
}
/**
* @param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* @return the address
*/
public String getAddress() {
return address;
}
/**
* @param address the address to set
*/
public void setAddress(String address) {
this.address = address;
}
/**
* @return the phoneNumber
*/
public int getPhoneNumber() {
return phoneNumber;
}
/**
* @param phoneNumber the phoneNumber to set
*/
public void setPhoneNumber(int phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
Heres a screenshot of my file structure:
Solution
I added model.addAttribute("userModel", new UserModel());
into the root map of the model so it now looks like this:
@GetMapping("/")
public String display(Model model)
{
// Display the login form view
model.addAttribute("title", "Register Form");
model.addAttribute("userModel", new UserModel());
return "register";
}
This fixed it and it runs fine now!
Answered By - ThatGhostToast
Answer Checked By - David Marino (JavaFixing Volunteer)