Form with hashset attribute jsp spring mvc - spring

I am working with spring mvc and i want to know how get a hashset from a checkbox
Muy problem is that the checkbox return null

In your controller class, in any method, you need to populate hashset in Model and use it page.
For e.g.
#Controller
#RequestMapping("/member.htm")
public class MemberController {
#RequestMapping(method = RequestMethod.GET)
public String initForm(Model model) {
Member member = new Member();
Set<String> data = new HashSet<String>();
courses.add("Yoga");
courses.add("Stretching");
courses.add("Pilates");
courses.add("Aerobic");
courses.add("Oriental");
model.addAttribute("courses", courses);
return "member";
}
}
Use spring-taglib for use HashSet like:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<title>Spring MVC checkbox</title>
</head>
<body>
<h2>Subscribe to the gym</h2>
<form:form method="POST" commandName="member">
<table>
<tr>
<td>Choose the courses you like:</td>
<td><form:checkboxes path="courses" items="${courses}" />
</td>
</tr>
<tr>
<td><input type="submit" name="submit" value="Submit"></td>
</tr>
<tr>
</table>
</form:form>
</body>
</html>

Related

Why do am I getting error "java.lang.IllegalStateException" after putting <form:form> tag in jsp file of spring?

I have 2 tables, city and hotel_details in my database. I am trying to fetch the data from these tables and populating inside a form for registering the customer. But I am getting "java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute" as error.
JSP file
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<head>
<title>Search Hotels</title>
</head>
<body>
<h4>Search Hotels</h4>
<form:form action="search">
<table>
<tr>
<td>City:</td>
<td>
<form:select path="cities">
<form:options items="${cities}" />
</form:select>
</td>
</tr>
<tr>
<td>Hotel:</td>
<td>
<form:select path="hotels">
<form:options items="${hotels}" />
</form:select>
</td>
</tr>
<tr>
<td>Date:</td>
<td>
<input type="date" id="date" name="date">
</td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Check Availability">
</td>
</tr>
</table>
</form:form>
Controller
#Controller
public class HomeController {
//need a controller method to show the initial HTML form
#Autowired(required=true)
private CityDAO cityDAO;
#Autowired(required=true)
private HotelDetailsDAO hotelDetailsDAO;
#RequestMapping("/")
public String showCheckAvailablityForm(Model theModel) {
// get customers from the dao
//List<City> theCities = cityDAO.getCities();
List<String> theCities = cityDAO.getCities();
Set<String> theHotels = hotelDetailsDAO.getHotels();
// add the customers to the model
theModel.addAttribute("cities", theCities);
theModel.addAttribute("hotels", theHotels);
//printing the data fetched
System.out.println("In HomeController showCheckAvailability method where city name is being fetched from city table");
theCities.forEach((n) -> System.out.println(n));
System.out.println("printing hotels");
for (String temp : theHotels) {
System.out.print(temp + " ");
}
return "checkAvailability-form";
}
#RequestMapping("/search")
public String searchResult(#RequestParam("cityName") String theCityName, #RequestParam("hotelName") String theHotelName,Model model) {
System.out.println("processed successfully");
return null;
}
}
When you use <form:form> attribute, it requires you to specify model object that should be bound to form tag. If you don't specify any model attribute default name is used as command.
Following is the description of form:form tag from spring-form.tld -
<attribute>
<description>Name of the model attribute under which the form object is exposed.
Defaults to 'command'.</description>
<name>modelAttribute</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>Name of the model attribute under which the form object is exposed.
Defaults to 'command'.</description>
<name>commandName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
As you don't have any model object bound to form, try removing form:form tag and use HTML form tag and also make sure you match input parameter names with method parameter names. i.e -
<form action="search">
...
</form>

ModelAttribute Doesn't return any value from front end to back end

