How to get the value of the input username with thymeleaf? - spring

How can I get the value of the input username in a login form?
My login form is:
<form th:action="#{/login}" method="post">
<div class="form-group">
<input type="text" name="username" id="username"
class="form-control" th:placeholder="Email" autofocus required/>
</div>
<div class="form-group">
<input type="password" name="password" id="password"
class="form-control" th:placeholder="Password" required/>
</div>
<input type="submit" class="btn btn-lg btn-primary btn-block"
th:value="Login"/>
</form>
And my controller is :
#Controller
public class LoginController {
#GetMapping("/login")
public String login(#RequestParam(value = "error", required = false) String error, Model model,
Principal principal) {
if (principal != null) {
return "redirect:/ccursos";
}
if (error != null) {
model.addAttribute("msg",
"Error al iniciar sesión: Nombre de usuario o contraseña incorrecta, por favor vuelva
a intentarlo!");
}
return "login";
}
#GetMapping("/logout")
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login";
}
}
I was trying to use the #RequestParam to get the value of the variable, but it says the varibale Email doesn't exist. I'm knew to this so any help would be appreciated.
Here is what I'm trying to to:
#GetMapping("/login")
public String login(#RequestParam(value = "error", required = false) String error,#RequestParam("Email") String email,
Model model, Principal principal) {
if (principal != null) {
return "redirect:/ppeliculas";
}
if (error != null) {
model.addAttribute("msg",
"Error al iniciar sesión: Nombre de usuario o contraseña incorrecta, por favor vuelva
a intentarlo!");
}
return "login";
}

You are trying to send form by POST method but your controller is defined only for #GetMapping. Change or add #PostMapping, then add #RequestBody Model model (if class Model describe your form) and all should works.
If you are starting with programing read something about HTTP: https://www.w3schools.com/tags/ref_httpmethods.asp and in this case about #RequestBody: https://www.baeldung.com/spring-request-response-body

Related

Error resolving template [create], template might not exist or might not be accessible by any of the configured Template Resolvers

I can't figure out why I keep getting this status = 500 template error.
''There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template [create], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [create], template might not exist or might not be accessible by any of the configured Template Resolvers''
I tried looking up resources and I coundn't resolve it.
This is what IntelliJ is saying:
This is my create.html template:
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head th:replace="fragments :: head"></head>
<head>
<link th:href="#{/css/meetups.css}" rel="stylesheet" />
</head>
<body class="create-meetup-body">
<header th:replace="fragments :: header"></header>
<div class="navbar">
<div class="container">
<nav>
<ul class="meetup-nav">
<li>All Meetups
Create a Meetup
Delete a Meetup</li>
</ul>
</nav>
</div>
</div>
<section class="create-meetup-section">
<form method="post">
<div class="form-group">
<div class="form-wrapper">
<label class="form-name">Meetup Name:
<input th:field="${meetup.meetupName}" class="form-control">
</label>
<p class="error" th:errors="${meetup.meetupName}"></p>
<label class="form-email">Contact Email:
<input th:field="${meetup.meetupContactEmail}" class="form-control">
</label>
<p class="error" th:errors="${meetup.meetupContactEmail}"></p>
<!--label class="form-date">Date:
<input type="date" class="form-control">
</label-->
<label class="form-date">Date (mm/dd/yyy):
<input th:field="${meetup.meetupDate}" class="form-control">
</label>
<p class="error" th:errors="${meetup.meetupDate}"></p>
<label class="form-description">Description:
<textarea th:field="${meetup.meetupDescription}" class="form-control"></textarea>
</label>
<p class="error" th:errors="${meetup.meetupDescription}"></p>
<label class="form-category" th:for="category">Category:</label>
<select id="meetupCategory" name="meetupCategory">
<option value="Nature Walk">Nature Walk</option>
<option value="Cycling">Cycling</option>
<option value="Family Activity">Family Activity</option>
<option value="Athletic">Athletic</option>
</select>
<label class="form-trail" th:for="trail">Trail:</label>
<select name="trailId">
<option th:each="trail : ${trails}"
th:text="${trail.name}"
th:value="${trail.id}"></option>
</select>
</div>
</div>
<input type="submit" value="Create Meetup">
</div>
</form>
</section>
</body>
</html>
I believe create.html it's in the correct directory:
This is my controller class:
#RequestMapping("meetups")
public class MeetupController {
#Autowired
private MeetupRepository meetupRepository;
#Autowired
private TrailRepository trailRepository;
#Autowired
private AuthenticationController authenticationController;
#GetMapping
public String displayMeetups(Model model, HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
User theUser = authenticationController.getUserFromSession(session);
model.addAttribute("theUser", theUser);
}
model.addAttribute("title", "Trail Meetups");
model.addAttribute("meetups", meetupRepository.findAll());
model.addAttribute("trails", trailRepository.findAll());
return "meetups/index";
}
#GetMapping("create")
public String displayCreateMeetupsForm(Model model) {
model.addAttribute("title", "Create A New Meetup");
model.addAttribute("trails", trailRepository.findAll());
model.addAttribute(new Meetup());
return "meetups/create";
}
#PostMapping("create")
public String processCreateMeetupsForm(#ModelAttribute #Valid Meetup newMeetup,
Errors errors, Model model, #RequestParam int trailId) {
if (errors.hasErrors()) {
model.addAttribute("title", "Create A New Meetup");
return "create";
}
Optional<Trail> trailObjs = trailRepository.findById(trailId);
if (trailObjs.isPresent()) {
Trail trail = trailObjs.get();
model.addAttribute("trail", trail);
model.addAttribute("trailId", trailId);
newMeetup.setTrail(trail);
meetupRepository.save(newMeetup);
model.addAttribute("meetups", meetupRepository.findAll());
return "meetups/index";
} else {
return "redirect:";
}
}
#GetMapping("delete")
public String displayDeleteMeetupsForm(Model model, HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
User theUser = authenticationController.getUserFromSession(session);
model.addAttribute("theUser", theUser);
}
model.addAttribute("title", "Delete A Meetup");
model.addAttribute("meetups", meetupRepository.findAll());
return "meetups/delete";
}
#PostMapping("delete")
public String processDeleteMeetupsForm(#RequestParam(required = false) int[] meetupIds, Model model, HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
User theUser = authenticationController.getUserFromSession(session);
model.addAttribute("theUser", theUser);
}
if (meetupIds != null) {
for (int id : meetupIds) {
meetupRepository.deleteById(id);
}
}
return "redirect:";
}
#GetMapping("details")
public String displayMeetupDetails(#RequestParam Integer meetupId, Model model, HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
User theUser = authenticationController.getUserFromSession(session);
model.addAttribute("theUser", theUser);
}
Optional<Meetup> result = meetupRepository.findById(meetupId);
if (result.isEmpty()) {
model.addAttribute("title", "Invalid: A meetup with ID " + meetupId + "does not seem to exist.");
} else {
Meetup meetup = result.get();
model.addAttribute("title", meetup.getMeetupName() + " Details");
model.addAttribute("meetups", meetup);
model.addAttribute("trails", trailRepository.findAll());
}
return "meetups/details";
}

