Naming variables/fields?? Not accepting names - Thymeleaf and Spring Boot MVC - java

I am new to Spring Boot and I am am working on creating connecting the front of an application to the back at the moment.
I used this site https://spring.io/guides/gs/validating-form-input/
to work on a simple example and it worked fine. It uses the names 'name' and 'age' for the two fields, and getAge, and getName etc for getters and setters.
This code works:
HTML form:
<html>
<body>
<form action="#" th:action="#{/}" th:object="${personForm}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{name}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" th:field="*{age}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
Person java class
public class PersonForm {
#NotNull
#Size(min=2, max=30)
private String name;
#NotNull
#Min(18)
private Integer age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "Person(Name: " + this.name + ", Age: " + this.age + ")";
}
}
Controller
#Controller
public class WebController extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/results").setViewName("results");
}
#GetMapping("/")
public String showForm(PersonForm personForm) {
return "form";
}
#PostMapping("/")
public String checkPersonInfo(#Valid PersonForm personForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}
return "redirect:/results";
}
}
I have simply changed the names of the variables to the below: (2 strings instead of an int and a string). The following error is displayed when I try to view the page: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (form:33)
Line 33 has " th:field="*{testcolumn}" " on it.
Is there certain naming conventions you must follow with thymeleaf perhaps? I cannot find information about it. Thanks
Person class:
#NotNull
#Size(min=2, max=30)
private String testcolumn;
#NotNull
private String testcolumntwo;
public String getTestcolumn() {
return this.testcolumn;
}
public void setTestcolumn(String testcolumn) {
this.testcolumn = testcolumn;
}
public String getTestcolumntwo() {
return testcolumntwo;
}
public void setTestcolumntwo(String testcolumntwo) {
this.testcolumntwo = testcolumntwo;
}
public String toString() {
return "Person(Name: " + this.testcolumntwo + ", Age: " + this.testcolumntwo + ")";
}
HTML Form:
<form action="#" th:action="#{/}" th:object="${personForm}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{testcolumn}" /></td>
<td th:if="${#fields.hasErrors('testcolumn')}" th:errors="*{testcolumn}">Name Error</td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" th:field="*{testcolumntwo}" /></td>
<td th:if="${#fields.hasErrors('testcolumntwo')}" th:errors="*{testcolumntwo}">Age Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>

Related

Cannot print in HTML ArrayList using Spring MVC