I'm using spring boot and thymeleaf to create a form to collect the data from front-end and update the database at back-end. I'm having trouble to pass the object value by using ModelAttribute. I can almost guaranty my repository and my bean work fine because I have written Junit test case against it and I can see the update from DB. I tried to use th:field at the html page, but it doesn't give me any default value in the field, so I have to use th:value. The print out statements in the controller just keep return 0. It feels like (#ModelAttribute("city") CityBean city) just never pass any data into the variable city. I can't really tell where the problem is after hours of the debugging. I will attach my code here. Thank you very much for helping.
My bean:
public class CityBean {
int cityID;
int population;
String cityName;
String state;
My Repository/DAO:
public int updatePopulation(CityBean city) {
String sql = "UPDATE CITY SET population = ? WHERE cityID = ?";
Object[] args = {city.getPopulation(), city.getCityID()};
int[] types = {Types.VARCHAR, Types.INTEGER};
return jdbcTemplate.update(sql, args, types);
}
My controller:
#RequestMapping(value = "/action", method = RequestMethod.POST)
public String updatePopulation(#ModelAttribute("city") CityBean city) {
System.out.println("This is city ID " + city.getCityID());
System.out.println("This is city population " + city.getPopulation());
cityRepository.updatePopulation(city);
return "redirect:/cityInfo";
}
My Front-end HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>CS6400 Fall 2020 Team 017 Project</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
<h1 style="text-align:center">City Population Update Form</h1>
<br>
<form action="#" th:action="#{/action}" th:object="${city}" method="post" modelAttribute="city">
>
<table class="table">
<thead>
<tr>
<th scope="col">City ID</th>
<th scope="col">City Name</th>
<th scope="col">State</th>
<th scope="col">Population</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr >
<td><input type="text=" th:value="*{cityID}" readonly="readonly"></td>
<td><input type="text=" th:value="*{cityName}" readonly="readonly"></td>
<td><input type="text=" th:value="*{state}" readonly="readonly"></td>
<td><input type="text=" th:value="*{population}" ></td>
<td>
<button type="submit" class="btn btn-primary">Update Population</button>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
Problem solved, I added name="pramName" in the input tag then everything works fine.

Spring form validation - errors are not displayed

I have following situation:
I try to create a simple form to edit information about a movie. Therefor I use spring mvc with jsp.
For the validation I use the JSR 303 hibernate implementation (hibernate-validator 4.2.0).
My problem is that if there are validation errors (BindResults hasErrors method returns true) I can only display the errors with
<form:errors path="*" />
and not fieldspecific. like with:
<form:errors path="title" />
I have no idea why but all errors are displayed in at the path="*" errortag, but none at the fieldspecific ones. The only errors which are displayed right to the field are some which brought an exception i.e.
Failed to convert property value of type java.lang.String to required type int for property runtime; nested exception is java.lang.NumberFormatException: For input string: "")
the important parts of my jsp file look like this:
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form commandName="movie">
<fieldset>
<form:errors path="*" cssClass="formErrorBlock"/>
<table>
<tr>
<td><form:label path="title">Title:</form:label></td>
<td>
<form:input path="title"/>
<form:errors path="title" cssClass="formFieldError"/>
</td>
</tr>
<tr>
<td><form:label path="runtime">Runtime:</form:label></td>
<td>
<form:input path="runtime"/><br />
<form:errors path="runtime" cssClass="formFieldError" />
</td>
</tr>
<tr>
<td><form:label path="imdbId">IMDB-ID:</form:label></td>
<td>
<form:input path="imdbId"/><br />
<form:errors path="imdbId" cssClass="formFieldError" />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" />
</td>
</tr>
</table>
</fieldset>
</form:form>
My Controller:
#Controller
public class MovieController {
#Autowired
private MovieService _movieService;
//some other methods...
#RequestMapping(value="/movie/{pMovieId}/edit", method = RequestMethod.GET)
public String showForm(ModelMap pModel, #PathVariable Integer pMovieId) {
Movie movie = _movieService.getMovieById(pMovieId);
pModel.addAttribute("movie", movie);
return "edit/movie";
}
#RequestMapping(value="/movie/{pMovieId}/edit", method = RequestMethod.POST)
public String editMovieSave(#Valid Movie pMovie, BindingResult pResult, #PathVariable Integer pMovieId, ModelMap pModel) {
Movie movie = _movieService.getMovieById(pMovieId);
if(pResult.hasErrors()) {
return "edit/movie";
}
//save
//redirect to moviepage
return "redirect:/movie/" + pMovieId;
}
}
and finally my movie class:
public class Movie implements Serializable{
private int _id;
#NotEmpty
#Size(min=3)
private String _title;
#NotEmpty
private String _filename;
#Pattern(regexp="tt+[0-9]{7}")
private String _imdbId;
#Min(value=1)
private int _runtime;
//getters and setters....
}
I know this question has been asked a lot of times before, but none of the answers worked with me.
thanks for your help
I solved it by renaming the attributes (removing the underlines). However it was like "jpprade" said (maybe there are accessed by reflection).
For those who can't rename the class attributes (in case of some codingconventions, ...) can annotate the getter methods.

