Issue
I was writing a Spring Boot application, and whenever the client requested to get "registration.html" template, the server should return it
I first put the GetMapping in my RegistrationController, and it worked, that is, when I access localhost:8080/registration, it does return me that page
@Controller
@RequestMapping("/registration")
public class UserRegistrationController {
private UserService userService;
public UserRegistrationController(UserService userService) {
super();
this.userService = userService;
}
@ModelAttribute("user")
public UserRegistrationDto userRegistrationDto() {
return new UserRegistrationDto();
}
@GetMapping
public String registration() {
return "registration";
}
@PostMapping
public String registerUserAccount(@ModelAttribute("user") UserRegistrationDto registrationDto) {
userService.save(registrationDto);
return "redirect:/registration?success";
}
}
Then I decided to create a template controller, and put all GetMapping for templates there. But then when I try to access localhost:8080/registration again, it gives me an error (type=Internal Server Error, status=500)
@Controller
@RequestMapping
public class TemplateController {
@GetMapping("/")
public String home() {
return "index";
}
@GetMapping("/registration")
public String registration() {
return "registration";
}
}
So my question is, does it matter where I put the GetMapping? Or is there are some configurations I needed to fix, so the app knows where to find the GetMapping? But the thing is, the home() method in this TemplateController does return me /index successfully, so I thought it's not to do with this class
The summary of the log file is:
org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor
I think this line below might be the issue
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
My registration.html is as below, however the "user" object is only used for the POST request, not GET request for returning the page
<html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form th:action="@{/registration}" method="post" th:object="${user}">
<div class="form-group">
<label class="control-label" for="name"> Name </label>
<input id="name" class="form-control" type="text" th:field="*{name}"
required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="email"> Email </label>
<input id="email" class="form-control" type="text" th:field="*{email}" required
autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="password"> Password </label>
<input id="password" class="form-control" type="password"
th:field="*{password}" required autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Register</button>
<span>Already registered? <a href="/" th:href="@{/login}">Login
here</a></span>
</div>
</form>
</body>
Solution
Thank you @Ahmet for the solution. The registration method under TemplateController is working now, and registration.html template is being returned, after I add a Model into the method. The complete code is:
@Controller
@RequestMapping("/")
public class TemplateController {
...
@GetMapping("/registration")
public String registration(Model model) {
User user = new User();
model.addAttribute(user);
return "registration";
}
// below is the old version, which didn't work.
// @GetMapping("/registration")
// public String registration() {
// return "registration";
// }
...
}
And this method is only present in TemplateController class, not in UserRegistrationController class (if I put the method here, it has always been working, as described in the question)
Answered By - cliff_leaf
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)