I am unable to post my form to the post method of my controller - spring

I am trying to submit the form and send the data to the post method of my controller, but all i get is status 400 error I am not able to understand why this error is poping when i am able to submit for the post method for the different JSP pages.
Have I gone wrong somewhere, please help me I am not able to find my mistake
this is my controller
#RequestMapping(value = "personal" , method=RequestMethod.GET)
public String test(HttpServletRequest request, Model model, HttpServletResponse response, #ModelAttribute("personalDetails") PersonalDetails personalDetails) {
if(personalDetails==null){
personalDetails = new PersonalDetails();
}
Map referenceData = new HashMap();
Map<Long, String> salutation = new LinkedHashMap<Long, String>();
salutation.put(1L, "Mr");
salutation.put(2L, "Miss");
salutation.put(3L, "Mrs");
Map<Long,String> bloodGrp = new LinkedHashMap<Long, String>();
bloodGrp.put(1L, "A+");
bloodGrp.put(2L, "B+");
Map<Long, String> gender = new LinkedHashMap<Long, String>();
gender.put(1L, "MALE");
gender.put(2L, "Female");
Map<Long, String> marriageStatus = new LinkedHashMap<Long, String>();
marriageStatus.put(1L, "Single");
marriageStatus.put(2L, "divorsy");
log.info("Before setting model attributes");
model.addAttribute("salutationList", salutation);
model.addAttribute("bloodGrp", bloodGrp);
model.addAttribute("genderList", gender);
model.addAttribute("marriageStatus", marriageStatus);
model.addAttribute("persoanalDetails", personalDetails);
log.info("after setting model attributes");
return "personal";
}
#RequestMapping(value="personaldetails" , method=RequestMethod.POST)
public String personalDetails(#ModelAttribute("personalDetails") PersonalDetails personalDetails, HttpServletRequest request, HttpServletResponse response){
this.personalDetails = personalDetails;
return "success";
}
My jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Generic Tool For Employee</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<link rel="stylesheet" href="layout/css/bootstrap.min.css">
<link rel="stylesheet" href="layout/css/validator/screen.css">
<link rel="stylesheet"
href="layout/datepicker/css/bootstrap-datepicker3.min.css">
<link rel="stylesheet" href="layout/css/index.css">
<div class="container-fluid">
<h2>Personal Details</h2>
<form:form commandName="personalDetails" class="form-horizontal" id="personalDetailsForm" role="form"
method="POST" action="${pageContext.request.contextPath}/personaldetails">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Personal Information</h4>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-sm-2 control-label" for="salutation">Salutation</label>
<div class="col-sm-2">
<form:select path="salutation" id="salutation"
name="salutation" class="form-control">
<!-- <option value="Mr">Mr</option>
<option value="Miss">Miss</option>
<option value="Mrs">Mrs</option>
<option value="Mx">Mx</option> -->
<form:options items="${salutationList}" />
</form:select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">First Name</label>
<div class="col-sm-4">
<form:input path="firstName" id="firstName" type="text"
class="form-control charcterClss" name="firstName"
placeholder="FIRST NAME" maxlength="250" />
</div>
<label class="col-sm-2 control-label">Middle Name</label>
<div class="col-sm-4">
<form:input path="middleName" id="middleName" type="text"
class="form-control charcterClss" name="middleName"
placeholder="MIDDLE NAME" maxlength="250" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Last Name</label>
<div class="col-sm-4">
<form:input path="lastName" id="lastName" type="text"
class="form-control charcterClss" name="lastName"
placeholder="LAST NAME" maxlength="250" />
</div>
<label class="col-sm-2 control-label">Blood group</label>
<div class="col-sm-4">
<form:select path="bloodGrp" id="bloodGroup"
name="bloodGroup" class="form-control">
<!-- <option></option>
<option>O +ve</option>
<option>O -ve</option>
<option>B +ve</option>
<option>B -ve</option>
<option>A +ve</option>
<option>A -ve</option>
<option>AB +ve</option>
<option>AB -ve</option> -->
<form:options items="${bloodGrp}" />
</form:select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Gender</label>
<div class="col-sm-4">
<form:select path="gender" id="gender" name="gender"
class="form-control">
<!-- <option value="Male">Male</option>
<option value="FeMale">Fe-Male</option>
<option value="Neutral">Transgender</option> -->
<form:options items="${genderList}" />
</form:select>
</div>
<label class="col-sm-2 control-label">Email Id</label>
<div class="col-sm-4">
<form:input path="emailId" class="form-control" type="text"
name="personalEmail" id="personalEmail"
placeholder="Personal Email" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Contact Number</label>
<div class="col-sm-4">
<form:input path="contactNo" class="form-control" type="text"
id="personalPhoneNno" name="personalPhoneNno"
placeholder="Personal Contact" />
</div>
<label class="col-sm-2 control-label">Alternative Contact
Number</label>
<div class="col-sm-4">
<form:input path="alterContactNo" class="form-control" type="text"
id="alternativePhoneNo" name="alternativePhoneNo"
placeholder="Alternative Contact" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Date of Birth</label>
<div class="col-sm-4">
<form:input path="dob" type="text" class="form-control datepicker"
placeholder="DOB" id="dOb" name="dOb" />
</div>
<label class="col-sm-2 control-label">Birth Place</label>
<div class="col-sm-4">
<form:input path="birthPlace" type="text"
class="form-control charcterClss" placeholder="PLACE YOU BORN"
id="birthPlace" name="birthPlace" maxlength="250" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Nationality</label>
<div class="col-sm-4">
<form:input path="nationality" type="text"
class="form-control charcterClss" placeholder="NATIONALITY"
id="nationality" name="nationality" />
</div>
<label class="col-sm-2 control-label">Religion</label>
<div class="col-sm-4">
<form:input path="religion" type="text"
class="form-control charcterClss" placeholder="RELIGION"
id="religion" name="religion" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Marital Status</label>
<div class="col-sm-4">
<form:select path="marriageDetails" id="maritalStatus" name="maritalStatus"
class="form-control">
<!-- <option value="single">Single</option>
<option value="married">Married</option>
<option value="divorcee">Divorcee</option> -->
<form:options items="${marriageStatus}"/>
</form:select>
</div>
<label class="col-sm-2 control-label">Date of Wedding</label>
<div class="col-sm-4">
<form:input path="dow" type="text" class="form-control datepicker"
placeholder="WEDDING DATE" id="weedingDate" name="weedingDate"/>
</div>
</div>
</div>
<div class="panel-footer">
<input class="submit btn btn-default" type="submit" value="Submit">
</div>
</div>
</form:form>
</div>
<!-- SCRIPTS -->
<script src="js/vendors/jquery-1.9.1.min.js"></script>
<script src="js/vendors/jquery.validate.min.js"></script>
<script src="js/vendors/bootstrap-3.3.5.js"></script>
<script src="datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="js/index.js"></script>
<script src="js/personal.js"></script>
and this is my model
#Entity
#Table(name="TB_PERSONAL_DETAILS")
public class PersonalDetails implements Serializable {
#Id
#GeneratedValue
#Column(name="PERSON_ID")
private Long personId;
#ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.DETACH)
#JoinColumn(name="SALUTATION_ID")
private SalutationMaster salutation;
#Column(name="FIRST_NAME")
private String firstName;
#Column(name="MIDDLE_NAME")
private String middleName;
#Column(name="LAST_NAME")
private String lastName;
#OneToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name="BLOOD_GRP_ID")
private BloodGrpMaster bloodGrp;
#OneToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name="GENDER_ID")
private GenderMaster gender;
#Column(name="EMAIL_ID")
private String emailId;
#Column(name="CONTACT_NO")
private String contactNo;
#Column(name="ALTERNATE_CONTACT_NO")
private String alterContactNo;
#Column(name="DATE_OF_BIRTH")
private Date dob;
#Column(name="BIRTH_PLACE")
private String birthPlace;
#Column(name="RELIGION")
private String religion;
#Column(name="NATIONALITY")
private String nationality;
#ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name="MARRIAGE_DETAILS_ID")
private MarriageMaster marriageDetails;
#Column(name="DOW")
private Date dow;
#OneToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy="personalDetails")
private EmployeeDetails employeeDetails;
public PersonalDetails() {
// TODO Auto-generated constructor stub
}
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public BloodGrpMaster getBloodGrp() {
return bloodGrp;
}
public void setBloodGrp(BloodGrpMaster bloodGrp) {
this.bloodGrp = bloodGrp;
}
public GenderMaster getGender() {
return gender;
}
public void setGender(GenderMaster gender) {
this.gender = gender;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public String getBirthPlace() {
return birthPlace;
}
public void setBirthPlace(String birthPlace) {
this.birthPlace = birthPlace;
}
public String getReligion() {
return religion;
}
public void setReligion(String religion) {
this.religion = religion;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public SalutationMaster getSalutation() {
return salutation;
}
public void setSalutation(SalutationMaster salutation) {
this.salutation = salutation;
}
public EmployeeDetails getEmployeeDetails() {
return employeeDetails;
}
public void setEmployeeDetails(EmployeeDetails employeeDetails) {
this.employeeDetails = employeeDetails;
}
/**
* give the marital details of the employee
* #return
*/
public MarriageMaster getMarriageDetails() {
return marriageDetails;
}
/**
* set the marital details of the employee
* #param marriageDetails
*/
public void setMarriageDetails(MarriageMaster marriageDetails) {
this.marriageDetails = marriageDetails;
}
public Date getDow() {
return dow;
}
public void setDow(Date dow) {
this.dow = dow;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public String getAlterContactNo() {
return alterContactNo;
}
public void setAlterContactNo(String alterContactNo) {
this.alterContactNo = alterContactNo;
}
}
Thank you in advance for going through my issue and giving your best on that.

Related

Unable to bind thymeleaf template and spring boot correctly

I am working on registration in spring boot with spring security and thymeleaf but for some reason the userForm.getUsername() gives null value during POST (see code below)
Person.java
#Entity#Table(name = "person")
public class Person {
#Id#Column(name = "username")
private String username;
#Column(name = "mobile")
private String mobile;
#JsonIgnore#Column(name = "password")
private String password;
#Transient#JsonIgnore
private String passwordConfirm;
#ManyToMany(cascade = CascadeType.ALL)#JoinTable(name = "bookandperson", joinColumns = #JoinColumn(name = "username"), inverseJoinColumns = #JoinColumn(name = "bookName"))
private List < Book > listOfBooks = new ArrayList < Book > ();
}
PersonController.java
#Controller
public class PersonController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/registration", method = RequestMethod.GET)
public String registration(Model model, Principal user) {
if (user != null) {
return "redirect:/";
}
model.addAttribute("userForm", new Person());
return "registration";
}
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute Person userForm, BindingResult bindingResult, Model model) {
System.out.println(userForm.getUsername()); //This is giving null value
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
System.out.println("binding result has errors");
return "registration";
}
userService.save(userForm);
securityService.autologin(userForm.getUsername(), userForm.getPasswordConfirm());
return "redirect:/";
}
registration.html
<head>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
</head>
<body>
<nav th:replace="common/navbar :: common-navbar"/>
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-6 col-md-offset-6">
<form th:action="#{/registration}" method="post">
<div class="form-group row">
<label for="inputUsername" class="col-sm-2 col-form-label">Username</label>
<div class="col-md-6">
<input type="text" class="form-control" th:field="${userForm.username}" id="inputUsername" value="" placeholder="Username">
</div>
</div>
<div class="form-group row">
<label for="mobile" class="col-sm-2 col-form-label">Mobile</label>
<div class="col-md-6">
<input type="text" class="form-control" th:field="${userForm.mobile}" id="inputMobile" placeholder="Mobile">
</div>
</div>
<div class="form-group row">
<label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" th:field="${userForm.password}" id="inputPassword" placeholder="Password">
</div>
</div>
<div class="form-group row">
<label for="inputPasswordConfirm" class="col-sm-2 col-form-label">Confirm Password</label>
<div class="col-md-6">
<input type="password" class="form-control" th:field="${userForm.passwordConfirm}" id="inputPasswordConfirm" placeholder="Password">
</div>
</div>
<div class="form-group row">
<div class="offset-2 col-sm-10">
<button type="submit" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" class="btn btn-primary">Submit</button>
</div>
</div>
<small th:text="${error}"></small>
</form>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</body>
I binded correctly using th:field="${userForm.username}" but unable to find what is the problem here.
you have to take the model object into the form as follows
<form action="#" th:action="#{/registration}" th:object="${userForm}" method="post">
and add the getters and setters to the Person class

ASP.NET Core model binding

I'm trying to bind an edit action to a model which doesn't work. Here below the controller:
[Route("[controller]/[action]")]
public class CustomerController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public CustomerController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet("{_customerCode}")]
public IActionResult Edit(int _customerCode)
{
var customer = _unitOfWork.Customers.getCustomerByCode(_customerCode);
var customerDTO = Mapper.Map<CustomerModelDTO>(customer);
return View(customerDTO);
}
[HttpPost]
public IActionResult Edit(CustomerModelDTO model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var _customer = _unitOfWork.Customers.getCustomerByCode(model.CustomerCode);
if (_customer==null)
{
return NotFound();
}
Mapper.Map(model, _customer);
_unitOfWork.Complete();
return RedirectToAction("Detail", new { customerCode = _customer.CustomerCode });
}
}
And here is the view I am using:
#model Almiz.Dtos.CustomerModelDTO
<form asp-action="Edit" method="post">
<div class="form-horizontal">
<h4>CustomerModelDTO</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomerCode" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CustomerCode" class="form-control" />
<span asp-validation-for="CustomerCode" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="FirstName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="MiddleName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="MiddleName" class="form-control" />
<span asp-validation-for="MiddleName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="LastName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Telephone" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Telephone" class="form-control" />
<span asp-validation-for="Telephone" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Mobile" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Mobile" class="form-control" />
<span asp-validation-for="Mobile" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to Index</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
When I call the view and with the ID http://localhost:65001/Customer/Edit/1001, I get the all the information. However when I edit it and post the edited form I get resource not found error. Please help. Here below the model:
public class CustomerModelDTO
{
public int CustomerCode { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public double Telephone { get; set; }
public double Mobile { get; set; }
public string Email { get; set; }
}
I got it working. Here below the change.
[HttpPost("{customerCode}")]
public IActionResult Edit(int customerCode, CustomerModelDTO data)

How to Bind the list data thymeleaf html from to spring controller?

This is my Controller class
package com.myblog.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.myblog.model.User;
#Controller
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
#GetMapping(value="/user")
public String getUser(Model model){
model.addAttribute("user", new User());
return "user";
}
#PostMapping(value="/user")
public String postUser(#ModelAttribute("user") User user){
log.info("user :"+user);
return "user";
}
}
This is My Model class
user.java
package com.myblog.model;
import java.util.ArrayList;
import java.util.List;
public class User {
private int id;
private String name;
private List<Address> address=new ArrayList<Address>();
#Override
public String toString() {
return "User [name=" + name + ", address=" + address + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Address> getAddress() {
return address;
}
public void setAddress(List<Address> address) {
this.address = address;
}
}
address.java
package com.myblog.model;
public class Address {
private int id;
private String street;
private String city;
public int getAddid() {
return addid;
}
public void setAddid(int addid) {
this.addid = addid;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
This is my thymeleaf HTML page
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Page Title</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet" media="screen" th:href="#{css/bootstrap.min.css}"/>
<script src="/static/js/bootstrap.min.js" th:src="#{js/bootstrap.min.js}"></script>
</head>
<body>
<div class="container">
<h1> User Account</h1>
<form class="form-horizontal" th:action="#{/user}" method="POST" th:object="${user}">
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-5">
<input type="text" class="form-control" name="name" placeholder="Full name"/>
</div>
</div>
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Address</label>
<div class="col-sm-5">
<input type="text" class="form-control" name="address.city" placeholder="City"/>
</div>
</div>
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Street</label>
<div class="col-sm-5">
<input type="text" class="form-control" name="address.street" placeholder="street" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input type="submit" class="btn btn-primary" value="Add"/>
</div>
</div>
</form>
</div>
</body>
</html>
in controller user object does not bind the data into address model object.
output is user :user[name="name",address[]]
Your form seems to only manage one adress, but your domain model specifies a list of adresses. In this case you would need to name your input fields like address[0].street for the first address and so on.
So I'd consider to use a thymleaf iterator (th:each) to make all addresses manageable in your form. Then use th:field instead of defining name attributes. This should solve your problem.
<form class="form-horizontal" th:action="#{/user}" method="POST" th:object="${user}">
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-5">
<input type="text" class="form-control" th:field="*{name}" placeholder="Full name"/>
</div>
</div>
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Address</label>
<div class="col-sm-5">
<input type="text" class="form-control" th:field="*{address[0].city}" placeholder="City"/>
</div>
</div>
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Street</label>
<div class="col-sm-5">
<input type="text" class="form-control" th:field="*{address[0].street}" placeholder="street" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input type="submit" class="btn btn-primary" value="Add"/>
</div>
</div>
</form>

Spring Validation - Errors not displayed

I'm using a combination of Annotation validation and a Custom Validator
Object:
#Entity
#Table(name = "monitoringsystems")
public class MonitoringSystem {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NotNull(message = "Name must not be empty.")#Size(min=1, message="Name must not be empty.")
private String name;
#NotNull(message = "URL must not be empty.")#Size(min=1, message="Name must not be empty.")
private String url;
#NotNull(message = "Username must not be empty.")#Size(min=1, message="Name must not be empty.")
private String username;
#NotNull(message = "Password must not be empty.")#Size(min=1, message="Name must not be empty.")
private String password;
#NotNull(message = "Confirm Password must not be empty.")#Size(min=1, message="Name must not be empty.")
#Transient
private String passwordConfirm;
CustomValidator:
#Component
public class MonitoringSystemValidator implements Validator {
#Override
public boolean supports(Class<?> type) {
return MonitoringSystem.class.isAssignableFrom(type);
}
#Override
public void validate(Object o, Errors errors) {
MonitoringSystem monitoringSystem = (MonitoringSystem) o;
if(!monitoringSystem.getPassword().equals(monitoringSystem.getPasswordConfirm())){
errors.rejectValue("passwordConfirm", "Passwords are not equal.");
}
}
}
I initialize the custom validator in my controller and set the mapping for the form and the saving method.
Controller:
#Controller
public class MonitoringSystemController {
#Autowired
private MonitoringSystemValidator monitoringSystemValidator;
#InitBinder
public void dataBinding(WebDataBinder binder) {
binder.addValidators(monitoringSystemValidator);
}
#RequestMapping("/monitoringsystem/new")
public String newMonitoringSystem(Model model, HttpServletRequest request) {
MonitoringSystem monitoringSystem = new MonitoringSystem();
model.addAttribute("monitoringSystem", monitoringSystem);
request.getSession().setAttribute("anonymization", monitoringSystem.getAnonymization());
request.getSession().setAttribute("hosts", monitoringSystem.getHosts());
return "monitoringsystem/form";
}
#RequestMapping(value = "/monitoringsystem/save", method = RequestMethod.POST)
public String save(#Valid MonitoringSystem monitoringSystem, BindingResult result, HttpServletRequest request, Model model) {
if(result.hasErrors()){
model.addAttribute("monitoringSystem", monitoringSystem);
request.getSession().setAttribute("anonymization", request.getSession().getAttribute("anonymization"));
request.getSession().setAttribute("hosts", request.getSession().getAttribute("hosts"));
return "monitoringsystem/form";
}
//more code
In a first step I only want to change the CSS of my fields (I use bootstrap) so display the errors.
Form:
<form class="form-horizontal" th:modelAttribute="monitoringSystem" th:object="${monitoringSystem}" th:action="#{/monitoringsystem/save}" method="post">
<input type="hidden" th:field="*{id}"/>
<fieldset>
<legend>New Monitoring-System</legend>
<div class="form-group" th:classappend="${#fields.hasErrors('name')} ?: 'has-error has-danger'">
<label class="col-md-4 control-label" for="textinput">Systemname</label>
<div class="col-md-5">
<input th:field="*{name}" class="form-control input-md" type="text" />
</div>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('url')} ?: 'has-error has-danger'">
<label class="col-md-4 control-label" for="textinput">URL</label>
<div class="col-md-5">
<input th:field="*{url}" class="form-control input-md" type="text" />
</div>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('username')} ?: 'has-error has-danger'">
<label class="col-md-4 control-label" for="textinput">Username</label>
<div class="col-md-5">
<input th:field="*{username}" class="form-control input-md" type="text" />
</div>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('password')} ?: 'has-error has-danger'">
<label class="col-md-4 control-label" for="textinput">Password</label>
<div class="col-md-5">
<input th:field="*{password}" class="form-control input-md" type="password" />
</div>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('passwordConfirm')} ?: 'has-error has-danger'">
<label class="col-md-4 control-label" for="textinput">Confirm Password</label>
<div class="col-md-5">
<input th:field="*{passwordConfirm}" class="form-control input-md" type="password" />
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="singlebutton"></label>
<div class="col-md-4">
<a th:href="#{/monitoringsystem}" class="btn btn-default btn-small">Cancel</a> <button id="singlebutton" name="singlebutton" class="btn btn-primary btn-small">Submit</button>
</div>
</div>
</fieldset>
</form>
My validation is working correctly. The form is only saved if my fields are not null, the size is greater 1 and the password match. If not, my controller redirects me to the form.
The problem is, that my css don't change. So there must be a problem with my view-code or the errorBinding is not passed correctly to the view. But I can't find my mistake.
There was an error in my if condition which add the errorclasses. I had to change ${#fields.hasErrors('url')} ?: 'has-error has-danger' to ${#fields.hasErrors('*{name}')} ? 'has-error has-danger'

#ModelAttribute is not working in spring MVC with post

Hi I am developing my first spring mvc application. I am trying to add a form to db. For this I am using #ModelAttribute and it is not working.
My Controller:
#Controller
public class AddKPI {
#RequestMapping("/getAddKPIForm")
public ModelAndView addKPI(){
ModelAndView modelAndView = new ModelAndView("getAddKPIForm","kpi", new KPI());
String auditInfo = "User : "+getCurrentDateInStringFormat_YYYYMMDD_HHSSMM();
modelAndView.addObject("auditInfo",auditInfo);
return modelAndView;
}
#RequestMapping(value="/addKPITODB")
public ModelAndView add2DB(#ModelAttribute("kpi") KPI kpi){
System.out.println("In controller Method");
System.out.println("kpi.getKpi_name() = "+kpi.getKpi_name());
return new ModelAndView("adding_Success");
}
public static String getCurrentDateInStringFormat_YYYYMMDD_HHSSMM() {
String date_Str = null;
try {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
date_Str = sdf.format(date);
} catch (Exception pe) {
// TODO: Add catch code
pe.printStackTrace();
}
return date_Str;
}
}
My Form Code:
<div align="center">
<div style="width: 650px;">
<form:form class="form-horizontal" method="POST" modelAttribute="kpi" commandName="kpi" action="addKPITODB" >
<form:input type="hidden" name="id" value="122" path="id"></form:input>
<div class="form-group form-group-sm">
<label for="kpi_name" class="col-sm-2 control-label">KPI
Name</label>
<div class="col-sm-5">
<form:input type="text" class="form-control" id="kpi_name"
placeholder="KPI Name" name="kpi_name" required="required"
autofocus="autofocus" path="kpi_name"/>
</div>
</div>
<div class="form-group form-group-sm">
<label for="kpi_sql" class="col-sm-2 control-label">KPI SQL</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="K sql"
name="kpi_sql" id="kpi_sql" required="required">
</div>
</div>
<div class="form-group form-group-sm">
<label for="threshold" class="col-sm-2 control-label">Threshold</label>
<div class="col-sm-2">
<input type="text" class="form-control" placeholder="t"
name="threshold" id="threshold" required="required">
</div>
<label for="Operator" class="col-sm-3 control-label">Threshold
Operator</label>
<div class="col-xs-3">
<select class="form-control input-small" id="Operator"
name="Operator">
<option>G Than</option>
<option>L Than</option>
</select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="category" class="col-sm-2 control-label">Category</label>
<div class="col-xs-3">
<select class="form-control input-small" id="category"
name="category">
<option value="Business Health">Business Health</option>
<option value="Operations Health">Operations Health</option>
</select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="module" class="col-sm-2 control-label"> Module</label>
<div class="col-xs-3">
<select class="form-control input-small" id="module">
<option value="Finance">Finance</option>
<option value="Supply Chain">Supply Chain</option>
</select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="submodule" class="col-sm-2 control-label">Sub
Module</label>
<div class="col-xs-3">
<select class="form-control input-small" id="submodule"
name="submodule">
<option value="A/P (Accounts Payable)">A/P (Accounts
Payable)</option>
<option value="A/R (Accounts Receivable)">A/R (Accounts
Receivable)</option>
<option value="Inventory">Inventory</option>
<option value="Purchase">Purchase</option>
<option value="Sales">Sales</option>
<option value="Manufacturing">Manufacturing</option>
</select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="helptext" class="col-sm-2 control-label">Help
Text</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="helptext"
name="helptext" id="helptext" required="required">
</div>
</div>
<div class="form-group form-group-sm">
<label for="perf_reason" class="col-sm-2 control-label">Reason</label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="Reason"
name="perf_reason" id="perf_reason" required="required">
</div>
</div>
<!-- category , module, submodule -->
<!-- Operator , AutoMoniter_Enabled, submodule -->
<div class="form-group form-group-sm">
<label for="Xaxis_Description" class="col-sm-2 control-label">Xaxis_Description</label>
<div class="col-sm-10">
<input type="text" class="form-control"
placeholder="Xaxis_Description" name="Xaxis_Description"
id="Xaxis_Description" required="required">
</div>
</div>
<div class="form-group form-group-sm">
<label for="Yaxis_Desciption" class="col-sm-2 control-label">Yaxis_Desciption</label>
<div class="col-sm-10">
<input type="text" class="form-control"
placeholder="Yaxis_Desciption" name="Yaxis_Desciption"
id="Yaxis_Desciption" required="required">
</div>
</div>
<div class="form-group form-group-sm">
<label for="toEmail" class="col-sm-2 control-label">To
Email</label>
<div class="col-sm-4">
<input type="text" class="form-control" placeholder="toEmail"
name="toEmail" id="toEmail" required="required">
</div>
<label for="cc_email" class="col-sm-2 control-label">CC
Email</label>
<div class="col-sm-4">
<input type="text" class="form-control" placeholder="cc_email"
name="cc_email" id="cc_email" required="required">
</div>
</div>
<div class="form-group form-group-sm">
<label for="DSchemaName" class="col-sm-2 control-label">Detailed
View</label>
<div class="col-sm-3">
<input type="text" class="form-control" placeholder="DSchemaName"
name="DSchemaName" id="DSchemaName">
</div>
<div class="col-sm-3">
<input type="text" class="form-control" placeholder="DTableName"
name="DTableName" id="DTableName">
</div>
<div class="col-sm-4">
<input type="text" class="form-control" placeholder="DFieldName"
name="DFieldName" id="DFieldName">
</div>
</div>
<div class="form-group form-group-sm">
<label for="ame" class="col-sm-2 control-label">Auto
Mointer Enabled</label>
<div class="col-xs-3">
<select class="form-control input-small" id="ame"
name="AutoMoniter_Enabled">
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="Audit Info" class="col-sm-2 control-label">Audit
Info</label>
<div class="col-sm-5">
<input type="text" class="form-control" placeholder="Audit Info"
name="audit_info" id="Audit Info" readonly="readonly"
value="${auditInfo }">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div align="left">
<button type="submit" class="btn btn-primary btn-xs">Add
KPI</button>
</div>
</div>
</div>
</form:form>
</div>
</div>
MY KPI class:
#Entity
#Table(name="KPI")
public class KPI {
#Id
private int id;
public KPI(int id) {
super();
this.id = id;
}
public KPI(){
}
private String kpi_name;
private String kpi_sql;
private int threshold;
private String helptext;
private String perf_reason;
private String category;
private String module;
private String submodule;
private String status;
private String toEmail;
private String Operator;
private String AutoMoniter_Enabled;
private String cc_email;
private String audit_info;
private String Xaxis_Description;
private String Yaxis_Desciption;
private String DSchemaName;
private String DTableName;
private String DFieldName;
public String getXaxis_Description() {
return Xaxis_Description;
}
public void setXaxis_Description(String xaxis_Description) {
Xaxis_Description = xaxis_Description;
}
public String getYaxis_Desciption() {
return Yaxis_Desciption;
}
public void setYaxis_Desciption(String yaxis_Desciption) {
Yaxis_Desciption = yaxis_Desciption;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getKpi_name() {
return kpi_name;
}
public void setKpi_name(String kpi_name) {
this.kpi_name = kpi_name;
}
public String getKpi_sql() {
return kpi_sql;
}
public void setKpi_sql(String kpi_sql) {
this.kpi_sql = kpi_sql;
}
public int getThreshold() {
return threshold;
}
public void setThreshold(int threshold) {
this.threshold = threshold;
}
public String getHelptext() {
return helptext;
}
public void setHelptext(String helptext) {
this.helptext = helptext;
}
public String getPerf_reason() {
return perf_reason;
}
public void setPerf_reason(String perf_reason) {
this.perf_reason = perf_reason;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public String getSubmodule() {
return submodule;
}
public void setSubmodule(String submodule) {
this.submodule = submodule;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getToEmail() {
return toEmail;
}
public void setToEmail(String toEmail) {
this.toEmail = toEmail;
}
public String getOperator() {
return Operator;
}
public void setOperator(String operator) {
Operator = operator;
}
public String getAutoMoniter_Enabled() {
return AutoMoniter_Enabled;
}
public void setAutoMoniter_Enabled(String autoMoniter_Enabled) {
AutoMoniter_Enabled = autoMoniter_Enabled;
}
public String getCc_email() {
return cc_email;
}
public void setCc_email(String cc_email) {
this.cc_email = cc_email;
}
public String getAudit_info() {
return audit_info;
}
public void setAudit_info(String audit_info) {
this.audit_info = audit_info;
}
public String getDSchemaName() {
return DSchemaName;
}
public void setDSchemaName(String dSchemaName) {
DSchemaName = dSchemaName;
}
public String getDTableName() {
return DTableName;
}
public void setDTableName(String dTableName) {
DTableName = dTableName;
}
public String getDFieldName() {
return DFieldName;
}
public void setDFieldName(String dFieldName) {
DFieldName = dFieldName;
}
}
When I am hitting submit button it is not going to controller method "/addKPITODB" I am getting 404 error(URL is http://localhost:6006/EasyRUN/addKPITODB). If I remove #ModelAttribute it is going to controller method. What is the mistake I am doing. Please correct me.
Your help will be highly appreciate. Thank you.
I created a sample project with your code which works just fine:
git clone https://github.com/denis-zhdanov/spring-playground.git
cd spring-playground/
git checkout so-33429407
export GRADLE_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=n"
./gradlew jettyRun
Wait until the following line is printed - ':jettyRun > Running at http://localhost:8080/spring-playground'
Connect by remote debugger to the localhost:9999
Set a breakpoint at the org.denis.test.spring.mvc.MyController.add2DB()
Open 'http://localhost:8080/spring-playground/form.html' at the browser
Type any text there and press
The breakpoint is hit

Resources