select multiple not passing all the selected values - spring

path="userRoles" is multi select field. Which is populated with the method "initializeRoles()" from the controller. I have a converter also to convert Roles to UserRoles object. When I submit the form even after selecting all the Roles, I get only the first selected one always to the converter class as shown below. Why I am not getting String[] from JSP?
Output in the Converter class:
1
string
JSP code:
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# page isELIgnored="false" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>User Create Form</title>
<link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>
<link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link>
</head>
<body>
<div class="generic-container">
<%#include file="authheader.jsp" %>
<div class="well lead">User Create Form</div>
<form:form method="POST" modelAttribute="user" class="form-horizontal">
<form:input type="hidden" path="userid" id="userid"/>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="firstName">First Name</label>
<div class="col-md-7">
<form:input type="text" path="firstName" id="firstName" class="form-control input-sm"/>
<div class="has-error">
<form:errors path="firstName" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="middleName">Middle Name</label>
<div class="col-md-7">
<form:input type="text" path="middleName" id="middleName" class="form-control input-sm" />
<div class="has-error">
<form:errors path="middleName" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="lastName">Last Name</label>
<div class="col-md-7">
<form:input type="text" path="lastName" id="lastName" class="form-control input-sm" />
<div class="has-error">
<form:errors path="lastName" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="username">Username</label>
<div class="col-md-7">
<c:choose>
<c:when test="${edit}">
<form:input type="text" path="username" id="username" class="form-control input-sm" disabled="true"/>
</c:when>
<c:otherwise>
<form:input type="text" path="username" id="username" class="form-control input-sm" />
<div class="has-error">
<form:errors path="username" class="help-inline"/>
</div>
</c:otherwise>
</c:choose>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="password">Password</label>
<div class="col-md-7">
<form:input type="password" path="password" id="password" class="form-control input-sm" />
<div class="has-error">
<form:errors path="password" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="email">Email</label>
<div class="col-md-7">
<form:input type="text" path="email" id="email" class="form-control input-sm" />
<div class="has-error">
<form:errors path="email" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="userRoles">Roles</label>
<div class="col-md-7">
<form:select path="userRoles" items="${roles}" multiple="true" itemValue="roleid" itemLabel="roleName" class="form-control input-sm" />
<div class="has-error">
<form:errors path="userRoles" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-actions floatRight">
<c:choose>
<c:when test="${edit}">
<input type="submit" value="Update" class="btn btn-primary btn-sm"/> or Cancel
</c:when>
<c:otherwise>
<input type="submit" value="Register" class="btn btn-primary btn-sm"/> or Cancel
</c:otherwise>
</c:choose>
</div>
</div>
</form:form>
</div>
</body>
</html>
Controller code:
package com.rsa.tools.springmvc.web.controller;
import java.util.List;
import java.util.Locale;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.rsa.tools.springmvc.model.User;
import com.rsa.tools.springmvc.model.UserRoles;
import com.rsa.tools.springmvc.service.UserManagementService;
#Controller
#RequestMapping("/users")
public class UserController {
#Autowired
UserManagementService umService;
#Autowired
MessageSource messageSource;
#RequestMapping(value="/list", method=RequestMethod.GET)
public String listUsers(ModelMap model) {
List<User> users = umService.getAllUsersOrderedByUsername();
model.addAttribute("users", users);
return "userslist";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", false);
return "registration";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(#Valid User user, BindingResult result, ModelMap model) {
System.out.println(user);
System.out.println(result.getAllErrors());
if (result.hasErrors()) {
return "registration";
}
if(!umService.isUsernameUnique(user.getUsername())) {
FieldError usernameError = new FieldError("user","username",messageSource.getMessage("non.unique.username", new String[]{user.getUsername()}, Locale.getDefault()));
result.addError(usernameError);
return "registration";
}
umService.addUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
//return "success";
return "registrationsuccess";
}
#RequestMapping(value = { "/edit-user-{username}" }, method = RequestMethod.GET)
public String editUser(#PathVariable String username, ModelMap model) {
User user = umService.findByUsername(username);
model.addAttribute("user", user);
model.addAttribute("edit", true);
return "registration";
}
#RequestMapping(value = { "/edit-user-{username}" }, method = RequestMethod.POST)
public String updateUser(#Valid User user, BindingResult result, ModelMap model, #PathVariable String username) {
if (result.hasErrors()) {
return "registration";
}
umService.editUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
return "registrationsuccess";
}
#RequestMapping(value = { "/delete-user-{username}" }, method = RequestMethod.GET)
public String deleteUser(#PathVariable String username) {
umService.deleteUser(username);
return "redirect:/list";
}
#ModelAttribute("roles")
public List<UserRoles> initializeRoles() {
return umService.getAllUserRoles();
}
}
Converter code:
package com.rsa.tools.springmvc.configuration.web.converter;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import com.rsa.tools.springmvc.dao.UserDao;
import com.rsa.tools.springmvc.model.UserRoles;
#Component
public class UserRolesConverter implements Converter<Object, List<UserRoles>> {
#Autowired
UserDao userDao;
#Override
public List<UserRoles> convert(Object roles) {
List<UserRoles> userRoles = new ArrayList<UserRoles>();
System.out.println(roles);
if (roles instanceof String) {
System.out.println("string");
String sRoles = (String)roles;
UserRoles ur = userDao.findByRoleid(Long.parseLong(sRoles));
userRoles.add(ur);
} else if (roles instanceof String[]) {
System.out.println("string[]");
for (String role : (String[])roles) {
UserRoles ur = userDao.findByRoleid(Long.parseLong(role));
userRoles.add(ur);
}
}
return userRoles;
}
}
Web Configuration:
package com.rsa.tools.springmvc.configuration.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import com.rsa.tools.springmvc.configuration.web.converter.UserRolesConverter;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.rsa.tools.springmvc.web.controller", "com.rsa.tools.springmvc.configuration.web.converter" })
public class ApplicationWebConfiguration extends WebMvcConfigurerAdapter {
#Autowired
UserRolesConverter userRolesConverter;
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(userRolesConverter);
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}

Added one more converter class for String[]. Then I started getting multiple values which were selected in in UI. Why I have to write two Converter classes. Is there a way to combine both the classes.
public class UserRolesConverter1 implements Converter<String[], List<UserRoles>> {
...
#Override
public List<UserRoles> convert(String[] roles) {

Related

Neither BindingResult nor plain target object for bean name 'user' available as request attribute during form implemetntaion

I am getting this error when I run my Project and I tried all the fixes online but it did not work.
Neither BindingResult nor plain target object for bean name 'user' available as request attribute during form implementation
I am pasting the code below
Do I have to create a table in my database or how do I fix this?
I am trying to read the values entered from the form to another jsp page using spring mvc but without using annotations. And while doing so I am getting this error: Neither BindingResult nor plain target object for bean name 'user' available as request attribute My Controller Class code is as follows:
User.java
package User;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
private String gender;
private String email;
private String city;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
UserController.java
package Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import User.User;
#Controller
public class UserController {
#Autowired
private UserRepository userRepository;
#GetMapping("/greeting")
public String greetingForm(Model model) {
model.addAttribute("user", new User());
return "greeting";
}
#PostMapping("/greeting")
public String greetingSubmit(#ModelAttribute User user , Model model) {
User newUser = new User();
newUser.setName(user.getName());
newUser.setAge(user.getAge());
newUser.setGender(user.getGender());
newUser.setEmail(user.getEmail());
newUser.setCity(user.getCity());
userRepository.save(user);
return "result";
}
#GetMapping("/all")
public String getMeassage(Model model ) {
Iterable<User> users = userRepository.findAll();
model.addAttribute("users", users);
return "all";
}
}
greeting.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Form Submission</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<br><br>
<h2 style="color:green">Form</h2>
<br><br>
<form class="form-horizontal" role="form" action="#" th:action="#{/greeting}" th:object="${user}" modelAttribute="user" method="post">
<div class="form-group" style="width:300px">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Enter name">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="age" class="col-sm-2 control-label">Age</label>
<div class="col-sm-10">
<input type="text" th:field="*{age}" class="form-control" id="age" placeholder="Enter age">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="gender" class="col-sm-2 control-label">Gender</label>
<div class="col-sm-10">
<input type="text" th:field="*{gender}" class="form-control" id="gender" placeholder="Enter gender(M or F)">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Enter email">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="city" class="col-sm-2 control-label">City</label>
<div class="col-sm-10">
<input type="text" th:field="*{city}" class="form-control" id="city" placeholder="Enter city">
</div>
</div>
<div class="form-group">
<div>
<button type="submit" class="btn btn-primary" id="btn">Submit</button>
<input type="reset" class="btn btn-warning" value="Reset" />
</div>
</div>
</form>
</body>
</html>
Thanks in advance for the help

How to use LocalDateTime

what is the right way to solve LocalDateTime error?
I am new to spring therefore I have tried to look for the way to solve this online but I cannot get around it.
This is my entity
package com.reserve.entities;
import java.time.LocalDateTime;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
#Entity
public class Flight extends AbstractEntity {
private String flightNumber;
private String operatingAirlines;
private String departureCity;
private String arrivalCity;
#DateTimeFormat(iso=ISO.DATE)
private Date dateOfDeparture;
#Column(name="estimatedDepartureTime",columnDefinition="TIMESTAMP")
private LocalDateTime estimatedDepartureTime;
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public String getOperatingAirlines() {
return operatingAirlines;
}
public void setOperatingAirlines(String operatingAirlines) {
this.operatingAirlines = operatingAirlines;
}
public String getDepartureCity() {
return departureCity;
}
public void setDepartureCity(String departureCity) {
this.departureCity = departureCity;
}
public String getArrivalCity() {
return arrivalCity;
}
public void setArrivalCity(String arrivalCity) {
this.arrivalCity = arrivalCity;
}
public Date getDateOfDeparture() {
return dateOfDeparture;
}
public void setDateOfDeparture(Date dateOfDeparture) {
this.dateOfDeparture = dateOfDeparture;
}
public LocalDateTime getEstimatedDepartureTime() {
return estimatedDepartureTime;
}
public void setEstimatedDepartureTime(LocalDateTime estimatedDepartureTime) {
this.estimatedDepartureTime = estimatedDepartureTime;
}
#Override
public String toString() {
return "Flight [flightNumber=" + flightNumber + ", operatingAirlines=" + operatingAirlines + ", departureCity="
+ departureCity + ", arrivalCity=" + arrivalCity + ", dateOfDeparture=" + dateOfDeparture
+ ", estimatedDepartureTime=" + estimatedDepartureTime + "]";
}
}
This is my controller.
I am not sure which information is required.
Please let me know if there are more information that could help.
package com.reserve.controllers;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.reserve.entities.Flight;
import com.reserve.repository.FlightRepository;
#Controller
public class FlightController {
#Autowired
private FlightRepository flightRepository;
#RequestMapping("findFlights")
public String findFlights(
#RequestParam("from")String from,
#RequestParam("to")String to,
#RequestParam("departureDate")
#DateTimeFormat(pattern = "MM-dd-yyyy")
Date departureDate,
Model model)
{
List<Flight> flights = flightRepository.findFlights(from,to,departureDate);
model.addAttribute("flights", flights);
return "displayFlights";
}
#RequestMapping("/ourFlights")
public String ourFlights() {
return "ourFlights";
}
#RequestMapping(value="/add", method=RequestMethod.POST)
public String addFlights(#ModelAttribute("flight")Flight flight,Model model) {
Flight save = flightRepository.save(flight);
String msg = save.getFlightNumber() + " from " + save.getDepartureCity() + " to "
+ save.getArrivalCity() + " has been added.";
model.addAttribute("msg", msg);
return "ourFlights";
}
}
This is my JSP file
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Money Wise</title>
<link rel="stylesheet" href="/reserve/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/reserve/css/custom.css"/>
</head>
<body>
<div class="container">
<div id="body">
<nav class="navbar navbar-expand-lg navbar-light bg-lights">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="home">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Ideology</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Faq</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">News</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0 pull-right">
<input class="form-control mr-sm-2" type="search" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<!-- Site Body -->
<div id="content" class="container">
<div class="row">
<div id="leftMain" class="col-sm-3">
<img src="/reserve/images/jim.png"width=100%/>
</div>
<div id="mainBody" class="col-sm-9 ">
<h2>Add Flights</h2>
<form action="add" method="post">
<div class="form-group">
<label for="flightNumber">Flight number</label>
<input type="text" class="form-control" name="flightNumber" placeholder="Flight number"/>
</div>
<div class="form-group">
<label for="operatingAirlines">Operating airlines</label>
<input type="text" class="form-control" name="operatingAirlines" placeholder="Operating airlines"/>
</div>
<div class="form-group">
<label for="departureCity">Departure city</label>
<input type="text" class="form-control" name="departureCity" placeholder="Departure city"/>
</div>
<div class="form-group">
<label for="arrivalCity">Arrival city</label>
<input type="text" class="form-control" name="arrivalCity" placeholder="Arrival city"/>
</div>
<div class="form-group">
<label for="dateOfDeparture">Date of departure</label>
<input type="Date" class="form-control" name="dateOfDeparture" placeholder="Date of departure"/>
</div>
<div class="form-group">
<label for="estimatedDepartureTime">Estimated departure time</label>
<input type="datetime-local" class="form-control" name="estimatedDepartureTime" placeholder="Estimated departure time"/>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- JS, Popper.js, and jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js"></script>
<script src="/reserve/js/bootstrap.min.js"></script>
</body>
</html>
This is the error I get
Field error in object 'flight' on field 'estimatedDepartureTime': rejected value [2020-06-20T17:35]; codes
[typeMismatch.flight.estimatedDepartureTime,typeMismatch.estimatedDepartureTime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [flight.estimatedDepartureTime,estimatedDepartureTime]; arguments []; default message [estimatedDepartureTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'estimatedDepartureTime';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type
[java.lang.String] to type [#javax.persistence.Column java.time.LocalDateTime] for value '2020-06-20T17:35'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-06-20T17:35]]]
``````
You can try to use Spring The Formatter SPI to convert Date expressed as String to LocalDateTime and vice versa.
public class DateTimeFormatters {
public static class LocalDateTimeFormatter implements Formatter<LocalDateTime> {
#Override
public LocalDateTime parse(String pattern, Locale locale) throws ParseException {
return LocalDateTime.parse(pattern, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
#Override
public String print(LocalDateTime object, Locale locale) {
return object.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
}
}
And register your Formatter e.g
public class ApplicationConfig implements WebMvcConfigurer {
...
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateTimeFormatters.LocalDateTimeFormatter());
}
...
}

Themeleaf issue with can not be null variable

I was trying to send the posts to DB. However,when I tried to use themeleaf, it shows me the following error:
EL1007E: Property or field 'name' cannot be found on null Exception evaluating SpringEL expression: "name" (template: "StudentForm" - line 264, col 49) An error happened during template parsing (template: "class path resource [templates/StudentForm.html]")
This is what I tried below:
StudentForm.html
<div class="col-lg-10">
<div class="card">
<div class="card-header">
<strong>Basic Form</strong> Elements
</div>
<div class="card-body card-block">
<form th:action="#{/StudentForm}" th:Object="${student}" method="post" enctype="multipart/form-data" class="form-horizontal" role="form">
<div class="row form-group">
<div class="col col-md-3">
<label for="text-input" th:field="*{name}" class=" form-control-label">Ismi sharifi</label>
</div>
<div class="col-12 col-md-9">
<input type="text" id="text-input" placeholder="Iltimos ismni kiriting" class="form-control">
</div>
</div>
<div class="row form-group">
<div class="col col-md-3">
<label for="select" class=" form-control-label">Fakulteti</label>
</div>
<!-- <div class="col-12 col-md-9">
<select name="select" id="select" class="form-control">
<option value="0">Fakultetni tanlang</option>
<option value="1">Option #1</option>
<option value="2">Option #2</option>
<option value="3">Option #3</option>
</select>
</div>
</div> -->
<div class="row form-group">
<div class="col col-md-3">
<label for="email-input" class=" form-control-label">Email Input</label>
</div>
<div class="col-12 col-md-9">
<input type="email" id="email-input" th:field="*{email}" placeholder="Emailni kiriting" class="form-control">
<small class="help-block form-text"></small>
</div>
</div>
<div class="row form-group">
<div class="col col-md-3">
<label for="text-input" class=" form-control-label">To'langan summa</label>
</div>
<div class="col-12 col-md-9">
<input type="text" id="text-input" placeholder="Summani kiriting" class="form-control">
</div>
</div>
<div class="row form-group">
<div class="col col-md-3">
<label for="file-input" class=" form-control-label">File input</label>
</div>
<div class="col-12 col-md-9">
<input type="file" id="file-input" name="file-input" class="form-control-file">
</div>
</div>
</form>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary btn-sm">
<i class="fa fa-dot-circle-o"></i> Yuklash
</button>
<button type="reset" class="btn btn-danger btn-sm">
<i class="fa fa-ban"></i> Reset
</button>
</div>
</div>
StudentController.java
package io.javabrains;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import io.javabrains.Entities.Student;
import io.javabrains.repository.StudentRepository;
import io.javabrains.service.StudentService;
#Controller
public class StudentController {
#Autowired
private StudentRepository repository;
#Autowired
private StudentService service;
#RequestMapping(value= {"/student"},method=RequestMethod.GET)
public ModelAndView student(HttpServletRequest request) {
request.setAttribute("Student", service.findAll());
request.setAttribute("mode", "MODE_TASKS");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("student");
return modelAndView;
}
#RequestMapping(value="/StudentForm",method=RequestMethod.POST)
public ModelAndView studentForm(#Valid Student student,BindingResult bindingResult,ModelMap modelMap)
{
ModelAndView modelAndView = new ModelAndView();
service.addStudent(student);
modelAndView.addObject("student",new Student());
modelAndView.setViewName("studentForm");
return modelAndView;
}
#RequestMapping(value={"/StudentForm"},method=RequestMethod.GET)
public ModelAndView studentForm() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("StudentForm");
return modelAndView;
}
public List<Student>getAllEmployers(){
return service.findAll();
}
StudentEntity.java
package io.javabrains.Entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "studentId")
private int studentId;
#Column(name="name")
#NotNull(message = "Name is compulsort")
private String Name;
#Column(name="email")
#NotNull(message = "Email is compulsory")
private String Email;
#Column(name="department")
#NotNull(message = "department is compulsort")
private String Department;
#Column(name="amount")
#NotNull(message = "Amount is compulsort")
private double Amount;
#ManyToOne
#JoinColumn(name="studentId",referencedColumnName="id",insertable=false, updatable=false)
private DepartmentCategory departmentCategory;
First of all your controller should contain get method which returns Student object as a form to bind. You missed that. It should look something like this:
#RequestMapping(value={"/StudentForm"},method=RequestMethod.GET)
public ModelAndView studentForm() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("student", new Student()) //returns object to thymeleaf context
modelAndView.setViewName("StudentForm");
return modelAndView;
}
then you should change your naming convention in your student class, fields should start with lower case. You should notice that you have field Name in your Student class but you want to map th:field="*{name}" in thymeleaf view.
Read something about DTO and Models because you shouldn't use your entities directly in controller layer

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>

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

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.

Resources