'Cannot connect Thymeleaf HTML webpage to my Spring Boot API/DB
I have a Spring Boot application for a school records management system. My API is working perfectly when using Insomnia but I cannot get my hTML webpage to interact with the API. Here are the relevant bits of my Staff entity/controller/repository/service. Any help appreciated!
Entity class:
@Entity
@Data
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Staff {
@Id
@SequenceGenerator(
name = "STAFF_SEQ",
sequenceName = "STAFF_SEQ",
allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "STAFF_SEQ"
)
private Long staffId;
private String firstName;
private String lastName;
private String staffEmail;
@ManyToOne(targetEntity = Department.class)
private Long departmentId;
private String address;
private String contactNumber;
private char gender;
}
...
}
Controller Class
@RestController
public class StaffController {
@Autowired
private StaffService staffService;
@RequestMapping(value = "/saveStaff")
public Staff saveStaff(Staff staff) {
return staffService.saveStaff(staff);
}
...
}
Repository Class
@Repository
public interface StaffRepository extends JpaRepository<Staff, Long> {
Staff findByFirstNameAndLastName(String firstName, String lastName);
}
Service Interface
public interface StaffService {
public Staff saveStaff(Staff staff);
...
}
ServiceImpl
@Service
public class StaffServiceImpl implements StaffService{
@Autowired
StaffRepository staffRepository;
@Override
public Staff saveStaff(Staff staff) {
return staffRepository.save(staff);
}
...
}
HTML file
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<h2>Add Staff</h2>
<form action = "#" method="post" th:action ="@{/saveStaff}" th:object = "${staff}">
<fieldset>
<legend>Staff</legend>
<label for="firstName">First name:</label><br>
<input type="text" th:field ="*{firstName}" class="form-control" id="firstName" name="firstName"><br><br>
<label for="lastName">Last name:</label><br>
<input type="text" th:field ="*{lastName}" class="form-control" id="lastName" name="lastname"><br><br>
<label for="staffEmail">Staff email:</label><br>
<input type="staffEmail" th:field ="*{staffEmail}" class="form-control" id="staffEmail" name="staffEmail"> <br><br>
<label for="address">Address</label><br>
<input type="text" th:field ="*{address}" class="form-control" id="address" name="address"><br><br>
<label for="contactNumber"> Contact number</label><br>
<input type="text" th:field ="*{contactNumber}" class="form-control" id="contactNumber" name="contactNumber"><br><br>
<label for="gender">Gender:</label>
<select th:field ="*{gender}" class="form-control" id="gender" name="gender">
<option value="f">F</option>
<option value="m">M</option>
</select><br><br>
<label for="departmentId"> Department Id</label><br>
<input type="number" th:field ="*{departmentId}" class="form-control" id="departmentId" name="departmentId"><br><br>
<input type="submit" value="Submit">
<input type="reset">
</fieldset>
</form>
</body>
</html>
Solution 1:[1]
Your controller class is a @RestController. From view page you need to call the rest controller by using XmlHttpRequest or we can say, Ajax request or fetch API. For your ease, you can try jQuery. If you really want to submit your form the Thymeleaf way, then your controller needs to be a MVC Controller. Long story short, you should replace the annotation @RestController with @Controller. Also remove the action attribute and keep only th:action.
Your Controller class
@Controller
@RequestMapping("/course")
public class CourseController {
@Autowired
CourseService courseService;
@GetMapping("/add")
public String get_saveCourseForm(Model model) {
Course course = new Course();
model.addAttribute("course", course);
return "saveCourse";
}
@PostMapping("/save")
public String post_saveCourseForm(@ModelAttribute("course") Course course, Model model) {
courseService.saveCourse(course);
var courses = courseService.fetchCourseList();
model.addAttribute("courses", courses);
return "displayCourses";
}
}
- Replaced
@RestControllerwith@Controllerannotation
- Add MVC methods and return view page names from the MVC methods. Also notice the request mappings. We will view the form by calling
/course/addand the form will be submitted to/course/save.
Your Form Page
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<h2>Add Course</h2>
<form method="post" th:action ="@{/course/save}" th:object = "${course}">
<fieldset>
<legend>Staff</legend>
<label for="courseName">Course name:</label><br>
<input type="text" th:field ="*{courseName}" class="form-control" id="courseName" name="courseName"><br><br>
<label for="courseCode">Course code:</label><br>
<input type="text" th:field ="*{courseCode}" class="form-control" id="courseCode" name="courseCode"><br><br>
<label for="departmentId"> Department Id</label><br>
<input type="number" th:field ="*{departmentId}" class="form-control" id="departmentId" name="departmentId"><br><br>
<input type="submit" value="Submit">
<input type="reset">
</fieldset>
</form>
</body>
</html>
Check the form action.
The page will look like below.
When the form will be submitted, it will return the result page. the HTML code is as follows.
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Display Courses</title>
</head>
<body>
<table>
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th>Course Code</th>
</tr>
<tr th:each="course : ${courses}">
<td><span th:text="${course.courseId}"></span></td>
<td><span th:text="${course.courseName}"></span></td>
<td><span th:text="${course.courseCode}"></span></td>
</tr>
</table>
</body>
</html>
The page will look as follows.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |





