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:
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!
Related
I am working with the Spring Framework, I have a model mapped to a controller with which I am trying to do some validations with the annotations offered by Spring, I use the BindingResult hasErrors() interface and also the #Validate annotation, however although I leave fields empty in my models (and specifies the #NotEmpty annotation) I can't get the hasErrors to change its state, it stays false. Am I forgetting something?
#Entity
#Table(name = "Clientes")
public class Cliente {
#Id
#Column(name= "ID_cliente")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idCliente;
#Column(name= "Productos_cliente", nullable = true)
private String productosCliente;
#Column(name= "Primer_nombre")
#NotEmpty(message = "El nombre no puede estar vacio")
private String primerNombre;
#Column(name= "Segundo_nombre")
#NotEmpty
private String segundoNombre;
#Column(name= "Primer_apellido")
#NotEmpty
private String primerApellido;
#Column(name= "Segundo_apellido")
#NotEmpty
private String segundoApellido;
#Column(name= "Ciudad_cliente")
private String ciudadCliente;
#Column(name= "Direccion_cliente")
private String direccionCliente;
#Column(name= "Correo_electronico")
#NotEmpty
private String email;
#Column(name= "Contraseña")
#NotEmpty
private String contraseña;
public Cliente(String productosCliente, String primerNombre, String segundoNombre, String primerApellido, String segundoApellido, String email, String contraseña ){
this.productosCliente = productosCliente;
this.primerNombre = primerNombre;
this.segundoNombre = segundoNombre;
this.primerApellido = primerApellido;
this.segundoApellido = segundoApellido;
this.email = email;
this.contraseña = contraseña;
}
/**
* #return Integer return the idCliente
*/
public Integer getIdCliente() {
return idCliente;
}
/**
* #param idCliente the idCliente to set
*/
public void setIdCliente(Integer idCliente) {
this.idCliente = idCliente;
}
/**
* #return String return the productosCliente
*/
public String getProductosCliente() {
return productosCliente;
}
/**
* #param productosCliente the productosCliente to set
*/
public void setProductosCliente(String productosCliente) {
this.productosCliente = productosCliente;
}
/**
* #return String return the primerNombre
*/
public String getPrimerNombre() {
return primerNombre;
}
/**
* #param primerNombre the primerNombre to set
*/
public void setPrimerNombre(String primerNombre) {
this.primerNombre = primerNombre;
}
/**
* #return String return the segundoNombre
*/
public String getSegundoNombre() {
return segundoNombre;
}
/**
* #param segundoNombre the segundoNombre to set
*/
public void setSegundoNombre(String segundoNombre) {
this.segundoNombre = segundoNombre;
}
/**
* #return String return the primerApellido
*/
public String getPrimerApellido() {
return primerApellido;
}
/**
* #param primerApellido the primerApellido to set
*/
public void setPrimerApellido(String primerApellido) {
this.primerApellido = primerApellido;
}
/**
* #return String return the segundoApellido
*/
public String getSegundoApellido() {
return segundoApellido;
}
/**
* #param segundoApellido the segundoApellido to set
*/
public void setSegundoApellido(String segundoApellido) {
this.segundoApellido = segundoApellido;
}
/**
* #return String return the ciudadCliente
*/
public String getCiudadCliente() {
return ciudadCliente;
}
/**
* #param ciudadCliente the ciudadCliente to set
*/
public void setCiudadCliente(String ciudadCliente) {
this.ciudadCliente = ciudadCliente;
}
/**
* #return String return the direccionCliente
*/
public String getDireccionCliente() {
return direccionCliente;
}
/**
* #param direccionCliente the direccionCliente to set
*/
public void setDireccionCliente(String direccionCliente) {
this.direccionCliente = direccionCliente;
}
/**
* #return String return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return String return the contraseña
*/
public String getContraseña() {
return contraseña;
}
/**
* #param contraseña the contraseña to set
*/
public void setContraseña(String contraseña) {
this.contraseña = contraseña;
}
}
Controller:
#Controller
#Validated
public class FormController {
#Autowired
ClienteServices service;
#GetMapping("/register")
public String formLoggin(Model model, Cliente cliente, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente", cliente);
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}
}
register.html:
<body>
<div style="display: flex; flex-direction: column; min-width: 500; min-height: 800; align-items: center; justify-content: center;">
<h3 th:text="${Title}"></h3>
<form th:action="#{/register}" th:object="${cliente}" method="post">
<div>
<label for="Primer nombre">Primer nombre</label>
<div>
<input id="username" name="username" type="text" th:field="*{primerNombre}">
<div th:if="${#fields.hasErrors('primerNombre')}" th:errors="*{primerNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Segundo nombre</label>
<div>
<input id="Secondname" name="Secondname" type="text" th:field="*{segundoNombre}">
<div th:if="${#fields.hasErrors('segundoNombre')}" th:errors="*{segundoNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Primer apellido</label>
<div>
<input id="Surname" name="Surname" type="text" th:field="*{primerApellido}">
</div>
</div>
<div>
<label for="Segundo apellido">Segundo apellido</label>
<div>
<input id="secondSurname" name="secondSurname" type="text" th:field="*{segundoApellido}">
</div>
</div>
<div>
<label for="Email">Correo electrónico</label>
<div>
<input id="Email" name="email" type="email" th:field="*{email}">
</div>
</div>
<div>
<label for="contraseña">Contraseña</label>
<div>
<input id="contraseña" name="password" type="password" th:field="*{contraseña}">
</div>
</div>
<div>
<label for="contraseña">Ciudad</label>
<div>
<input id="City" name="City" type="text" th:field="*{ciudadCliente}">
</div>
</div>
<div>
<label for="contraseña">Dirección</label>
<div>
<input id="Dir" name="Dir" type="text" th:field="*{direccionCliente}">
</div>
</div>
<div class="card-footer">
<button type="submit">Enviar</button>
</div>
</form>
</div>
Every thing seems to be fine. Try changing your controller this way . Create a new object when sending it to the form like below instead of sending it through parameter as it might not be able to bind object properly:
#GetMapping("/register")
public String formLoggin(Model model, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente",new cliente()); //change this line
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid #ModelAttribute("cliente") Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}
This is generally a result from only including the javax.validation API and not an implementation. You probably have something like the following in your depenendencies list.
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
This is only the API not an implementation. This is much like including the JPA jakarta.persistence-api and expect JPA to work (but you still need an implementation like Hibernate ORM). For the validation this is the same you need an implementation, mostly used is hibernate-validator. So you could add
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.5.Final</version>
</dependency>
NOTE: You have to use version 6.x as 7+ is for the new Jakarta Validation API which isn't supported yet (as of Spring Framework 6 / Spring Boot 3 it will).
However as you are already using Spring Boot I would strongly encourage you to use.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
This will include both the API and an implementation (the aformentioned hibernate-validator one). It will make sure you have a compatible version for this version of Spring / Spring Boot.
Instead of annotating with '#NotEmpty' you can follow this method:
#Column(name= "Correo_electronico", nullable = false)
private String email;
When you use this method either Jpa or Hibernate will throw an error if the value is empty.
Basically, Spring crashes with this error "value [null]; codes [NotNull.user.email,NotNull.email,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email]]; default message [must not be null], Field error in object 'user' on field 'firstName': rejected value [null]; codes" everytime I try to submit the completeProfile form. So, naturally, I looked at what data was saved after clicking submit on form. It turns out that the User object saved was having all the submitted property from the form as null. I checked inside the controller what was passed inside, all submitted properties from the form were null. Why does this happen?
User.java
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(min = 2, max = 80)
private String firstName;
#NotNull
#Size(min= 2, max = 80)
private String lastName;
#NotNull
#Email
private String email;
private Boolean enabled = false;
private String password = "";
private String role = "AUTHOR";
private String location = "";
private String topics = "";
private String job = "";
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getTopics() {
return topics;
}
public void setTopics(String topics) {
this.topics = topics;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
completeProfile.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>Complete your profile</p>
<form action="#" th:action="#{/completed-profile}" th:object="${user}" method="post">
<p>Email: <p th:text="${user.email}"></p>
<table>
<tr>
<td>Location:</td>
<td><input type="text" th:field="*{location}" /></td>
<td th:if="${#fields.hasErrors('location')}" th:errors="*{location}"></td>
</tr>
<tr>
<td>Job</td>
<td><input type="text" th:field="*{job}" /></td>
<td th:if="${#fields.hasErrors('job')}" th:errors="*{job}"></td>
</tr>
<tr>
<td>Topics of interest</td>
<td><input type="text" th:field="*{topics}" /></td>
<td th:if="${#fields.hasErrors('topics')}" th:errors="*{topics}"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" th:field="*{password}" /></td>
<td th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></td>
<td th:text="${password_error}"></td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
ProfileController.java
#Controller
public class ProfileController {
UserRepository userRepository;
public ProfileController(UserRepository userRepository) {
this.userRepository = userRepository;
}
#RequestMapping(value = {"/profile", "/profile.html"}, method = RequestMethod.GET)
public String profileForm(){
return "auth/profile";
}
#RequestMapping(value = "/complete-profile", method = RequestMethod.GET)
public String completeProfileForm(){
return "auth/completeProfile";
}
#RequestMapping(value = "/completed-profile", method = RequestMethod.POST)
public String submitProfileForm(#Valid User user, BindingResult bindingResult, Model model){
System.err.println(user.getEmail());
if (user.getPassword() == null || user.getPassword().equals("")){
// model.addAttribute("password_error", "password cannot be null");
model.addAttribute("user", user);
return "auth/completeProfile";
}
if(bindingResult.hasErrors()){
System.out.println(bindingResult.getAllErrors());
return "auth/completeProfile";
}
userRepository.save(user);
return "auth/login";
}
}
I would like to build a form to save an User. I have 2 tables, User and UserRole as described in Spring Security. To save an user I need to create a User Object that contains a field Set. I want to create a list of checkboxes and map them into an Set of UserRoles, but I don't know how to map them with checkboxes. I have the following classes:
#Controller
public class UserController {
#Autowired
IUserService userService;
/** Default GET form handler for users, in submission will call saveRegistration */
#RequestMapping(value="/createuser", method=RequestMethod.GET)
public String createUser(Model model) {
// User form will be bind to this User object
model.addAttribute("user", new User());
// Code about adding the user roles to JSP?
// Maybe something like this?:
// User u = new User ("useruser","123456",false);
// Set<UserRole> roles = new HashSet<UserRole>();
// roles.add(new UserRole(u,"ROLE_ADMIN"));
// roles.add(new UserRole(u,"ROLE_USER"));
// model.addAttribute("roles", roles);
return "createuser";
}
/** This method will be called on form submission, handling POST request,
* It also validates the user input */
#RequestMapping(value="/createuser", method=RequestMethod.POST)
public String doCreateUser(Model model, #Valid User user, BindingResult result) {
if(result.hasErrors()) {
return "createuser";
}
userService.createUser(user,user.getUserRole()) //createUser(User user, Set<UserRole> role)
return "success";
}
}
My JSP:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="resources/css/createuser.css" />
</head>
<body onload='document.createUserForm.username.focus();'>
<sf:form name="createUserForm" method="post"
action="${pageContext.request.contextPath}/createuser"
commandName="user">
<table class="formtable">
<tr>
<td class="label">Username:</td>
<td><sf:input class="control" path="username" name="username"
type="text" /><br />
<div class="error">
<sf:errors path="username"></sf:errors>
</div></td>
</tr>
<tr>
<td class="label">Role:</td>
<td>
<ul>
<sf:checkboxes element="li" path="userRole" items="${roles}"></sf:checkboxes>
</ul></td>
</tr>
<tr>
<td class="label">Password:</td>
<td><sf:input class="control" path="password" name="password"
type="password" />
<div class="error">
<sf:errors path="password"></sf:errors>
</div></td>
</tr>
<tr>
<td class="label">Confirm Password:</td>
<td><input class="control" name="confirmpass" type="password" />
<div class="error">
<sf:errors path="password"></sf:errors>
</div></td>
</tr>
<tr>
<td class="label"></td>
<td><input class="control" value="Create account" type="submit" /></td>
</tr>
</table>
</sf:form>
User Role:
public class UserRole {
private Integer userRoleId;
private User user;
private String role;
public UserRole () {
}
public UserRole(User user, String role) {
this.user = user;
this.role = role;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_role_id",
unique = true, nullable = false)
public Integer getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "username", nullable = false)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name = "role", nullable = false, length = 45)
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String toString () {
return role;
}
}
And User:
public class User {
#NotNull
#NotBlank(message="Username cannot be blank.")
#Size(min=4, max=15, message="Username must be between 4 and 15 characters long.")
#Pattern(regexp="^\\w{6,}$", message="Username can only consist of numbers, letters and the underscore character.")
private String username;
#NotBlank(message="Password cannot be blank.")
#Pattern(regexp="^\\S+$", message="Password cannot contain spaces.")
#Size(min=6, message="Username must be longer than 6 characters.")
private String password;
//private String confirmPassword;
private boolean enabled;
private Set<UserRole> userRole = new HashSet<UserRole>(0);
public User() {
}
public User(String username, String password, boolean enabled) {
this.username = username;
this.password = password;
this.enabled = enabled;
}
public User(String username, String password,
boolean enabled, Set<UserRole> userRole) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.userRole = userRole;
}
#Id
#Column(name = "username", unique = true, nullable = false, length = 45)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password", nullable = false, length = 60)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "enabled", nullable = false)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
public Set<UserRole> getUserRole() {
return userRole;
}
public void setUserRole(Set<UserRole> userRole) {
this.userRole = userRole;
}
/*public String getConfirmPassword() {
return confirmPassword;
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}*/
}
Thanks in advance.
Refert this post, and i dont see the itemlabel and itemid attribute, which maps to userrole object.
also refer post
Found solution using Properties Editor. Here and here
I am trying to post some variables to my controller which are then entered into a DB. But i keep getting an error stating that the request is syntactically incorrect.
Here is the form.
<form:form action="addLink" method="POST" commandName="link" >
<table id="productFinderTable">
<tbody align="left">
<tr align="left">
<td colspan="2">Gender:<input style="width: 798px;" type="number" name="gender" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Garment:<input style="width: 798px;" type="number" name="garment" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Product Class:<input style="width: 798px;" type="number" name="productclass" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Sport:<input style="width: 798px;" type="text" name="sport" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Link:<input style="width: 798px;" type="text" name="link" value="http://www.google.ie" /></td>
</tr>
<tr align="left">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</tbody>
</table>
</form:form>
The Entity Link
package com.wlgore.webapp.fab.pfsa.db;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "LINK")
public class Link implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column
private String hash;
#Column
#NotNull
private String link;
#Column
#NotNull
private Integer garment;
#Column
#NotNull
private Integer productclass;
#Column
#NotNull
private Integer gender;
#Column
private String sport;
/**
* #return the link
*/
public String getLink() {
return link;
}
/**
* #param link the link to set
*/
public void setLink(String link) {
this.link = link;
}
/**
* #return the garment
*/
public Integer getGarment() {
return garment;
}
/**
* #param garment the garment to set
*/
public void setGarment(Integer garment) {
this.garment = garment;
}
/**
* #return the productclass
*/
public Integer getProductclass() {
return productclass;
}
/**
* #param productclass the productclass to set
*/
public void setProductclass(Integer productclass) {
this.productclass = productclass;
}
/**
* #return the gender
*/
public Integer getGender() {
return gender;
}
/**
* #param gender the gender to set
*/
public void setGender(Integer gender) {
this.gender = gender;
}
/**
* #return the sport
*/
public String getSport() {
return sport;
}
/**
* #param sport the sport to set
*/
public void setSport(String sport) {
this.sport = sport;
}
/**
* #return the hash
*/
public String getHash() {
return hash;
}
/**
* #param hash the hash to set
*/
public void setHash(String hash) {
this.hash = hash;
}
}
Controller
#RequestMapping(value = "/addLink", method = RequestMethod.POST)
public #ResponseBody String addNewCommand(#ModelAttribute("link") Link link, BindingResult result)throws Exception{
/***
* Here we receive the relvant variables 1.Gender 2.Garment 3.Product
* Class 4.Sport 5.Link
* */
try {
if (result.hasErrors()) {
throw new Exception("Invalid post!");
} else {
String hash = HashFunction.gen(8);
Link linkExists = dao.getById(hash);
while (null != linkExists) {
hash = HashFunction.gen(8);
linkExists = dao.getById(hash);
}
System.out.println(hash);
link.setHash(hash);
dao.create(link);
return new ObjectMapper().writeValueAsString("Test Message");
}
} catch (Exception e) {
return new ObjectMapper().writeValueAsString(new ErrorJSON(e));
}
}
I don’t think #ModelAttribute is the correct annotation here. For BindingResult to work, you also need #Valid on the form bean.
Can anyone help us with this?
We're trying to make the register user feature in our JSF application. We want the user log in right after he registers. After the user hits the I'm a new client commandLink, we have this exception, and we don't know how to handle it:
com.sun.faces.mgbean.ManagedBeanPreProcessingException: Unexpected error processing managed bean registerBean
at com.sun.faces.mgbean.BeanManager.preProcessBean(BeanManager.java:394)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:260)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:99)
at com.sun.el.parser.AstValue.getValue(AstValue.java:158)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
at javax.faces.component.UIOutput.getValue(UIOutput.java:168)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:338)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.sun.faces.mgbean.ManagedBeanPreProcessingException: Unexpected error processing managed property loginBean
at com.sun.faces.mgbean.ManagedBeanBuilder.bake(ManagedBeanBuilder.java:117)
at com.sun.faces.mgbean.BeanManager.preProcessBean(BeanManager.java:349)
... 50 more
Caused by: java.lang.NullPointerException
at com.sun.faces.mgbean.ManagedBeanBuilder.bakeBeanProperty(ManagedBeanBuilder.java:350)
at com.sun.faces.mgbean.ManagedBeanBuilder.bake(ManagedBeanBuilder.java:107)
... 51 more
Here are the LoginBean and the RegisterBean:
#ManagedBean
#SessionScoped
public class LoginBean
{
private String username, password;
private User user;
private UserManager um = UserManager.getInstance();
/**
*
*/
public LoginBean()
{
super();
}
/**
* #return the username
*/
public String getUsername()
{
return username;
}
/**
* #return the password
*/
public String getPassword()
{
return password;
}
public void setUser(User user)
{
this.user = user;
username = user.getUsername();
password = user.getPassword();
}
/**
* #return the user
*/
public User getUser()
{
return user;
}
/**
* #param username
* the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
public String nextPage()
{
try
{
user = um.getUser(username, password);
}
catch (NoResultException e)
{
return "failure" + REDIRECT;
}
if (user instanceof Client)
return "home_client" + REDIRECT;
return "home_admin" + REDIRECT;
}
}
#ManagedBean
#RequestScoped
public class RegisterBean
{
private String username, password, repassword, firstname, lastname, email, address, city, county, postcode, country, phone;
#ManagedProperty(value = "#{loginBean}")
private LoginBean loginBean;
// private UserManager um = UserManager.getInstance();
public RegisterBean()
{
}
/**
* #return the username
*/
public String getUsername()
{
return username;
}
/**
* #return the password
*/
public String getPassword()
{
return password;
}
/**
* #return the repassword
*/
public String getRepassword()
{
return repassword;
}
/**
* #return the firstname
*/
public String getFirstname()
{
return firstname;
}
/**
* #return the lastname
*/
public String getLastname()
{
return lastname;
}
/**
* #return the email
*/
public String getEmail()
{
return email;
}
/**
* #return the address
*/
public String getAddress()
{
return address;
}
/**
* #return the city
*/
public String getCity()
{
return city;
}
/**
* #return the county
*/
public String getCounty()
{
return county;
}
/**
* #return the postcode
*/
public String getPostcode()
{
return postcode;
}
/**
* #return the country
*/
public String getCountry()
{
return country;
}
/**
* #return the phone
*/
public String getPhone()
{
return phone;
}
/**
* #return the user
*/
public LoginBean getLoginBean()
{
return loginBean;
}
/**
* #param username
* the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* #param repassword
* the repassword to set
*/
public void setRepassword(String repassword)
{
this.repassword = repassword;
}
/**
* #param firstname
* the firstname to set
*/
public void setFirstname(String firstname)
{
this.firstname = firstname;
}
/**
* #param lastname
* the lastname to set
*/
public void setLastname(String lastname)
{
this.lastname = lastname;
}
/**
* #param email
* the email to set
*/
public void setEmail(String email)
{
this.email = email;
}
/**
* #param address
* the address to set
*/
public void setAddress(String address)
{
this.address = address;
}
/**
* #param city
* the city to set
*/
public void setCity(String city)
{
this.city = city;
}
/**
* #param county
* the county to set
*/
public void setCounty(String county)
{
this.county = county;
}
/**
* #param postcode
* the postcode to set
*/
public void setPostcode(String postcode)
{
this.postcode = postcode;
}
/**
* #param country
* the country to set
*/
public void setCountry(String country)
{
this.country = country;
}
/**
* #param phone
* the phone to set
*/
public void setPhone(String phone)
{
this.phone = phone;
}
public String register()
{
this.loginBean.setUser(new Client(username, password, new ContactDetails(firstname, lastname, email, address, city, county, postcode, country, phone)));
return "home_client" + REDIRECT;
}
}
Here is the login form from login.xhtml:
<h:form>
Username: <h:inputText value="#{loginBean.username}" />
<br />
Password: <h:inputSecret value="#{loginBean.password}" />
<br />
<h:commandButton value="Login" action="#{loginBean.nextPage}" />
<h:commandLink value="I'm a new client" action="register"></h:commandLink>
</h:form>
And the register form from register.xhtml:
<h:form>
<h:outputText value="Inregistrare client nou"/>
<br/>
Username: <h:inputText value="#{registerBean.username}">
<f:validator validatorId="registerUsernameValidator"></f:validator>
</h:inputText>
<br/>
Parola: <h:inputSecret value="#{registerBean.password}"></h:inputSecret>
<br/>
Re-Parola: <h:inputSecret value="#{registerBean.repassword}"></h:inputSecret>
<br/>
<br/>
Prenume: <h:inputText value="#{registerBean.firstname}"></h:inputText>
<br/>
Nume: <h:inputText value="#{registerBean.lastname}"></h:inputText>
<br/>
E-mail: <h:inputText value="#{registerBean.email}"></h:inputText>
<br/>
Adresa: <h:inputText value="#{registerBean.address}"></h:inputText>
<br/>
Oras: <h:inputText value="#{registerBean.city}"></h:inputText>
<br/>
Judet: <h:inputText value="#{registerBean.county}"></h:inputText>
<br/>
Cod postal: <h:inputText value="#{registerBean.postcode}"></h:inputText>
<br/>
Tara: <h:inputText value="#{registerBean.country}"></h:inputText>
<br/>
Telefon: <h:inputText value="#{registerBean.phone}"></h:inputText>
<br/>
<br/>
<h:commandButton value="Inregistreaza-ma"
action="#{registerBean.register}"></h:commandButton>
Our custom RegisterUsernameValidator:
public class RegisterUsernameValidator implements Validator
{
UserManager um = UserManager.getInstance();
#Override
public void validate(FacesContext context, UIComponent arg1, Object value) throws ValidatorException
{
String username = (String) value;
if (!um.isUsernameAvailable(username))
{
FacesMessage facesMessage = new FacesMessage("Username indisponibil");
FacesContext.getCurrentInstance().addMessage("Username indisponibil", facesMessage);
}
}
}
And the validation part from faces-config.xml:
<validator>
<validator-id>registerUsernameValidator</validator-id>
<validator-class>validation.RegisterUsernameValidator</validator-class>
</validator>
com.sun.faces.mgbean.ManagedBeanPreProcessingException: Unexpected error processing managed bean registerBean
This means that processing the bean properties on RegisterBean directly after its construction has failed miserably due to a developer error (wrong configuration, inaccessible properties, invalid property type, etc). The root cause of the problem should be visible as root cause part in the stacktrace of the exception. Since you didn't share the entire stacktrace, it's hard to tell what exactly is failing.
Anyway, just read the stacktrace. The answer is in there.
Update: as per the full stacktrace:
Caused by: com.sun.faces.mgbean.ManagedBeanPreProcessingException: Unexpected error processing managed property loginBean
Caused by: java.lang.NullPointerException
The managed property for loginBean could not be set in registerBean. Verify if there is a setter in RegisterBean class and it has the right signature.
public void setLoginBean(LoginBean loginBean) {
this.loginBean = loginBean;
}
Unrelated to the concrete problem, this NullPointerException should really have been a PropertyNotWritableException. What JSF impl/version are you using?