Why is Thymeleaf failing to bind form inputs to object fields? - java

I am using Thymeleaf to create a registration form with Spring Boot (following this tutorial from Baeldung). The form is submitting, but it's not binding the inputs to the relevant object fields. This is my object:
#PasswordMatches
public class UserDto {
#NotNull
#NotEmpty
private String username;
#NotNull
#NotEmpty
#Email
private String email;
#NotNull
#NotEmpty
#Password
private String password;
#NotNull
#NotEmpty
#Password
private String confirmPassword;
#AssertTrue
private boolean agreementAccepted;
private boolean thirteen;
public String getUsername() {
return username;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public String getConfirmPassword() {
return confirmPassword;
}
public boolean isAgreementAccepted() {
return agreementAccepted;
}
public boolean isThirteen() {
return thirteen;
}
}
And this is the Thymeleaf template I am using:
<form class="form-signin" method="post" th:object="${user}"
th:action="#{''}">
<input type="hidden" th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
<h2 class="form-signin-heading">Create New Account</h2>
<p>
<label for="email" class="sr-only"></label> <input type="email"
id="email" name="email" class="form-control" placeholder="Email"
required="" autofocus="" th:field="*{email}">
</p>
<p>
<label for="username" class="sr-only"></label> <input type="text"
id="username" name="username" class="form-control"
placeholder="Username" required="" autofocus=""
th:field="*{username}">
</p>
<p>
<label for="password" class="sr-only"></label> <input type="password"
id="password" name="password" class="form-control"
placeholder="Password" required="" th:field="*{password}">
</p>
<p>
<label for="confirmPassword" class="sr-only"></label> <input
type="password" id="confirmPassword" name="confirmPassword"
class="form-control" placeholder="Confirm Password" required=""
th:field="*{confirmPassword}">
</p>
<p class="form-control">
<input required="" type="checkbox" id="accepted-agreement"
name="terms" placeholder="I agree to the terms of service"
th:field="*{agreementAccepted}" class="pointer"> <label
for="accepted-agreement" class="pointer">I agree to the terms
of service</label>
</p>
<p class="form-control">
<input type="checkbox" id="is-thirteen" name="terms"
placeholder="I am 13 years or older" th:field="*{thirteen}"
class="pointer"> <label data-toggle="tooltip"
data-placement="bottom"
title="You must be at least 13 years old to access this site's social media features."
class="pointer" for="is-thirteen">I am 13 years or older</label> <a
id="thirteen-info" class="info" href="#" data-toggle="tooltip"
data-bs-toggle="tooltip" data-bs-placement="bottom"
title="You must be at least 13 years old to access this site's social media features (<a target='_blank' href='../terms#coppa'>Learn More</a>).">?</a>
</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign
Up</button>
</form>
I double checked that the form is submitting the correct data using Chrome Dev Tools:
But the object fields are still not binding properly (screenshot from my debugger):
Why is this not working?

You need to have setters on UserDto for the binding to work.

Related

Calling a POST method from a pop up

I have one controller called IndexController. It has a #GetMapping and #PostMapping methods. When the user types in the URL to go to /index, it loads a list of books. On that index page, there's a 'Add a new book' button that triggers a modal pop up. When the user enters in information in the form and clicks the 'Add' button, it should call the #PostMapping method. It's not calling the method. The model for the form is the IndexBook.
IndexController class:
#Controller
public class IndexController {
#GetMapping("/index")
public String formGet(Model model) {
BookService bookService = new BookService();
ArrayList<ReviewedBook> reviewedBooks = bookService.getRecordedBooks(1);
model.addAttribute("indexbook", new IndexBook());
model.addAttribute("books", reviewedBooks);
return "index";
}
#PostMapping("/index")
public String formPost(#ModelAttribute IndexBook ib, Model model) {
System.out.println("Post for index called.");
BookService bookService = new BookService();
return "index";
}
}
IndexBook:
public class IndexBook {
private int userId;
private String title;
private String author;
private String isbn;
private String genre;
private String dateRead;
private int rating;
public void setUserId(int userId) {
this.userId = userId;
}
public int getUserId() {
return userId;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAuthor() {
return author;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getIsbn() {
return isbn;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getGenre() {
return genre;
}
public void setDateRead(String dateRead) {
this.dateRead = dateRead;
}
public String getDateRead() {
return dateRead;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getRating() {
return rating;
}
}
index.html (scroll down a bit to the comment 'Modal content')
<!DOCTYPE html>
<html lang="en">
<head>
<title>Book Note Book</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="css/index_styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index">Book Note Book</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>Books</li>
<li>Badges</li>
<li>Wishlist</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Profile</li>
<li><span class="glyphicon glyphicon-off"></span> Logout</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<h2>Books</h2>
<p>This is all the books you've read</p>
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>ISBN</th>
<th>Date read</th>
<th>Rating</th>
</tr>
</thead>
<tbody>
<tr th:if="${books.empty}">
<td colspan="2"> No Books Available </td>
</tr>
<tr th:each="book : ${books}">
<td><p th:text="${book.title}"/></td></td>
<td><p th:text="${book.author}"/></td>
<td><p th:text="${book.genre}"/></td>
<td><p th:text="${book.isbn}"/></td>
<td><p th:text="${book.dateRead}"/></td>
<td><p th:text="${book.rating}"/></td>
</tr>
</tbody>
</table>
</div>
<div class="container">
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#addNewBook">Add new book</button>
<div class="modal fade" id="addNewBook" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Add a new book</h4>
</div>
<div class="modal-body">
**<form action="#" class="form-horizontal" th:action="#{/index}" th:object="${indexbook}" method="post">
<input type="hidden" th:field="*{userId}" />
<div class="form-group">
<label class="control-label col-sm-2" for="title">Title</label>
<div class="col-sm-10">
<input type="text" th:field="*{title}" class="form-control" id="title" placeholder="Enter title" name="title">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="author">Author</label>
<div class="col-sm-10">
<input type="text" th:field="*{author}" class="form-control" id="author" placeholder="Enter author" name="author">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="genre">Genre</label>
<div class="col-sm-10">
<input type="text" th:field="*{genre}" class="form-control" id="genre" placeholder="Enter genre" name="genre">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="isbn">ISBN</label>
<div class="col-sm-10">
<input type="text" th:field="*{isbn}" class="form-control" id="isbn" placeholder="Enter ISBN" name="isbn">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="dateRead">Date read</label>
<div class="col-sm-10">
<input type="text" th:field="*{dateRead}" class="form-control" id="dateRead" placeholder="Enter date read" name="Enter the date read">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="rating">Rating</label>
<div class="col-sm-10">
<input type="text" th:field="*{rating}" class="form-control" id="rating" placeholder="Enter rating" name="Enter the rating">
</div>
</div>
</form>**
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Add</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="footer navbar-fixed-bottom">
<footer class="container-fluid text-center">
<p>© 2018 Book Note Book</p>
</footer>
</div>
</body>
</html>
You need to change your button type, in order to submit your form.
<div class="modal-footer">
<button type="submit" class="btn btn-default" data-dismiss="modal">Add</button>
</div>
When you have a button element with type button, it is only clickable, but it won't submit a form, unless you specified an action in js.

Recover form in JAVA-Spring (with thymeleaf) from html page

I am new in development tool and i am trying to use spring with thymeleaf to create a form to register on a website. I am currently not able to recover information from the form to another page which only show the list of users.
I create a classic Spring boot security in Eclipse with model/service/dao/controller java files.
My Model java file --> Register.java
#Entity
public class Register {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String pseudo;
private String lastname;
private String firstname;
private String sex;
private String country;
private String phone;
private String spokenlanguages;
private String email;
private String password;
private String job;
private boolean premium;
public void updateRegister(String pseudo, String lastname, String firstname, String sex, String country, String phone,
String spokenlanguages, String email, String password, String job, boolean premium) {
this.pseudo = pseudo;
this.lastname = lastname;
this.firstname = firstname;
this.sex = sex;
this.country = country;
this.phone = phone;
this.spokenlanguages = spokenlanguages;
this.email = email;
this.password = password;
this.job = job;
this.premium = premium;
// with all the getters & setters
}
My Service java file --> RegisterService.java
public interface RegisterService {
public List<Register> list();
public Register getById(long id);
}
My Repository Java file --> RegisterRepository.java
#Repository
public interface RegisterRepository extends PagingAndSortingRepository<Register, Long> {}
My Controller Java file --> RegisterController.java
#Controller
public class RegisterController {
#Autowired
RegisterRepository registerRepository;
#RequestMapping(value="/register", method=RequestMethod.GET)
public String form (Model model) {
return "register/form";
}
#PostMapping("/register/add")
public String registerAdd(
#Valid Register register,
BindingResult result,
Model model) {
if (result.hasErrors()) {
return "redirect:/error";
}
else {
Register r = new Register();
r.updateRegister(register.getPseudo(),
register.getLastname(),
register.getFirstname(),
register.getSex(),
register.getCountry(),
register.getPhone(),
register.getSpokenlanguages(),
register.getEmail(),
register.getPassword(),
register.getJob(),
register.isPremium());
System.out.println(r);
registerRepository.save(r);
model.addAttribute("registerlist", registerRepository.findAll());
return "register/valid";
}
}
#RequestMapping(value="/register/valid", method=RequestMethod.GET)
public String list (Model model) {
return "redirect:/home";
}
}
My Form in HTML --> form.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org/">
<head>
<title>Formulaire d'inscription</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</head>
<body>
<h1 class="register">Formulaire d'inscription</h1>
<form action="#" method="post" th:object="${register}" th:action="#{/register/add}">
<div class="form-group">
<label for="pseudo">Pseudo</label> <input type="text"
class="form-control" id="pseudo" placeholder="Pseudo"
th:field="*{pseudo}" required="required">
</div>
<div class="form-group">
<label for="lastname">Nom</label> <input type="text"
class="form-control" id="lastname" placeholder="Nom"
th:field="*{lastname}" required="required">
</div>
<div class="form-group">
<label for="firstname">Prénom</label> <input type="text"
class="form-control" id="firstname" placeholder="Prenom"
th:field="*{firstname}" required="required">
</div>
<div class="form-group radio">
<label for="sex">Sexe</label><br />
<label for="male">Homme<input
type="radio" class="form-control" id="sex" value="male"
th:field="*{sex}" required="required">
</label> <label for="female">Femme<input type="radio"
class="form-control" th:field="*{sex}" id="sex" value="female">
</label> <label for="other">Autre<input type="radio"
class="form-control" th:field="*{sex}" id="sex" value="other"></label>
</div>
<div class="form-group">
<label for="country">Pays</label> <br /> <select th:field="*{country}" required="required">
<option value="France" selected="selected">France</option>
....other countries...
</select>
</div>
<div class="form-group">
<label for="phone">Téléphone</label> <label
class="optional">(Facultatif)</label> <input type="text"
class="form-control" id="phone" placeholder="Téléphone" th:field="*{phone}">
</div>
<div class="form-group">
<label for="spokenlanguages">Langues parlées</label> <input
type="text" class="form-control" id="spokenlanguages"
placeholder="Langues" th:field="*{spokenlanguages}" required="required">
</div>
<div class="form-group">
<label for="email">Adresse Email</label> <input type="email"
class="form-control" id="email" aria-describedby="emailHelp"
placeholder="Email" th:field="*{email}" required="required">
</div>
<div class="form-group">
<label for="emailconf">Confirmez votre adresse Email</label> <input
type="email" class="form-control" id="emailconf"
aria-describedby="emailHelp" placeholder="" required="required">
</div>
<div class="form-group">
<label for="password">Mot de passe</label> <input type="password"
class="form-control" id="password" placeholder=""
th:field="*{password}" required="required">
</div>
<div class="form-group">
<label for="passwordconf">Confirmez votre mot de passe</label> <input
type="password" class="form-control" id="passwordconf"
placeholder="" required="required">
</div>
<div class="form-group">
<label for="job">Travail</label> <br /> <select id="job"
th:field="*{job}" required="required">
<option value="alexandre">Alexandre</option>
<option value="filmlover">Cinéphile</option>
<option value="scenarist">Scénariste</option>
<option value="productor">Producteur</option>
<option value="other">Autres</option>
</select>
</div>
<div class="form-group radio">
<label for="premium">Premium</label><br />
<label for="yes">Oui<input
type="radio" class="form-control" id="premium"
value="yes" th:field="*{premium}" required="required">
</label>
<label for="no">Non<input type="radio" class="form-control"
th:field="*{premium}" id="premium" value="no">
</label>
</div>
<input type="submit" class="btn btn-primary" id="valider" name="valider" value="Valider" />
</form>
<a href="../home" > <input class="btn btn-primary" type="reset" value="Annuler" /></a>
</body>
</html>
and my second HTML --> valid.html where i want to see at first now that the register was successful...but I got in this page this message --> org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor and my trial sysout in the controller lead to an null values for everything except the id and the premium stuff (boolean)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org/">
<head>
<title>Formulaire d'inscription</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</head>
<body>
<h1 class="register">Confirmation de votre inscription</h1>
<!-- <h2 class ="register" th:text="${'Bienvenue ' + register.pseudo}"></h2> -->
<div class="container">
<div class="page-header" id="banner">
<div class="row">
<div class="col-lg-8 col-md-7 col-sm-6">
<h1>Utilisateurs</h1>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Id</th>
<th>Pseudo</th>
<th>Nom</th>
<th>Prénom</th>
<th>Sexe</th>
<th>Pays</th>
<th>Téléphone</th>
<th>Langues parlées</th>
<th>E-mail</th>
<th>Mot de passe</th>
<th>Travail</th>
<th>Premium</th>
</tr>
</thead>
<tbody>
<tr th:each="register : ${registerlist}">
<td th:text="${register.id}"></td>
<td th:text="${register.pseudo}"></td>
<td th:text="${register.lastname}"></td>
<td th:text="${register.firstname}"></td>
<td th:text="${register.sex}"></td>
<td th:text="${register.country}"></td>
<td th:text="${register.phone}"></td>
<td th:text="${register.spokenlanguages}"></td>
<td th:text="${register.email}"></td>
<td th:text="${register.password}"></td>
<td th:text="${register.job}"></td>
<td th:text="${register.premium}"></td>
<td th:text="${register.id}"></td>
</tr>
</tbody>
</table>
</div>
</div>
<a href="../home" > <input class="btn btn-primary" type="reset" value="Retour" /></a>
</body>
</html>
Thanks in advance for the help.
Feel free to ask me more in order to a better unterstanding...
Try to add #ModelAttribute("register") in your registerAdd method, so it should look like
#RequestMapping(value="/register/add", method=RequestMethod.POST)
public String registerAdd(#ModelAttribute("register") #Valid Register register, BindingResult result, Model model)
Let me know if it was the problem.
Edit1
Add this line to your GET mapping
model.addAttribute("register", new Register());
So it should look like:
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String form(Model model) {
model.addAttribute("register", new Register());
return "register/form";
}
Hope it solves the problem :)

How to get data using an input form through a rest call?

I want to get the name and email address from a user through following form
<!-- Contatct Us-->
<section>
<div class="grey-bg">
<div class="container p-y-40">
<h1>Contact Us</h1>
<div class="row">
<div class="col-md-6">
<div class="form-horizontal contact-us" th:action="#{/contact-us}">
<div class="form-group">
<label for="FirstName" class="col-sm-3 control-label mandatory">Name</label>
<div class="col-sm-9">
<input type="text" class="form-control" th:value="${name}" placeholder=""/>
<input name="name" type="text" th:value="${name}" placeholder=""/>
<span th:text = "${name}"/>
</div>
</div>
<!-- -->
<div class="form-group">
<label for="Email" class="col-sm-3 control-label mandatory">Email</label>
<div class="col-sm-9">
<input type="email" class="form-control" th:value="${email}" placeholder=""/>
<input type="email" name="email" class="form-control" th:value="${email}" placeholder=""/>
</div>
</div>
<!-- -->
<div class="form-group">
<label for="Telephone" class="col-sm-3 control-label">Telephone</label>
<div class="col-sm-9">
<input type="text" class="form-control" th:value="${telephone}" placeholder=""/>
</div>
</div>
<!-- -->
<div class="form-group">
<label for="Message" class="col-sm-3 control-label ">Message</label>
<div class="col-sm-9">
<textarea class="form-control" rows="4" th:value="${message}"> </textarea>
</div>
</div>
<!-- -->
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3 col-md-offset-3">
<input type="button" value="Send" class="btn btn-primary btn-flat w-min-120"
data-toggle="modal" data-target="#myModal" />
</div>
</div>
<!-- -->
</div>
</div>
<div class="col-md-6">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d63371.792586563766!2d79.85603378454613!3d6.922006503004973!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x5f6f0f981a359f05!2sDialog+Axiata+PLC!5e0!3m2!1sen!2slk!4v1503969814382" width="100%" height="350" frameborder="0" style="border:0" allowfullscreen="true"></iframe>
</div>
</div>
</div>
</div>
</section>
I have used html and thymeleaf here. This is my controller. In the controller I want to pass parameters to the sendUserRegisterEmail method which I was taken from the user.
#Autowired
private EmailService emailService;
#ResponseBody
#RequestMapping(value = "/contact-us", method = RequestMethod.POST)
public String showContactForm(#RequestParam("name") String contactName, #RequestParam("email") String contactEmail) {
emailService.sendUserRegisterEmail(contactName, contactEmail);
return "index";
}
I wrote a DTO class as well.
public class ContactUsDto {
private String name;
private String email;
private String telephone;
private String message;
public ContactUsDto(String name, String email, String telephone, String message) {
this.name = name;
this.email = email;
this.telephone = telephone;
this.message = message;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Currently I get no errors. But the email is not receiving. I have no any issues with the method which I used to send the email. Because I have used it in another instances. The only issue is passing form data to it. Please help me to resolve this
#RequestParam is used to pass the request parameters e.g.
http://example.com/path?name=myName&email=myEmail
Whereas #RequestBody is used to get the request's body, which in most cases for REST is a json (application/json) body. So your method will be
#ResponseBody
#RequestMapping(value = "/contact-us", method = RequestMethod.POST)
public String showContactForm(#RequestBody ContactUsDto contactUsDto ) {
emailService.sendUserRegisterEmail(contactUsDto.getContactName(), contactUsDto.getContactEmail());
return "index";
}
add to your input attibute name like this
<input type="email" name="email" class="form-control" th:value="${email}" placeholder=""/>
<input name="name" type="text" th:value="${name}" placeholder=""/>
and try again .

spring form validation BindingResult always returns false

i am using spring form validation to validate my form input fields..I am having problem with BindingResult where result.hasErrors() is always returning false even though my input fields are null/empty..i managed all the imports and everything is looking fine to me.But as I said, my validation is not working and needs help with fixing this...
form:
<%#include file="././Header.jsp"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<script src="<c:url value="/js/smlibray/emailCommunicate.js"/>"></script>
<link href="<c:url value="/js/jquery-ui.css"/>" rel="stylesheet" />
<script src="<c:url value="/js/jquery-ui.js"/>"></script>
<input type="hidden" name="applicationUrl" id="applicationUrl"
value="${pageContext.request.contextPath}">
<div class="container sec-container middle-sec">
<div class="form-fields row">
<div class="col-md-12 col-sm-12 col-xs-12">
<form:form class="form-horizontal policy-form" id="emailCommu-form" method="POST" action="sendEmailMessage" commandName="emailForm">
<div class="form-group">
<h1 class="email-header">SiteMidner Email Notification</h1>
<c:choose>
<c:when test="${not empty sMsg}">
<div class="email-Commu-SMsg">* ${sMsg}</div>
</c:when>
<c:otherwise>
<c:if test="${not empty eMsg}">
<div class="email-Commu-EMsg">* ${eMsg}</div>
</c:if>
</c:otherwise>
</c:choose>
<div class="form-emailCommu">
<label for="emailSub-txtArea" class="email-ContentHead">Enter
the Subject Line for the Email : </label>
<div class="email-sm-textDiv">
<form:textarea path="emailSubject" name="emailSubject" id="emailSubTxtArea"
placeholder="Email Subject"/>
</div>
<span><form:errors path="emailSubject" cssClass="error" /></span>
</div>
<div class="form-emailCommu">
<label for="emailBod-txtArea" class="email-ContentHead">Enter
the Message Body for the Email : </label>
<div class="email-sm-textDiv">
<form:textarea path="emailMsg" name="emailMsg" id="emailBodyTxtArea"
placeholder="Email Body"/>
</div>
<span><form:errors path="emailMsg" cssClass="error" /></span>
</div>
<div class="email-sendButton">
<input type="submit" class="styled-button" value="Send Email"></input>
</div>
</div>
</form:form>
</div>
<!--form-fields close -->
</div>
</div>
controller code:
#RequestMapping(value="/sendEmailMessage",method=RequestMethod.POST)
public ModelAndView sendEmailCommunication(#Valid #ModelAttribute("emailForm") EmailReqInfo emailInfo,BindingResult result,HttpServletRequest request){
ModelAndView view = null;
StringBuffer sMsg = new StringBuffer();
StringBuffer eMsg = new StringBuffer();
boolean isAdmin = false;
try{
String loggedInUser = request.getHeader("sm_user").trim();
isAdmin = getUserAdminRights(request);
if(result.hasErrors()){
view = new ModelAndView("EmailCommunication");
view.addObject("isAdmin", isAdmin);
return view;
}
else{
String emailSubject = emailInfo.getEmailSubject();
String emailMsg = emailInfo.getEmailMsg().replace("\n", "<br />\n");
boolean status = emailService.sendEmailCommuncation(emailSubject,emailMsg);
if(status){
sMsg.append(" Sending SiteMinder Notification Email was Success.");
}
else{
eMsg.append(" Oops! Something went wrong while sending Email Notification. Pls check logs");
}
}
}
catch(Exception ex){
ex.printStackTrace();
eMsg.append("Oops! Something went wrong while sending Email Notification. Pls check logs");
}
view = new ModelAndView("EmailCommunication");
view.addObject("emailForm", new EmailReqInfo());
view.addObject("isAdmin", isAdmin);
view.addObject("sMsg", sMsg.toString());
view.addObject("eMsg", eMsg.toString());
return view;
}
email Model:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class EmailReqInfo
{
#NotNull #NotEmpty
#Size(min=1)
private String emailSubject;
#NotNull #NotEmpty
private String emailMsg;
public String getEmailSubject() {
return emailSubject;
}
public void setEmailSubject(String emailSubject) {
this.emailSubject = emailSubject;
}
public String getEmailMsg() {
return emailMsg;
}
public void setEmailMsg(String emailMsg) {
this.emailMsg = emailMsg;
}
}
i have the necessary annotation in my spring-mvc.xml
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
help needed in fixing the validation..thanks
#NotNull: Checks whether the value is not null, disregarding the content.
#NotEmpty: Checks whether the value is not null nor empty. If it has just empty spaces, it will allow it as not empty.
#NotBlank: Checks whether the value is not null nor empty, trimming the value first. It means that, it won’t allow just empty spaces
So, if you want to validate that a field is not null but also that it doesn’t has just empty spaces, but text, you should use #NotBlank.
This example is working, try to do the same:
Entity:
#Entity
#Table(name="EMPLOYEE")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Size(min=3, max=50)
#Column(name = "NAME", nullable = false)
private String name;
#NotNull
#DateTimeFormat(pattern="dd/MM/yyyy")
#Column(name = "JOINING_DATE", nullable = false)
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate joiningDate;
#NotNull
#Digits(integer=8, fraction=2)
#Column(name = "SALARY", nullable = false)
private BigDecimal salary;
#NotEmpty
#Column(name = "SSN", unique=true, nullable = false)
private String ssn;
//getter & setter
}
Controller:
#RequestMapping(value = { "/new" }, method = RequestMethod.POST)
public String saveEmployee(#Valid Employee employee, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
service.saveEmployee(employee);
model.addAttribute("success", "Employee " + employee.getName() + " registered successfully");
return "success";
}
registation.jsp
<h2>Registration Form</h2>
<form:form method="POST" modelAttribute="employee">
<form:input type="hidden" path="id" id="id"/>
<table>
<tr>
<td><label for="name">Name: </label> </td>
<td><form:input path="name" id="name"/></td>
<td><form:errors path="name" cssClass="error"/></td>
</tr>
<tr>
<td><label for="joiningDate">Joining Date: </label> </td>
<td><form:input path="joiningDate" id="joiningDate"/></td>
<td><form:errors path="joiningDate" cssClass="error"/></td>
</tr>
<tr>
<td><label for="salary">Salary: </label> </td>
<td><form:input path="salary" id="salary"/></td>
<td><form:errors path="salary" cssClass="error"/></td>
</tr>
<tr>
<td><label for="ssn">SSN: </label> </td>
<td><form:input path="ssn" id="ssn"/></td>
<td><form:errors path="ssn" cssClass="error"/></td>
</tr>
<tr>
<td colspan="3">
<c:choose>
<c:when test="${edit}">
<input type="submit" value="Update"/>
</c:when>
<c:otherwise>
<input type="submit" value="Register"/>
</c:otherwise>
</c:choose>
</td>
</tr>
</table>
</form:form>
I see problem with Hibernate Validators. #NotEmpty is anyway on top of #NotNull.
Try removing #NotEmpty validation constraints from your form and execute once again.

Sending array of entities as parameters in Struts2

For example I need to save several employees from form:
<h4>Employee 1</h4>
<div>
<input type="text" name="names">
<input type="text" name="ages">
<input type="text" name="salaries">
</div>
<h4>Employee 2</h4>
<div>
<input type="text" name="names">
<input type="text" name="ages">
<input type="text" name="salaries">
</div>
<h4>Employee 3</h4>
<div>
<input type="text" name="names">
<input type="text" name="ages">
<input type="text" name="salaries">
</div>
for that I do this:
public EmployeeAction extends ActionSupport {
private String[] employeesNames;
private Integer[] employeesAges;
private Integer[] employeesSalaries;
// Setters and getters
public String save() {
Employee[] employees = new Employee[size];
// Creating employee objects with names, ages and salaries
// and then save
saveBatch(employees);
return SUCCESS;
}
}
Is there a way when I can save data from form without processing of arrays,
but merely to save array of employees?
For instance:
<h4>Employee 1</h4>
<div>
<input type="text" name="employees.name">
<input type="text" name="employees.age">
<input type="text" name="employees.salary">
</div>
<h4>Employee 2</h4>
<div>
<input type="text" name="employees.name">
<input type="text" name="employees.age">
<input type="text" name="employees.salary">
</div>
<h4>Employee 3</h4>
<div>
<input type="text" name="employees.name">
<input type="text" name="employees.age">
<input type="text" name="employees.salary">
</div>
and action class:
public EmployeeAction extends ActionSupport {
private Employee[] employees;
// Setters and getters
public String save() {
saveBatch(employees);
return SUCCESS;
}
}

Categories