Request method 'GET' not supported Spring Boot

I'm a beginer full stack developer. I need help.
I have the following code:
Controller:
#Controller
public class GreetingController {
#Autowired
private MessageRepos messageRepos;
#GetMapping("/")
public String greeting(Map<String, Object> model) {
return "greeting";
}
#GetMapping("/main")
public String main(Map<String, Object> model) {
Iterable<Message> messages = messageRepos.findAll();
model.put("messages", messages);
return "main";
}
#PostMapping("/main")
public String add(#RequestParam String text, #RequestParam String tag, Map<String, Object> model) {
Message message = new Message(text, tag);
messageRepos.save(message);
Iterable<Message> messages = messageRepos.findAll();
model.put("messages", messages);
return "main";
}
#PostMapping("filter")
public String filter(#RequestParam String filter, Map<String, Object> model) {
Iterable<Message> messages;
if (filter != null && !filter.isEmpty()) {
messages = messageRepos.findByTag(filter);
} else {
messages = messageRepos.findAll();
}
model.put("messages", messages);
return "main";
}
HTML:
</div>
<div>
<form method="post">
<input type="text" name="text" placeholder="Message" />
<input type="text" name="tag" placeholder="Tag">
<button type="submit">Add</button>
</form>
</div>
<div>
<form method="post" action="filter">
<input type="text" name="filter">
<button type="submit">Find</button>
</form>
</div>
When I click on the buttons add and find I get the problem.
Problem:
Request method 'GET' not supported.

form:errors are not displaying errors on JSP in Spring

I can not get the validation error messages to be showed in JSP page. The validation is working but messages are not getting displayed at all.
SystemValidator class :
#Override
public void validate(Object target, Errors errors) {
SystemUser systemUser = (SystemUser) target;
SystemUser user = systemUserRepository.findByUsername(systemUser.getUsername());
if (user != null && !(user.getId() == systemUser.getId()) || superUserName.equalsIgnoreCase(systemUser.getUsername())) {
errors.rejectValue("username", "Duplicate Username");
}
}
the view :
<form:form method="post" modelAttribute="user" action="addUser">
<div class="form-group">
<label for="username" class="col-form-label">User Name</label>
<form:input type="text" required="required" class="form-control" id="username" path="username"/>
<form:errors path = "username" cssClass = "error" />
</div>
<form:input type="hidden" id="id" name="id" path="id"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form:form>
the controller class :
#RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String saveUser(Model model, #Validated #ModelAttribute("user") SystemUser user, BindingResult result) {
logger.info("User save/update request received [{}]", user.toString());
if (result.hasErrors()) {
loadData(model);
model.addAttribute("user", user);
return "users";
}
systemUserService.saveSystemUser(user);
loadData(model);
return "users";
}
private void loadData(Model model) {
model.addAttribute("users", systemUserService.getAllUsers());
model.addAttribute("user", new SystemUser());
}
Use #Valid instead of #Validated like below.
#RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String saveUser(#Valid #ModelAttribute("user") SystemUser user, BindingResult result,Model model)
Don't do model.addAttribute("user", new SystemUser()); when validation error occurs.
Change to this:
if (result.hasErrors()) {
loadData(model, user);
return "users";
}
And:
private void loadData(Model model, User user) {
model.addAttribute("users", systemUserService.getAllUsers());
model.addAttribute("user", user);
}