The request sent by the client was syntactically incorrect, Spring with Hibernate Annotations

I searched everywhere for this error and looked through every single thread here with the same title, changed a lot in my code but still, the error is there.
it says:
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.
Apache Tomcat/7.0.35
My Controller code is:
#RequestMapping(value = "/manageInventory.htm", method = RequestMethod.GET)
public ModelAndView manageInventory(HttpSession session) {
ArrayList<Product> products = new ArrayList<Product>();
Manufacturer manufacturer = (Manufacturer) manufacturerDAO
.getByUsername(((UserAccount) session.getAttribute("user"))
.getUsername());
products = productDAO.getProductListByManufacturer(manufacturer
.getManufacturerName());
System.out.print(products.get(0).getProductName());
ModelAndView view = new ModelAndView("manageInventory");
view.addObject("products", products);
InventoryItem inventoryItem = new InventoryItem();
view.addObject("inventoryItem", inventoryItem);
return view;
}
#RequestMapping(value = "/manufacture.htm", method = RequestMethod.POST)
public ModelAndView manufactureProduct(HttpSession session, BindingResult result,
#ModelAttribute("inventoryItem") #Valid InventoryItem inventoryItem) {
System.out.print(result.getErrorCount()+" "+result.getAllErrors());
ModelAndView view = null;
if(!result.hasErrors())
{
Manufacturer manufacturer = manufacturerDAO
.getByUsername(((UserAccount) (session.getAttribute("user")))
.getUsername());
inventoryItem.setAvailability(true);
inventoryItem.setManufacturer(manufacturer);
manufacturer.getInventory().add(inventoryItem);
manufacturerDAO.update(manufacturer);
view = new ModelAndView("done");
}
else
{
view = new ModelAndView("manageInventory");
}
return view;
}
The first method adds inventoryItem into the model and I am fetching that for validations afterwards.
I am using tiles so,My tile for this is:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<body>
<h2>Add Inventory</h2>
<br />
<form:form modelAttribute="inventoryItem" action="manufacture.htm" method="post">
<table>
<tr>
<td>Select Product:</td>
<td><form:select path="product">
<c:forEach var="product" items="${products}">
<form:option value="${product}">${product.productName}</form:option>
</c:forEach>
</form:select></td>
<td>Select Quantity:</td>
<td>
<form:input path="quantity" placeholder="Quantity"/><br />
<font color="red"><form:errors path="quantity"/> </font>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Manufacture">
</td>
</tr>
</table>
</form:form>
</body>
My POJO has the following validation:
#NotNull
private int quantity;
Please help. Thanks in advance.
I forgot to add HttpServletRequest request to the method input parameters.
I added it and it stared working. strange, but worked. :)

How to reject a field from bean for validation when binding?

