listing values in spring - spring

I am doing following
List list=new ArrayList();
list.add(new String[] {"1","java"});
model.addAttribute("tagList", list);
And in view
<form:select path="probTag">
<form:options items="${tagList}" itemLabel="${tagList[0]}" itemValue="${tagList[1]}"/>
</form:select>
but this is not working. What else can be done to solve the problem ???

<form:options> can't work with arrays this way. Use either a class to encapsulate option
class Tag {
public String id;
public String name;
public Tag(String id, String name) {
this.id = id;
this.name = name;
}
}
-
list.add(new Tag("1","java"));
-
<form:select path="probTag">
<form:options items="${tagList}" itemLabel="name" itemValue="id" />
</form:select>
or iterate over the options manually
<form:select path="probTag">
<c:forEach var = "t" items = "${tagList}">
<form:option value="${t[0]}">${t[1]}</form:option>
</c:forEach>
</form:select>

Related

How to make Search data using Spring boot

i am a beginner of spring boot framework.i want to work with search records using spring boot application. my index.html is loaded successfully when i enter the employee id on the employee id textbox and click search button relevant employee name result want to display the below textbox.but i don't know how to pass it .what i tired so so i attached below.
index.html
<form action="#" th:action="#{/search}" th:object="${employee}" method="post">
<div alight="left">
<tr>
<label class="form-label" >Employee ID</label>
<td>
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{id}" class="form-control" placeholder="Employee ID" />
</td>
</tr>
</div>
<br>
<tr>
<td colspan="2"><button type="submit" class="btn btn-info">Search</button> </td>
</tr>
<div alight="left">
<tr>
<label class="form-label" >Employee Name</label>
<td>
<input type="text" th:field="*{ename}" class="form-control" placeholder="Employee Name" />
</td>
</tr>
</div>
</form>
Controller
#Controller
public class EmployeeController {
#Autowired
private EmployeeService service;
#GetMapping("/")
public String add(Model model) {
List<Employee> listemployee = service.listAll();
// model.addAttribute("listemployee", listemployee);
model.addAttribute("employee", new Employee());
return "index";
}
#RequestMapping("/search/{id}")
public ModelAndView showSearchEmployeePage(#PathVariable(name = "id") int id) {
ModelAndView mav = new ModelAndView("new");
Employee emp = service.get(id);
mav.addObject("employee", emp);
return mav;
}
}
Entity
#Entity
public class Employee {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String ename;
private int mobile;
private int salary;
public Employee() {
}
public Employee(Long id, String ename, int mobile, int salary) {
this.id = id;
this.ename = ename;
this.mobile = mobile;
this.salary = salary;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getMobile() {
return mobile;
}
public void setMobile(int mobile) {
this.mobile = mobile;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
#Override
public String toString() {
return "Employee [id=" + id + ", ename=" + ename + ", mobile=" + mobile + ", salary=" + salary + "]";
}
Repository
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
It is easiest to create a dedicated form data object:
public class EmployeeSearchFormData {
private long employeeId;
// getter and setter
}
In the controller:
#Controller
public class EmployeeController {
#Autowired
private EmployeeService service;
#GetMapping("/")
public String add(Model model) {
model.addAttribute("employeeSearchFormData", new EmployeeSearchFormData());
return "index";
}
#PostMapping("/search")
public String doSearchEmployee(#ModelAttribute("employeeSearchFormData") EmployeeSearchFormData formData, Model model) {
Employee emp = service.get(formData.getEmployeeId());
model.addAttribute("employee", emp);
return "index";
}
}
Thymeleaf template:
<form action="#" th:action="#{/search}" th:object="${employeeSearchFormData}" method="post">
<div alight="left">
<tr>
<label class="form-label" >Employee ID</label>
<td>
<input type="text" th:field="*{employeeId}" class="form-control" placeholder="Employee ID" />
</td>
</tr>
</div>
<br>
<tr>
<td colspan="2"><button type="submit" class="btn btn-info">Search</button> </td>
</tr>
<div alight="left">
<tr>
<label class="form-label" >Employee Name</label>
<td>
<input type="text" th:field="${employee.ename}" class="form-control" placeholder="Employee Name" />
</td>
</tr>
</div>
</form>
Note the use of th:field="${employee.ename}" and not use *{...}. I also removed the hidden field as it does not seem needed to have it to me.
As an alternative, you can have the #PostMapping redirect to /employee/<id> if there is an endpoint available like that:
#PostMapping("/search")
public String doSearchEmployee(#ModelAttribute("employeeSearchFormData") EmployeeSearchFormData formData) {
return "redirect:/employee/" + formData.getEmployeeId();
}

Spring boot+Web mvc+JPA using CrudRepository giving issue on insert of a row using save method throwing EntityExistsException

Among CRUD operation Create is giving error of "A different object with the same identifier value was already associated with the session" Rest all (Read, Update and Delete) is working fine.
Im using oracle sql as database and there is one more entity of product with many to one mapping with categories class.
EntityClass
#Entity
public class Categories {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
public Categories() {
super();
}
public Categories(Integer id,String name) {
this.id=id;
this.name=name;
}
public Categories(String name) {
this.name=name;
}
//with setters and getters
}
JSP page
<body onload="document.getElementById('name').disabled = true;document.getElementById('hidden').disabled = true;">
<div align="center">
<h4>Add or Modify or Delete Categories</h4>
<form:form method="POST" action="/categories" modelAttribute="categories">
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td>
<form:select path="name">
<form:option value="NONE" label="Select" />
<form:options items="${categoriesList}" />
</form:select>
</td>
</tr>
<tr>
<td>Operations</td>
<td>
<input type="radio" name="Ops" value="Add" checked="checked" onclick="document.getElementById('name').disabled = true; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Add</input><br/>
<input type="radio" name="Ops" value="Modify" onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Modify</input><br/>
<input type="radio" name="Ops" value="Delete" onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = true;document.getElementById('hidden').disabled = false;">Delete</input><br/>
</td>
</tr>
<tr>
<td>Name</td>
<td><input type="text" name="newName" id="newName"/>
<input type="hidden" id="hidden" name="newName" value="dummy"/>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
</div>
</body>
Controller Class
#Controller
public class CategoriesController {
#Autowired
private CategoriesService cservice;
#RequestMapping(value = "/categories", method = RequestMethod.GET)
public ModelAndView categories() {
// view name model
ModelAndView modelAndView = new ModelAndView("categories", "categories", new Categories());
return modelAndView;
}
#RequestMapping(value = "/categories", method = RequestMethod.POST)
public String opsOnCategories(#ModelAttribute("categories") Categories cat,#RequestParam("Ops") String ops,#RequestParam("newName") String name)
{
if(ops.equals("Modify"))
{
cservice.modifyCategory(new Categories(Integer.parseInt(cat.getName()), name));
}else if(ops.equals("Add"))
{
cservice.addCategory(new Categories(name));
}else
{
cservice.deleteCategory(Integer.parseInt(cat.getName()));
}
return "categories";
}
#ModelAttribute("categoriesList")
public Map<String, String> getCategoryList() {
Map<String, String> categoriesList = new HashMap<String, String>();
List<Categories> ls=cservice.getAll();
for(int i=0;i<ls.size();i++)
{
categoriesList.put(ls.get(i).getId().toString(), ls.get(i).getName());
}
return categoriesList;
}
}
Can anyone please help on this.
Previous one due to which there was error
insert into CATEGORIES(ID,NAME) values (1,'Mobile');
insert into CATEGORIES(ID,NAME) values (2,'Laptop');
**Changes made to remove error*
insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Mobile');
insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Laptop');
My initial guess is that there something wrong with #Id #GeneratedValue with Oracle Database specifically.
There are couple of things that you can do:
1- Try to connect to any other Database type just to test the functionality - so that you can rule out what doesn't matter
2- Try to use the #org.springframework.data.annotation.Id alongside with the #Id of javax persistence
Something that look like this
#Id
#org.springframework.data.annotation.Id
private Integer id;
3- Create a class that Generates random Integer Ids and refer to it using the annotations (#GenericGenerator & #GeneratedValue)

hibernate validation not working while one-to-one mapping in between two entities

During form submission, if there is any validation error then form shows the errors messages under the fields. But the actual problem is in another place. I have two entities User and UserDetails. These entities are mapped with each other by bidirectional one-to-one mapping. Validation is working only with the User entity fields but not with the UserDetails entity.
Spring - 5.0.2`
Hibernate - 5.2.10
User.java
#Entity
#Table(name="users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#NotEmpty(message="{common.error.msg}")
private String first_name;
#NotEmpty(message="{common.error.msg}")
private String last_name;
#NotEmpty(message="{common.error.msg}")
private String status;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.LAZY)
private UserDetails userDetails;
//Getter and setter methods
}
UserDetails.java
#Entity
#Table(name="user_details")
public class UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int user_id;
#NotEmpty(message="{common.error.msg}")
private String address;
#NotEmpty(message="{common.error.msg}")
private String mobile;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id")
private User user;
//Getter and setter methods
}
Get and Post methods in the controller class
#GetMapping(value="/create")
public String loadUserForm(Model model) {
model.addAttribute("command", new User());
return "backend/oms/user/form"; //JSP
}
#PostMapping(value="/create")
public String Save(#Valid #ModelAttribute("command") User user, BindingResult br, Model model, HttpSession session, RedirectAttributes ra) {
if(br.hasErrors()) {
return "backend/oms/user/form"; //JSP
} else {
try {
int id = userService.save(user);
if(id > 0) {
ra.addFlashAttribute("flash_msg", "ok|User added!");
return "redirect:/oms/user/edit/"+id;
} else {
return "backend/oms/user/create"; //JSP
}
} catch (ConstraintViolationException ex) {
model.addAttribute("err", "Something wrong! Please try again.");
return "backend/oms/user/form"; //JSP
}
}
}
messages.properties
common.error.msg=This field is required!
form.jsp
<form:form action="/oms/user/create" method="post" modelAttribute="command">
<label>First Name</label>
<form:input path="first_name" class="form-control" placeholder="First Name" value="" />
<form:errors cssClass="error" path="first_name" />
<label>Last Name</label>
<form:input path="last_name" class="form-control" placeholder="Last Name" value="" />
<form:errors cssClass="error" path="last_name" />
<label>Mobile</label>
<form:input path="userDetails.mobile" class="form-control" placeholder="Mobile" value="" />
<form:errors cssClass="error" path="userDetails.mobile" />
<label>Address</label>
<form:textarea path="UserDetails.address" class="form-control" placeholder="Address" value="" />
<form:errors cssClass="error" path="userDetails.address" />
<label>Status</label>
<form:select class="form-control" path="status">
<option value="">Choose...</option>
<option value="E">Enable</option>
<option value="D">Disable</option>
</form:select>
<form:errors path="status" cssClass="error"/>
<input type="submit" class="btn btn-primary" value="Save" />
</form>
Please see the screenshot
As you can see the image only fields from the User entity is validating but fields those are from the UserDetails are not validating. Please help.
It is solved now. #Valid annotation solved my problem. I need to put #Valid annotation before the entity variable declaration like below --
#OneToMany(mappedBy="majorHead", cascade = CascadeType.ALL)
#Valid
private List<MinorHead> minorHead = new ArrayList<MinorHead>();

How to populate a form:select and select a default value?

I have an edit user form which has textfields(username, lastname..) and a select of countries. I'm having problems with this select because i don't know the better way to populate it. I've tried populating with jquery with success but i cannot select a default value through commandName.
<form:form method="POST" commandName="user" action="registerUser.html">
<form:errors path="*" cssClass="errorblock" element="div" />
<spring:message code="app.user.username"/><form:input path="username" /><form:errors path="username" cssClass="error" /><br/>
<spring:message code="app.user.firstname"/> <form:input type="text" path="firstName" /> <form:errors path="firstName" cssClass="error"/><br/>
<spring:message code="app.user.password"/> <form:input type="password" path="password" /><form:errors path="password" cssClass="error"/><br/>
<spring:message code="app.user.repassword"/> <form:input type="password" path="confirmPassword" /><form:errors path="confirmPassword" cssClass="error"/><br/>
<spring:message code="app.user.email"/> <form:input type="text" path="email" /><form:errors path="email" cssClass="error"/><br/>
<spring:message code="app.user.country"/> <form:select path="isoCode" items="${countryList}"/><form:errors path="isoCode" cssClass="error"/><br/>
<input type="submit" value="Enviar" />
</form:form>
I've take a look to this tutorial, so i've tried with a map but i don't know how to return the data to be accesible in the jsp because in the tutorial uses a SimpleFormController but i wouldn't like to code a SimpleFormController for each form. This is my controller to return the view of the form and i have another to catch the submit.
#RequestMapping(method=RequestMethod.GET, value="/editUserForm")
public String recordUserRequestHandler(ModelMap model) throws Exception {
model.addAttribute("user", new User());
Map<String, Map<String, String>> referenceData = new HashMap<String, Map<String, String>>();
Map<String, String> country = new LinkedHashMap<String, String>();
country.put("US", "United Stated");
country.put("CHINA", "China");
country.put("SG", "Singapore");
country.put("MY", "Malaysia");
referenceData.put("countryList", country);
return "EditUserForm";
}
is it possible to pass the referenceData to the jsp to be accessed by the form:select?
<spring:message code="app.user.country"/> <form:select path="isoCode" items="${countryList}"/><form:errors path="isoCode" cssClass="error"/><br/>
Also you don't need to use hashmap for selects. Personally I use simple List with beans which holds my select options.
public class ListOption {
private String id;
private String name;
public ListOption(String id, String name) {
this.id = id;
this.name = name;
}
public ListOption() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
in your controller
List<ListOption> selectOptions = new List<ListOption>();
// add Your options
selectOptions.add(new ListOption("id","value");
then put isoCode object into your model with desired (selected) value then spring will manage to mark the value as selected.
in your jsp
<form:select path="isoCode" items="${countryList}" itemValue="id" itemLabel="name"/>

spring form controller with html checkbox

I am trying to bind the input type checkbox using spring form controller,But i failed .
Here i am posting Controller,bean and jsp example,One more thing is i can't use
.
Below is the code:
Controller:
package com.test.web;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import com.vaannila.domain.User;
import com.vaannila.service.UserService;
#SuppressWarnings("deprecation")
public class UserController extends SimpleFormController {
private UserService userService;
public UserController() {
setCommandClass(User.class);
setCommandName("user");
}
public void setUserService(UserService userService) {
this.userService = userService;
}
#Override
protected ModelAndView onSubmit(Object command) throws Exception {
User user = (User) command;
user.setCommunity(user.getCommunity());
userService.add(user);
return new ModelAndView("userForm","user",user);
}
}
jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# 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>Registration Page</title>
<script>
function submitForm(){
document.testForm.submit();
}
</script>
</head>
<body>
<form:form method="POST" commandName="user" name="testForm" action="./userRegistration.htm">
<table>
<tr>
<td>User Name :</td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td>Password :</td>
<td><form:password path="password" /></td>
</tr>
<tr>
<td>Gender :</td>
<td><form:radiobutton path="gender" value="M" label="M" />
<form:radiobutton path="gender" value="F" label="F" /></td>
</tr>
<tr>
<td>Country :</td>
<td><form:select path="country">
<form:option value="0" label="Select" />
<form:option value="1" label="India" />
<form:option value="2" label="USA" />
<form:option value="3" label="UK" />
</form:select></td>
</tr>
<tr>
<td>About you :</td>
<td><form:textarea path="aboutYou" /></td>
</tr>
<tr>
<td>Community :</td>
<td><input type="checkbox" name="community" value="Hibernate"/>Hibernate</br>
<input type="checkbox" name="community" value="test"/>test</br>
<input type="checkbox" name="community" value="test1"/>test1</br>
</td>
</tr>
<tr>
<td></td>
<td><form:checkbox path="mailingList"
label="Would you like to join our mailinglist?" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" onclick="submitForm();"></td>
</tr>
</table>
</form:form>
</body>
</html>
Java beans:
package com.test.domain;
public class User {
private String name;
private String password;
private String gender;
private String country;
private String aboutYou;
private String[] community;
private Boolean mailingList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getAboutYou() {
return aboutYou;
}
public void setAboutYou(String aboutYou) {
this.aboutYou = aboutYou;
}
public String[] getCommunity() {
return community;
}
public void setCommunity(String[] community) {
this.community = community;
}
public Boolean getMailingList() {
return mailingList;
}
public void setMailingList(Boolean mailingList) {
this.mailingList = mailingList;
}
}
I tried different ways,but no luck.Any hints please.
the browser will not send the field in the request if the checkbox isn't checked. the value will either be "true" or not sent. you will never get a "false" value.
add a hidden field with _name for every checkbox
EX:
<input type="checkbox" name="community" value="Hibernate"/>
<input type="hidden" name="_community" value="on"/>
Then, spring will take care of it.
If you do not use the form tag it will not automaticly bind your checkboxes. If you use plain html you have to bind the your self.
You can solve this by adding a list of community objects and then use form:checkboxes.
For example:
<form:checkboxes path="communityList" items="${communityList}" itemValue="key" itemLabel="value" />
I would also recomend you to use a HashMap when using ModelAndView like this:
Map<String, Object> model = new HashMap<String, Object>();
model.put("user", user);
model.put("communityList", communityList);
return new ModelAndView("userFormat", model);
Manually bind using 'ServletRequestUtils'... http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/bind/ServletRequestUtils.html
Example
public ModelAndView test(HttpServletRequest request, HttpServletResponse response) throws ServletRequestBindingException {
Long subscriptionOwnerId = ServletRequestUtils.getLongParameter(request, "id");
return new ModelAndView('test'); }`

Resources