spring-boot simple login failed

I'm a beginner in spring-Boot and i try to do a simple login using a thymeleaf form, it take the input name and password and compare it with the name and the paswword of a the user stored in database where its id is 1.
my controller is this:
#RequestMapping(value="/access", method=RequestMethod.POST)
public String access(#ModelAttribute("user") User user, ModelMap model)
{
Long id=(long) 1;
User u= userServiceImp.finduserById(id);
if(user.getName().equals(u.getName()) && user.getPassword().equals(u.getPassword()))
{
model.put("username", user.getName());
return "index";
}
else
{
model.put("message", "wrong username or password");
return "login";
}
}
and my html form is this:
<form th:action="#{/access}" th:object="${user}" method="POST">
<input type="text" th:field="*{name}" placeholder="Username" required="required" ></input>
<input type="password" th:field="*{password}" placeholder="Password" required="required" ></input>
<button type="submit" class="btn btn-primary btn-block btn-large">Let me in.</button>
<h1>${message}</h1>
</form>
but i alwayes get this error page
what could the problem be
the controller couldn't reconize the object th:object="${user}"
so i change this methode from this:
RequestMapping(value="/login", method = RequestMethod.GET)
public String showLoginPage(ModelMap model){
return "login";
}
to this:
RequestMapping(value="/login", method = RequestMethod.GET)
public String showLoginPage(ModelMap model){
User user = new User();
model.addAttribute("user", user);
return "login";}
now everything went right
Can you try this:
return "redirect:index";
or
return "redirect:/index";

Spring Boot multiple controllers with same mapping

My problem is very similar with this one: Spring MVC Multiple Controllers with same #RequestMapping
I'm building simple Human Resources web application with Spring Boot. I have a list of jobs and individual url for each job:
localhost:8080/jobs/1
This page contains job posting details and a form which unauthenticated users -applicants, in this case- can use to apply this job. Authenticated users -HR Manager-, can see only posting details, not the form. I have trouble with validating form inputs.
What I tried first:
#Controller
public class ApplicationController {
private final AppService appService;
#Autowired
public ApplicationController(AppService appService) {
this.appService = appService;
}
#RequestMapping(value = "/jobs/{id}", method = RequestMethod.POST)
public String handleApplyForm(#PathVariable Long id, #Valid #ModelAttribute("form") ApplyForm form, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "job_detail"; //HTML page which contains job details and the application form
}
appService.apply(form, id);
return "redirect:/jobs";
}
#RequestMapping(value = "/applications/{id}", method = RequestMethod.GET)
public ModelAndView getApplicationPage(#PathVariable Long id) {
if (null == appService.getAppById(id)) {
throw new NoSuchElementException(String.format("Application=%s not found", id));
} else {
return new ModelAndView("application_detail", "app", appService.getAppById(id));
}
}
}
As you guess this didn't work because I couldn't get the models. So I put handleApplyForm() to JobController and changed a little bit:
#Controller
public class JobController {
private final JobService jobService;
private final AppService appService;
#Autowired
public JobController(JobService jobService, AppService appService) {
this.jobService = jobService;
this.appService = appService;
}
#RequestMapping(value = "/jobs/{id}", method = RequestMethod.POST)
public ModelAndView handleApplyForm(#PathVariable Long id, #Valid #ModelAttribute("form") ApplyForm form, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return getJobPage(id);
}
appService.apply(form, id);
return new ModelAndView("redirect:/jobs");
}
#RequestMapping(value = "/jobs/{id}", method = RequestMethod.GET)
public ModelAndView getJobPage(#PathVariable Long id) {
Map<String, Object> model = new HashMap<String, Object>();
if (null == jobService.getJobById(id)) {
throw new NoSuchElementException(String.format("Job=%s not found", id));
} else {
model.put("job", jobService.getJobById(id));
model.put("form", new ApplyForm());
}
return new ModelAndView("job_detail", model);
}
}
With this way, validations works but I still can't get the same effect here as it refreshes the page so that all valid inputs disappear and error messages don't appear.
By the way, job_detail.html is like this:
<h1>Job Details</h1>
<p th:inline="text"><strong>Title:</strong> [[${job.title}]]</p>
<p th:inline="text"><strong>Description:</strong> [[${job.description}]]</p>
<p th:inline="text"><strong>Number of people to hire:</strong> [[${job.numPeopleToHire}]]</p>
<p th:inline="text"><strong>Last application date:</strong> [[${job.lastDate}]]</p>
<div sec:authorize="isAuthenticated()">
<form th:action="#{/jobs/} + ${job.id}" method="post">
<input type="submit" value="Delete this posting" name="delete" />
</form>
</div>
<div sec:authorize="isAnonymous()">
<h1>Application Form</h1>
<form action="#" th:action="#{/jobs/} + ${job.id}" method="post">
<div>
<label>First name</label>
<input type="text" name="firstName" th:value="${form.firstName}" />
<td th:if="${#fields.hasErrors('form.firstName')}" th:errors="${form.firstName}"></td>
</div>
<!-- and other input fields -->
<input type="submit" value="Submit" name="apply" /> <input type="reset" value="Reset" />
</form>
</div>
Check thymeleaf documentation here
Values for th:field attributes must be selection expressions (*{...}),
Also ApplyForm is exposed then you can catch it in the form.
Then your form should looks like this:
<form action="#" th:action="#{/jobs/} + ${job.id}" th:object="${applyForm}" method="post">
<div>
<label>First name</label>
<input type="text" name="firstName" th:value="*{firstName}" />
<td th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}"></td>
</div>
<!-- and other input fields -->
<input type="submit" value="Submit" name="apply" /> <input type="reset" value="Reset" />
</form>

Resources