I have three fields department_Id,department_Name,department_location in departmentForm act as a model object in this model form.
I have use annotation to validate the fields. Now, I want to only use two fields in different jsp page say create.jsp and one field in different jsp page say getDepartmentById.
When I press submit button of create.jsp, validation is happening but after providing correct information its not submitted cause in this page.
I haven't give one field department_Id which is auto generated by my DAO layer. So, please help me, how to reject this value to execute my create.jsp page for successfully creating department in database.
When I printed the BindingResult object, it shown as follow:
Field error in object 'departmentForm' on field 'departmentId': rejected value [null];
codes [NotEmpty.departmentForm.departmentId,NotEmpty.departmentId,NotEmpty.java.lang.String,NotEmpty];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [departmentForm.departmentId,departmentId]; arguments [];
default message [departmentId],org.hibernate.validator.constraints.NotEmpty.message},
[Ljava.lang.Class;#4fc4a198,[Ljava.lang.Class;#764d2b11];
default message [may not be empty]`
This is how I coded in controller:
#RequestMapping(value = "/createDepartment", method = RequestMethod.POST)
public String createEmployee(#Valid DepartmentForm departmentForm,
BindingResult bindingResult, Map<String, DepartmentForm> model)
throws Exception {
if (bindingResult.hasErrors()) {
System.out.println(bindingResult);
bindingResult.reject(departmentForm.getDepartmentId());
return "departmentForm";
}
System.out.println("mr ankur jadiy");
model.put("departmentForm", departmentForm);
departmentForm.setUpdateStatus('A');
if (departmentForm.getUpdateStatus() == 'A') {
departmentServiceImpl
.actionDecider(convertDeptFormToDeptBO(departmentForm));
}
return "Success";
}
my DepartmentForm code is as follow:
package com.nousinfo.tutorial.model;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class DepartmentForm {
#NotEmpty
#Size(min = 1, max = 20,message="")
private String departmentId;
#NotEmpty
private String departmentName;
private String departmentLocation;
private Character updateStatus;
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public String getDepartmentLocation() {
return departmentLocation;
}
public void setDepartmentLocation(String departmentLocation) {
this.departmentLocation = departmentLocation;
}
public Character getUpdateStatus() {
return updateStatus;
}
public void setUpdateStatus(Character updateStatus) {
this.updateStatus = updateStatus;
}
}
and my create.jsp is
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://jakarta.apache.org/taglibs/input-1.0" prefix="input"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="s"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Create Department</title>
<link rel="stylesheet" href="css/style.css" type="text/css"></link>
</head>
<body>
<table width="1254" height="74" border="0" align="center">
<tr>
<td width="300" height="68" align="center" bgcolor="#99CCFF"><h2>
<span class="style1">Employee Details </span>
</h2></td>
<td width="100" height="68" align="center" bgcolor="#FFFFFF"><img
src="./image/emps.jpg" width="190" height="92" /></td>
</tr>
</table>
<p>
<br />
</p>
<hr size="1" width="786">
<form:form id="form" method="post" action="/EmployeeWebSpring/departmentController/createDepartment"
modelAttribute="departmentForm">
<table>
<tr>
<form:hidden path="updateStatus" />
</tr>
<tr>
<td>
Department_Name:
<font color="red"><form:errors path="departmentName" /></font>
</td>
</tr>
<tr>
<td><form:input path="departmentName" /></td>
</tr>
<tr>
<td>
Department_Location:
<font color="red"><form:errors path="departmentLocation" /></font>
</td>
</tr>
<tr>
<td><form:input path="departmentLocation" /></td>
</tr>
</table>
<br>
<br />
<p> </p>
<br>
<tr>
<td><input type="submit" name="method" value="save" /></td>
<td><input type="submit" name="method" value="cancel" /></td>
</tr>
<hr size="1" width="786">
<p> </p>
</form:form>
</body>
</html>
What the error says is that you're missing value for departmentId, which is not surprising since you defined it as
#NotEmpty
#Size(min = 1, max = 20,message="")
You don't really need to validate departmentId if it's autogenerated by your code. You probably should remove it from the DepartmentForm, especially since it's not in the form, or at least make it optional.
You can make it mandatory in your business object, but the form backing object should reflect what's in the form.
update
If departmentId is a database-generated id, you should set it as disallowed in your controller's InitBinder:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(new String[] { "departmentId" });
}

Resources