How do I enter a null value in the thymeleaf field of an html page? - spring

I'm making an input page using thymeleaf:
insertText.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="#{/insertText}" th:object="${text}" method="post">
<p th:text="'id: ' + ${text.id}" />
<p th:text="'parent_id' + ${text.parent_id} ?: 'original'" />
<p th:text="'id: ' + ${text.name}" />
<p th:text="'content: ' + ${text.operation}" />
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
And in the parent_it field I want to enter null if it is the original text but I get an error:
Field error in object 'textTable' on field 'parent_id': rejected value [null];
codes [typeMismatch.textTable.parent_id,typeMismatch.parent_id,typeMismatch.java.lang.Integer,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [textTable.parent_id,parent_id]; arguments []; default message [parent_id]];
default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'parent_id';
nested exception is java.lang.NumberFormatException: For input string: "null"]]
Although in the post page I added zero value processing:
result.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'id: ' + ${text.id}" />
<p th:text="'content: ' + ${text?.parent_id}" />
<p th:text="'id: ' + ${text.name}" />
<p th:text="'content: ' + ${text.operation}" />
Submit another message
</body>
</html>
Maybe there is a way to make this possible?
My entity
textTablt
package com.example.HiberTest.Entities;
#Entity
#Table(name = "textTable")
public class textTable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "parent_id")
private Integer parent_id;
#NotBlank
#Size(min=1, max=128)
#Column(name = "name")
private String name;
#NotBlank
#Size(min=1, max=128)
#Column(name = "operation")
private String operation;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParent_id() {
return parent_id;
}
public void setParent_id(Integer parent_id) {
this.parent_id = parent_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
#Override
public String toString(){
return String.format("id = %o" +
", parent_id = %o, " +
"name = %s, operation = %s ",
id,parent_id,name,operation);
}
}
My conroller:
package com.example.HiberTest.Controller;
import java.util.List;
#Controller
public class TextController {
#Autowired
daoRepository dao;
#GetMapping("/insertText")
public String insertText(Model model){
//List<textTable> list =dao.findAll();
//model.addAttribute("texts",list);
model.addAttribute("text", new textTable());
return "insertText";
}
#PostMapping("/insertText")
public String getAllText(#ModelAttribute textTable texts, Model model){
//List<textTable> list =dao.findAll();
model.addAttribute("text", texts);
return "result";
}
}
I would be glad of help to figure out how to enter a null value so that it is processed correctly

Your variable parent_id in class textTable is of type Integer but you are trying to insert string in it. you are trying to append integer id in string 'parent_id' and then store in Database that's why you are getting error.

Related

Problem with controller return statement not performed (about redirect)