I am facing problem trying print at the same time a form and array in the same HTML.
Here is my usuario class:
public class usuario {
private String user_id;
private String createdAt;
private String address;
private String latitude;
private String longitude;
private String birthday;
private String email;
private String user_idp;
private ArrayList pedido;
private String phoneNunmber;
private Integer edad;
public String nombre;
private String confirmationCode;
private String promotions;
public String ciudad;
public String getCiudad() {
return ciudad;
}
public void setCiudad(String ciudad) {
this.ciudad = ciudad;
}
public String getPromotions() {
return promotions;
}
public void setPromotions(String promotions) {
this.promotions = promotions;
}
public String getConfirmationCode() {
return confirmationCode;
}
public void setConfirmationCode(String confirmationCode) {
this.confirmationCode = confirmationCode;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Integer getEdad() {
return edad;
}
public void setEdad(Integer edad) {
this.edad = edad;
}
public String getPhoneNunmber() {
return phoneNunmber;
}
public void setPhoneNunmber(String phoneNunmber) {
this.phoneNunmber = phoneNunmber;
}
public String getUser_idp() {
return user_idp;
}
public void setUser_idp(String user_idp) {
this.user_idp = user_idp;
}
public ArrayList getPedido() {
return pedido;
}
public void setPedido(ArrayList pedido) {
this.pedido = pedido;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
Here is my Controller code:
#Controller
public class GreetingController {
#GetMapping("/allusers")
public String greetingForm(Model model) throws ParseException{
tablausuario tu = new tablausuario();
ArrayList<usuario> user = tu.listausuarios();
Collections.sort(user, (o1, o2) -> o2.getCreatedAt().compareTo(o1.getCreatedAt())); //tabla ordenada
model.addAttribute("TodosLosUsuarios", user);
return "greeting";
}
#PostMapping("/allusers")
public String greetingSubmit(Model model, HttpServletRequest request, #ModelAttribute usuario users) {
String ciudad = request.getParameter("ciudad");
tablausuariofilterbycity tufc = new tablausuariofilterbycity();
ArrayList<usuario> userbycity = tufc.listausuariosfiltradosporciudad(ciudad);
model.addAttribute("TodosLosUsuarios", userbycity);
return "result";
}
}
And here is my HTML "greeting"
<div class="container">
<h2>Listado de usuarios </h2>
<p th:text=" ${TodosLosUsuarios.size()} "></p>
<div id="capa"> </div>
<h1>Form</h1>
<form action="#" th:action="#{/allusers}" th:object="${TodosLosUsuarios}" method="post">
<p>Message: <input type="text" th:field="*{ciudad}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Buscar por ciudad..">
<table id="myTable" class="table table-bordered">
<thead>
<tr>
<th>Nombre</th>
<th>Email</th>
<th>Teléfono</th>
<th>Día creado</th>
<th>Edad</th>
<th>Confirmado</th>
<th>Promocion</th>
<th>Direccion</th>
</tr>
</thead>
<tbody th:each="usuariosTotales: ${TodosLosUsuarios}" >
<tr>
<td th:text=" ${usuariosTotales.getNombre()} " ></td>
<td th:text=" ${usuariosTotales.getEmail()} " ></td>
<td th:text=" ${usuariosTotales.getPhoneNunmber()} " ></td>
<td th:text=" ${usuariosTotales.getCreatedAt()} " ></td>
<td th:text=" ${usuariosTotales.getEdad()} " ></td>
<td th:text=" ${usuariosTotales.getConfirmationCode()} " ></td>
<td th:text=" ${usuariosTotales.getPromotions()} " ></td>
<td th:text=" ${usuariosTotales.getAddress()} " ></td>
</tr>
</tbody>
</table>
</div>
</div>
I am sure that the problem is in the form:
<form action="#" th:action="#{/allusers}" th:object="${TodosLosUsuarios}" method="post">
<p>Message: <input type="text" th:field="*{ciudad}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
If instead of "user" I use "new usuario"
model.addAttribute("TodosLosUsuarios", user);
I use
model.addAttribute("TodosLosUsuarios", new usuario());
the form works but I am not able to read the ArrayList, and I get this error:
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "greeting" - line 10, col 40)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
... 48 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "greeting" - line 10, col 40)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleStandaloneElementEnd(TemplateHandlerAdapterMarkupHandler.java:260)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:256)
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleStandaloneElementEnd(OutputExpressionInlinePreProcessorHandler.java:169)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:104)
at org.attoparser.HtmlElement.handleStandaloneElementEnd(HtmlElement.java:79)
at org.attoparser.HtmlMarkupHandler.handleStandaloneElementEnd(HtmlMarkupHandler.java:241)
at org.attoparser.MarkupEventProcessorHandler.handleStandaloneElementEnd(MarkupEventProcessorHandler.java:327)
at org.attoparser.ParsingElementMarkupUtil.parseStandaloneElement(ParsingElementMarkupUtil.java:96)
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:706)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
... 50 more
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'ciudad' of bean class [java.util.ArrayList]: Bean property 'ciudad' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:622)
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:612)
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:158)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227)
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
... 63 more
I think the problem is your are using plain HTML (ie tag form) instead of the Spring JSP Form
<form:form method="POST" action="/todoslosusuarios"
modelAttribute="TodosLosUsuarios">
I think you are missing the proper tags for action in Thymeleaf and also the "post" method declaration.
<form action="#" th:action="#{/todoslosusuarios}" method="post">
this link covers the process end to end.
https://spring.io/guides/gs/handling-form-submission/

org.springframework.beans.NotReadablePropertyException: Invalid property 'user' of bean class [com.jit.model.Signup]:

i tried to save data in to table by spring but this error show when data submitted..
org.springframework.beans.NotReadablePropertyException: Invalid property 'user' of bean class [com.jit.model.Signup]: Bean property 'user' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
controller class
#Controller
public class DatabaseController
{
#RequestMapping("/signup.htm")
public String loginCheck(#ModelAttribute("bean") #Valid Signup bean,BindingResult result,HttpServletRequest request , HttpServletResponse response) throws IOException {
Session session= HiberSession.getHiber();
if (result.hasErrors()){
return "signup";
} else{
session.save(bean);
return "abc";
}
Bean class
#Entity
#Table(name="user")
public class Signup {
#Id
#GeneratedValue
#Column(name="uid")
private Integer uid;
#NotEmpty
#Column(name="name")
private String name;
#NotEmpty
#Column(name="father_name")
private String father;
#NotEmpty
#Size(min =4,max =10)
#Column(name="password")
private String pass;
#NotEmpty
#Length(min =10,max =10)
#Column(name="contact")
private String contact;
#NotEmpty
#Column(name="city")
private String city;
#NotNull
#Column(name="introducer")
private Integer introducer;
#Column(name="status")
private Integer status;
#Column(name="amount")
private Integer amount=400;
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFather() {
return father;
}
public void setFather(String father) {
this.father = father;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getIntroducer() {
return introducer;
}
public void setIntroducer(Integer introducer) {
this.introducer = introducer;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
signup.jsp
<%#page language="java" contentType="text/html"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
color: #ff0000;
}
</style>
</head>
<body>
<c:if test="${not empty message}"><h2>${message}</h2></c:if>
<h3>New user registration form..</h3>
<form:form method="POST" commandName='bean' action="/jit/signup.htm">
<table>
<tr>
<td>Name :</td>
<td><form:input path="name"/></td>
<td><form:errors path="name" cssClass="error"/></td>
</tr>
<tr>
<td>Father Name :</td>
<td><form:input path="father"/></td>
<td><form:errors path="father" cssClass="error"/></td>
</tr>
<tr>
<td>Password :</td>
<td><form:password path="pass" /></td>
<td><form:errors path="pass" cssClass="error" /></td>
</tr>
<tr>
<td>Contact Number :</td>
<td><form:input path="contact"/></td>
<td><form:errors path="contact" cssClass="error"/></td>
</tr>
<tr>
<td>City/Village :</td>
<td><form:input path="city"/></td>
<td><form:errors path="city" cssClass="error"/></td>
</tr>
<tr>
<tr>
<td>Introducer ID:</td>
<td><form:input path="introducer"/></td>
<td><form:errors path="introducer" cssClass="error"/></td>
</tr>
<tr>
<td colspan="3"><input type="submit" /></td>
</tr>
</table>
</form:form>
</body>
</html>
I'd say that you should avoid having table names that are reserved words, with hibernate. Sure you can escape it, but it may cause problems in the future (in a query for example). So the safest way is to name the table another way - say users
#Entity
#Table(name="users")
public class Signup {
}

Unable to get thymeleaf form data in spring mvc

I am new to Thymeleaf, I try to execute a simple form submittion example using Thymeleaf and Spring MVC. I wrote the code according to Thymeleaf documentation. But I am getting null values in the controller.
<form action="thymeleafexample/thymeleaf.html" th:action="#{/thymeleaf}"
th:object="${loginModel}" method="post">
<table>
<tr>
<td th:text="#{emp.empId.label}">Emp ID</td>
<td><input type="text" th:field="*{empId}"/></td>
</tr>
<tr>
<td th:text="#{emp.empName.label}">Emp Name</td>
<td><input type="text" th:field="*{empName}"/></td>
</tr>
<tr>
<td>
<button type="submit" name="save" th:text="#{${'.emp.button.label'}}">submit</button>
</td>
</tr>
</table>
</form>
and my Controller is
#RequestMapping(value = "/thymeleaf", params = {"save"})
public String save(#Validated LoginModel loginModel, final BindingResult bindingResult, ModelMap model) {
if (bindingResult.hasErrors()) {
return "thymeleaf";
}
System.out.println(loginModel);
System.out.println(loginModel.getEmpName());
return "/thymeleaf";
}
and my Model class is
public class LoginModel {
private String empName;
private int empId;
public void setEmpId(int empId) {
this.empId = empId;
}
public int getEmpId() {
return empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
}
I was having the same problem and as OP mentioned, creating a constructor for the POJO(Model) class with necessary member fields and using th:field=*{foo} instead of th:value=${foo} solved my issue.

Spring MVC - populate enum to dropdownlist

I have a form like this :
<form:form method="POST" action="searchProjects" commandName="projectcriteria">
<table>
<tr>
<td class="label"><spring:message code="number" /></td>
<td><form:input path="number" /></td>
<td class="label"><spring:message code="customer" /></td>
<td><form:input path="customer" /></td>
</tr>
<tr>
<td class="label"><spring:message code="name" /></td>
<td><form:input path="name" /></td>
<td class="label"><spring:message code="status" /></td>
<td>
<form:select path="status">
<option value=""><spring:message code="please_select" /></option>
<c:forEach var="enum" items="${allStatus}">
<option value="${enum}"><spring:message code="${enum.statusEnum}" /></option>
</c:forEach>
</form:select>
</td>
</tr>
<tr>
<td colspan="4" style="text-align: center;">
<input type="submit" value="<spring:message code="search"/>" />
<input type="button" value="<spring:message code="reset_criteria"/>" />
</td>
</tr>
</table>
</form:form>
The Projectcriteria and the StatusEnum are like this:
public enum StatusEnum {
INV("Invalidate"),
TOV("Validate"),
VAL("Validated"),
FIN("Finished");
private String name;
private StatusEnum(String name) {
this.name = name;
}
public String getStatusEnum() {
return this.name;
}
}
public class ProjectCriteria {
private long number;
private String name;
private String customer;
private StatusEnum status;
/**
* #return the number
*/
public long getNumber() {
return number;
}
/**
* #param number the number to set
*/
public void setNumber(long number) {
this.number = number;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the customer
*/
public String getCustomer() {
return customer;
}
/**
* #param customer the customer to set
*/
public void setCustomer(String customer) {
this.customer = customer;
}
/**
* #return the status
*/
public StatusEnum getStatus() {
return status;
}
/**
* #param status the status to set
*/
public void setStatus(StatusEnum status) {
this.status = status;
}
}
How do I populate the StatusEnum attribute in the ProjectCriteria class to the jsp page. What do i have to put into the Controller?
Thanks a lot for any help.
Add your enum values in Controller method which giving request to respective page i.e.
model.addAttribute("enumValues",StatusEnum.value());
Then iterate enumValues in dropdown menu using foreach.
You could try this (sorry code not tested):
<c:forEach var="enum" items="${StatusEnum.values()}">
<option value="${enum}"><spring:message code="${enum.name}" /></option>
</c:forEach>
Note: if your enum class has a package name, you might have to include the fully qualified class name in the items attribute. You might be able to pass the enum as a model attribute from your controller as well (?).

Spring 3 MVC, Not able to access model object in JSP (Closed)

i have one model object Person
public class Person {
public String firstName;
public String lastName;
public String country;
public String sex;
private Integer age;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String toString(){
return firstName + " " + sex;
}
}
and in controller i populated reference data countryList in below method
#ModelAttribute
public void populateCountryList(Model model){
System.out.println("inside populateCountryList");
Map<String,String> country = new LinkedHashMap<String,String>();
country.put("Select", "-----Select------");
country.put("US", "United Stated");
country.put("CHINA", "China");
country.put("SG", "Singapore");
country.put("MY", "Malaysia");
country.put("MY1", "India");
country.put("MY2", "UK");
country.put("MY3", "SA");
country.put("MY4", "Newzeland");
model.addAttribute("countryList", country);
}
Also populated Person object in another method
#ModelAttribute
public Person populateModel(){
System.out.println("inside populateCountry");
Person person = new Person();
person.setCountry("India");
person.setSex("M");
return person;
}
Now in jsp my components are text boxes for firstName, age, dropdown for country and radio button for sex. I want the radio button for Sex (M) and in dropdown the country "India" be selected by default. My jsp is below.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
...
<h1>Person page</h1>
<p>This is Person page</p>
<form:form method="POST" commandName="person" action="process-person.html">
<table>
<tbody><tr>
<td><form:label path="firstName">Name:</form:label></td>
<td><form:input path="firstName"></form:input></td>
</tr>
<tr>
<td><form:label path="age">Age:</form:label></td>
<td><form:input path="age"></form:input></td>
</tr>
<tr>
<td><form:label path="country">Country:</form:label></td>
<td>
<form:select path="country">
<form:options items="${countryList}" />
</form:select>
</td>
</tr>
<tr>
<td>Sex :</td>
<td><form:radiobutton path="sex" value="M" />Male
<form:radiobutton path="sex" value="F" />Female
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit">
</td>
<td></td>
<td></td>
</tr>
</tbody></table>
</form:form>
When i am running the application default values are not getting selected. I also tried to print Person object in jsp, it is printing the Person object value of its properties are getting null.
Please suggest me what is wrong in this implementation.
Solution
In the handler method i have written the below code.
**#RequestMapping(value="/person-form")
public ModelAndView personPage() {
return new ModelAndView("person-page", "person", new Person());
}**
so i've changed the code to
**#RequestMapping(value="/person-form")
public ModelAndView personPage() {
return new ModelAndView("person-page");
}**
It is because you need to set KEY instead the Value in your person object:
person.setCountry("MY1");

Categories

Resources