I'm working on a side project and it's been delayed for several days. When I run my code, I always can't run it from the "return redirect:/" part of the controller.
The result I expected is that I think of moving from sentence "return redirect:/" to another page, but everything seems fine inside, but only sentence "return redirect:/" is not performed.
I am using Mysql, SpringBoot, JPA, Spring Data Jpa, Lombok. What is the problem?
This is View to receive email and password.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel = "stylesheet" href ="/css/sample.css">
<link href="https://getbootstrap.com/docs/5.2/assets/css/docs.css" rel="stylesheet">
<link href="/css/font.css" rel = "stylesheet">
<link href="/css/navbar.css" rel = "stylesheet">
<title>loginpage</title>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript">
function functionclick() {
let email = document.getElementById('exampleDropdownFormEmail1').value;
let password = document.getElementById('exampleDropdownFormPassword1').value;
if (email == "" || password == "") {
alert("회원 정보를 입력하세요");
history.back();
} else{
const url = new URL("/trylogin",location);
url.searchParams.append('email',email);
url.searchParams.append('password',password);
location = url;
}
}
</script>
</head>
<body class="p-3 m-0 border-0 bd-example">
<!-- Example Code -->
<div class="dropdown-menu">
<form class="px-4 py-3" method="get" action="login">
<div class="mb-3">
<label for="exampleDropdownFormEmail1" class="form-label">이메일을 입력하세요</label>
<input type="text" class="form-control" id="exampleDropdownFormEmail1" placeholder="email#example.com" name = "email">
</div>
<div class="mb-3">
<label for="exampleDropdownFormPassword1" class="form-label">비밀번호를 입력하세요.</label>
<input type="password" class="form-control" id="exampleDropdownFormPassword1" placeholder="Password" name = "password">
</div>
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="dropdownCheck">
<label class="form-check-label" for="dropdownCheck">
비밀번호 기억하기
</label>
</div>
</div>
<button type="submit" class="btn btn-primary" ONCLICK="functionclick()">확인</button>
</form>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="http://localhost:8080/signup">회원가입 하기</a>
<a class="dropdown-item" href="http://localhost:8080/forgotpassword">비밀번호 찾기</a>
</div>
<!-- End Example Code -->
</body>
</html>
This is LoginController
#Controller
public class LoginController {
#Autowired
private
UserService userService;
#GetMapping("/trylogin")
public String login(LoginDto loginDto) {
try {
if(userService.login(loginDto).isPresent()) {
return "redirect:/loginSuccess";
}
} catch (Exception e) {
e.printStackTrace();
return "redirect:/loginFailed";
}
return "redirect:/loginFailed";
}
#GetMapping("/loginSuccess")
public String loginSuccess() {
return "login_success";
}
#GetMapping("/loginFailed")
public String loginFailed() {
return "login_failed";
}
}
It is a service layer and the Repository used spring data jpa.
#Service
#RequiredArgsConstructor
#Getter
public class UserService {
#Autowired
private UsersRepository usersRepository;
#Transactional
public Optional<Users> login(LoginDto loginDto) throws Exception{
return usersRepository.findByEmailAndPassword(loginDto.getEmail(), loginDto.getPassword());
}
}
This is the Users entity to perform the query.
#Entity
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Table(uniqueConstraints = {#UniqueConstraint(columnNames = {"ssn","phone_number"})})
public class Users {
#Column(name = "email", length = 40, updatable = false, nullable = false)
#Id
private String email;
#Column(name = "password", length = 20, nullable = false)
private String password;
#Column(name = "name", length = 25, nullable = false)
private String name;
#Column(name = "phone_number", length = 12, nullable = false)
private String phoneNumber;
#Column(name = "ssn", length = 13, nullable = false, updatable = false)
private String ssn;
#Embedded
private Address address;
#Column(name = "point")
private Long point;
#OneToMany(mappedBy = "postedUser")
private List<PostInfo> uploadedPost = new ArrayList<>();
#OneToMany(mappedBy = "userId")
private List<PointHistory> pointHistories = new ArrayList<>();
#Embedded
private Dates dates;
public Users(UserInfoDto userInfoDto){
this.setEmail(userInfoDto.getEmail());
this.setPassword(userInfoDto.getPassword());
this.setPhoneNumber(userInfoDto.getPhone_number());
this.setSsn(userInfoDto.getSsn());
this.setPoint(0L);
this.setName(userInfoDto.getName());
Address address = new Address(
userInfoDto.getCity_name(),
userInfoDto.getTown_name(),
userInfoDto.getStreet_name(),
userInfoDto.getZip_code(),
userInfoDto.getDetails()
);
this.setAddress(address);
List<PostInfo> postInfoList = new ArrayList<>();
List<PointHistory> pointHistoryList = new ArrayList<>();
this.setUploadedPost(postInfoList);
this.setPointHistories(pointHistoryList);
Dates dates = new Dates(LocalDateTime.now(), LocalDateTime.now());
this.setDates(dates);
}
public void setEmail(String id) {
this.email = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setName(String name) {
this.name = name;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public void setAddress(Address address) {
this.address = address;
}
public void setPoint(Long point) {
this.point = point;
}
public void setUploadedPost(List<PostInfo> uploadedPost) {
this.uploadedPost = uploadedPost;
}
public void setPointHistories(List<PointHistory> pointHistories) {
this.pointHistories = pointHistories;
}
public void setDates(Dates dates) {
this.dates = dates;
}
}
This is LoginDto (To transfer to the controller)
#Getter
#Setter
#AllArgsConstructor
public class LoginDto {
private String email;
private String password;
}
The page for redirection.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Success</title>
<script type = "text/javascript">
alert("로그인 성공");
location.href = "/";
</script>
</head>
<body>
</body>
</html>

Spring MVC Form not taking object path

Error shown is Bean property 'emergencyComplaint.emergencyComplaint' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
The getters and setters have the same return type, still it is showing this error.
JSP Page
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CRS | Kolkata</title>
</head>
<body>
<div>
<h1>Lodge an Emergency Complaint Now</h1>
<form:form action="" method="post" modelAttribute="people">
<form:label
path="emergencyComplaint.emergencyComplaint"
for="emergencyComplaint"
>
Emergency Complaint
</form:label>
<form:input
type="text"
name="emergencyComplaint"
id="emergencyComplaint"
path="emergencyComplaint.emergencyComplaint"
/>
<form:label
path="emergencyComplaint.status"
for="emergencyComplaintStatus"
>Status</form:label
>
<form:input
type="text"
name="emergencyComplaintStatus"
id="emergencyComplaintStatus"
path="emergencyComplaint.status"
></form:input>
<form:label path="name" for="name">Name</form:label>
<form:input path="name" type="text" name="name" id="name" />
<form:label path="phoneNumber" for="phoneNumber"
>Phone Number</form:label
>
<form:input
path="phoneNumber"
type="text"
name="phoneNumber"
id="phoneNumber"
/>
<button type="submit">Lodge</button>
</form:form>
</div>
</body>
</html>
Model Class
package com.naha.crimereportingsystem.people;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import com.naha.crimereportingsystem.emergencyComplaint.EmergencyComplaint;
#Entity
public class People {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private String phoneNumber;
#OneToMany(targetEntity = EmergencyComplaint.class, cascade = CascadeType.ALL)
private List<EmergencyComplaint> emergencyComplaint;
public People() {
}
public People(long id, String name, String phoneNumber) {
this.id = id;
this.name = name;
this.phoneNumber = phoneNumber;
this.emergencyComplaint = (List<EmergencyComplaint>) new EmergencyComplaint();
}
public List<EmergencyComplaint> getEmergencyComplaint() {
return emergencyComplaint;
}
public void setEmergencyComplaint(List<EmergencyComplaint> emergencyComplaint) {
this.emergencyComplaint = emergencyComplaint;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(final String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setName(final String name) {
this.name = name;
}
}
Mapped Other Model Class
package com.naha.crimereportingsystem.emergencyComplaint;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class EmergencyComplaint {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
long id;
private String emergencyComplaint;
private String status;
public String getEmergencyComplaint() {
return emergencyComplaint;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public void setEmergencyComplaint(String emergencyComplaint) {
this.emergencyComplaint = emergencyComplaint;
}
public EmergencyComplaint(long id, String emergencyComplaint, String status) {
this.id = id;
this.emergencyComplaint = emergencyComplaint;
this.status = status;
}
public EmergencyComplaint(String emergencyComplaint, String status) {
this.emergencyComplaint = emergencyComplaint;
this.status = status;
}
public EmergencyComplaint() {
}
}
This is a valid error. Take a close look at your Entity and your modelAttribute. There is no such thing emergencyComplaint.emergencyComplaint.
So, instead of:
<form:input type="text" name="emergencyComplaint" id="emergencyComplaint" path="emergencyComplaint.emergencyComplaint" />
Try this:
<form:input type="text" name="emergencyComplaint" id="emergencyComplaint" path="emergencyComplaint" />
I do not have OneToMany example handy but I think you are smart enough to identify the issue by now while reading this. If not then to get an idea, take a look at this and this.

Not mapping all fields from html to controller

I need to update my category object
my model:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
#Entity
public class Category {
#Id
#GeneratedValue
private int id;
#NotNull
private String name;
private String description;
#NotNull
private Long created;
private Long updated;
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 Long getCreated() {
return created;
}
public void setCreated(Long created) {
this.created = created;
}
public Long getUpdated() {
return updated;
}
public void setUpdated(Long updated) {
this.updated = updated;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
Here my controller:
#Controller
public class CategoryController {
private CategoryRepository categoryRepository;
private static Logger logger = LogManager.getLogger(CategoryController.class);
// If class has only one constructore then #Autowired wiil execute automatically
public CategoryController(CategoryRepository categoryRepository) {
this.categoryRepository = categoryRepository;
createStubCategoryList();
}
#PostMapping(value = "/category")
public String submitCategory(Category category, Model model) {
logger.info("updateCategory = " + category);
model.addAttribute("submitted", true);
model.addAttribute("category", category);
categoryRepository.save(category);
return "category";
}
#RequestMapping("category/edit/{id}")
public String editCategory(#PathVariable("id") int id, Model model) {
Optional<Category> category = categoryRepository.findById(id);
logger.info("find_category = " + category);
model.addAttribute("category", category);
return "category";
}
Here my template to edit category:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${appName}">Category template title</title>
<link th:href="#{/public/style.css}" rel="stylesheet"/>
<meta charset="UTF-8"/>
</head>
<body>
<div class="container">
<form method="post" action="#" th:object="${category}" th:action="#{/category}">
<h3>Category</h3>
<input type="text" placeholder="name" id="name" th:field="*{name}"/>
<textarea placeholder="Description of the category" rows="5" id="description"
th:field="*{description}"></textarea>
<input type="submit" value="Submit"/>
</form>
<div class="result_message" th:if="${submitted}">
<h3>Your category has been submitted.</h3>
<p>Find all categories here</p>
</div>
</div>
</body>
</html>
When call method in log has:
[INFO ] 2020-01-07 19:38:07.493 [http-nio-8090-exec-8] CategoryController - find_category = Optional[
Category{id=2, name='Electronics', created=1578418669105, updated=null, description='Electronics's description'}]
and here screen:
As you can see the field created=1578418669105
Nice.
Now I edit name "Electronics" to "Electronics2" and click submit.
As result call method: submitCategory in my controller. Nice.
Here result in log:
[INFO ] 2020-01-07 19:40:23.327 [http-nio-8090-exec-2] CategoryController - updateCategory =
Category{id=0, name='Electronics2', created=null, updated=null, description='Electronics's description'}
but as you can see the field created is null. Why?
I need to update only editable fields: name and description.
Another fields (like created, updated, id) must not change. This fields are not mapped.
How I can do this?
Because created, updated, id you need to pass as hidden. It is not available in html page.
Each column should be changed to updatable to false because by default is true.
#Column(name = "created", updatable = false)
private Long created;

Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor'

Trying to change value inside my model class which contains a private String name and I wanted to change the name using Thymeleaf in HTML page then see the change in another url response body.
When I try to access my ("/myname") page in localhost I got the error:
Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor'
Here is my Model:
public class Name {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here is my Controller
#Controller
public class MainController {
#RequestMapping("/name")
#ResponseBody
public String showName() {
Name myname = new Name();
return myname.getName();
}
#RequestMapping("/myname")
public String setName() {
return "myname";
}
#RequestMapping(value = "myname", method = RequestMethod.POST)
public String showName(#ModelAttribute Name iko, BindingResult errors, Model model) {
return "name";
}
}
Here is my html thymeleaf pages:
myname.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1"/>
<title>Insert title here</title>
</head>
<body>
<form action="#" th:action="#{/myname}" th:object="${iko}" method="post">
<label>Enter the name</label><br/>
<input type="text" th:field="*{name}"/>
<button type="submit">SUBMIT</button>
</form>
</body>
</html>

Spring Framework <form:errors/> tag not showing errors

I know there are many similar questions here, but none of them solved my problem.
I'm using Spring 4.0.3 and Hibernate Validator 5.1.0.
The problem occurs when I try to omit the path attribute of the <form:errors/> tag, so:
<form:errors path="contato.nome" /> works
<form:errors path="*" /> works
<form:errors /> doesn't work
I don't know why it happens. Spring javadocs (org.springframework.web.servlet.tags.form.ErrorsTag) says it should work like that:
Field only - set path to the field name (or path)
Object errors only - omit path
All errors - set path to *
Can you help me, please?
The interested code is in the 'edicao.jsp' and in the method 'confirmarEdicao' of the ContatoController.java. Sorry if my english is bad.
ContatoController.java
#Controller
#RequestMapping("/contatos")
public class ContatoController {
#Autowired
private ContatoService contatoService;
#Autowired
private MessageSource messageSource;
#RequestMapping(value = "/confirmarEdicao", method = RequestMethod.POST)
public String confirmarEdicao(#Valid Contato contato, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
return "contatos/edicao";
}
contatoService.save(contato);
return "redirect:/contatos";
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView form(HttpServletRequest request) {
String message = messageSource.getMessage("teste", null, new Locale("pt", "BR"));
System.out.println(message);
return new ModelAndView("contatos/listagem")
.addObject("contatos", contatoService.list());
}
#RequestMapping("/remover/{id}")
public String remover(Contato contato) {
contatoService.delete(contato);
return "redirect:/contatos";
}
#RequestMapping("/editar/{id}")
public ModelAndView formEdicao(Contato contato) {
contato = contatoService.find(contato.getId());
return new ModelAndView("contatos/edicao")
.addObject(contato);
}
#RequestMapping(value = "/cadastrar")
public String formCadastro() {
return "contatos/cadastro";
}
#RequestMapping(value = "/confirmarCadastro", method = RequestMethod.POST)
public String confirmarCadastro(#Valid Contato contato, BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
if (bindingResult.hasFieldErrors()) {
return "contatos/cadastro";
}
contatoService.save(contato);
redirectAttributes.addFlashAttribute("mensagem", "Contato cadastrado com sucesso.");
return "redirect:/contatos";
}
#ResponseBody
#RequestMapping(value = "/pesquisar/{nome}", method = RequestMethod.GET,
produces="application/json")
public List<Contato> pesquisar(#PathVariable String nome) {
return contatoService.findByName(nome);
}
}
edicao.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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=UTF-8">
<title>Editar contato</title>
</head>
<body>
<c:set var="context">${pageContext.request.contextPath}</c:set>
<script type="text/javascript">var context = "${context}";</script>
<script src="${context}/resources/js/jquery-2.1.0.min.js"></script>
<script src="${context}/resources/js/contatos/edicao.js"></script>
<form:form commandName="contato" action="${context}/contatos/confirmarEdicao" method="post">
<form:errors/>
<table>
<form:hidden path="id"/>
<tr>
<td>Nome:</td>
<td><form:input path="nome" /></td>
</tr>
<tr>
<td>Telefone:</td>
<td><form:input path="telefone"/></td>
</tr>
<tr>
<td><input type="button" value="Voltar" id="btn_voltar"/><input type="submit" value="Salvar"/></td>
</tr>
</table>
</form:form>
</body>
</html>
Contato.java
package com.handson.model;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class Contato {
private Long id;
#Size(min = 3, message = "Nome deve ter no mínimo 3 caracteres")
#NotEmpty(message = "O nome deve ser preenchido")
private String nome;
private String telefone;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
public Contato withId(Long id) {
setId(id);
return this;
}
public Contato withTelefone(String telefone) {
setTelefone(telefone);
return this;
}
public Contato withNome(String nome) {
setNome(nome);
return this;
}
#Override
public String toString() {
return "Contato [id=" + id + ", nome=" + nome + ", telefone="
+ telefone + "]";
}
}
There are some keywords which should be defined:
path - EL-like path to an object or to a field of an object (e.g. foo, foo.bar or foo.bar.baz)
nested path - current path context stored as nestedPath request attribute (new paths are relative to this path)
object error - error connected with object itself (e.g. path is equal to foo)
field error - error connected with object field (e.g. path is foo.bar)
The tag <form:form commandName="foo"> defines nested path as nestedPath=foo. When you write <form:errors path="bar"> it tries to find errors defined for path foo.bar.
Lets say that you have errors connected with foo (object error), foo.bar and foo.bar.baz (nested field error). What this means:
if you enter <form:errors>, only errors bound to foo path are displayed => 1 message
if you enter <form:errors path="bar">, only errors bound to foo.bar path are displayed => 1 message
if you enter <form:errors path="*">, errors bound to foo and its child paths are displayed => 3 messages
if you enter <form:errors path="bar.*">, only child errors for foo.bar are diplayed => 1 message
if you enter <form:errors path="bar*">, errors bound to foo.bar and its child paths are diplayed => 2 messages
Checking on Errors class JavaDoc might give you additional insight.

Resources