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/
Related
Trying to access multiple objects in the POST method using SpringBoot MVC and thymeleaf.
here is the controller.
#Controller
public class PatientController {
ObjectMapper Obj = new ObjectMapper();
#GetMapping("/patient")
public static String patientForm(Model model) {
model.addAttribute("patient", new PatientDataModel());
model.addAttribute("patient1", new PatientDataModel1());
return "patient";
}
#RequestMapping(value="/patient", method=RequestMethod.POST, params="action=Send data to MongoDB cluster")
public static String patientSubmit(#ModelAttribute("patient") PatientDataModel patient, #ModelAttribute("patient1") PatientDataModel patient1, Model model, Object obj ) throws JsonProcessingException {
model.addAttribute("patient", patient);
model.addAttribute("patient1", patient1);
return "result";
}
and here are the views:
patient.html
<form action="#" th:action="#{/patient}" th:object="${patient}" method="post">
<div th:object="${patient1}" >
<p>Patient Id: <input type="text" th:value="${patient.id}" /></p>
<p>Patient Name: <input type="text" th:value="${patient.name}" /></p>
<p>Message: <input type="text" th:value="${patient.content}" /></p>
<p>address: <input type="text" th:value="${patient1.address}" /></p>
</div>
<p><input type="submit" name="action" value="Send data to MongoDB cluster" />
<input type="reset" value="Reset" /></p>
</form>
</div>
and result.html
<div class="starter-template">
<h1>Result</h1>
<p th:text="'id: ' + ${patient.id}" />
<p th:text="'Name: ' + ${patient.name}" />
<p th:text="'content: ' + ${patient.content}" />
<p th:text="'address: ' + ${patient1.address}" />
Submit another message
</div>
and the bean classes are : PatientDataModel.java
public class PatientDataModel {
private long id;
private String content;
private String name;
public PatientDataModel()
{
}
public PatientDataModel(long id, String content, String name)
{
this.id = id;
this.content = content;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Override
public String toString()
{
return "Patient [id=" + id + ", firstName=" + name + ", " +
"content=" + content + "]";
}
}
another bean :
public class PatientDataModel1 {
private String address;
#Override
public String toString() {
return "Patient1 [address=" + address + "]";
}
public PatientDataModel1()
{
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
now , the issue is , I need both the beans to be accessible in the GET and POST method.
when I am running the code , it is executing but the beans does not have values , all are null . pls suggest
It will be easiest to have 1 object to find to the form. Create a new class PatientFormData for example that contains all the fields from the 2 objects and convert from/to the objects you have in the get and post methods in your controller.
For example:
public class PatientFormData {
private long id;
private String content;
private String name;
private String address;
public static PatientFormData from(PatientDataModel model,
PatientDataModel1 model1) {
id = model.getId();
content = model.getContent();
name = model.getName();
address = model.getAddress();
}
public PatientDataModel createPatientDataModel() {
PatientDataModel result = new PatientDataModel();
result.setId(id);
result.setContent(content);
result.setName(name);
return result;
}
// getters and setters here
}
Use this in the controller:
#Controller
public class PatientController {
ObjectMapper Obj = new ObjectMapper();
#GetMapping("/patient")
public static String patientForm(Model model) {
PatientFormData formData = PatientFormData.from(new PatientDataModel(), new PatientDataModel1());
model.addAttribute("patientFormData", formData);
return "patient";
}
#RequestMapping(value="/patient", method=RequestMethod.POST, params="action=Send data to MongoDB cluster")
public static String patientSubmit(#ModelAttribute("patientFormData") PatientFormData formData, Model model, Object obj ) throws JsonProcessingException {
PatientDataModel model = formData.createPatientDataModel();
PatientDataModel1 model1 = formData.createPatientDataModel1();
// Do more processing with objects
return "result";
}
Also be sure to correctly use the field binding using *{..}:
<form action="#" th:action="#{/patient}" th:object="${patientFormData}" method="post">
<p>Patient Id: <input type="text" th:value="*{id}" /></p>
<p>Patient Name: <input type="text" th:value="*{name}" /></p>
<p>Message: <input type="text" th:value="*{content}" /></p>
<p>address: <input type="text" th:value="*{address}" /></p>
</div>
<p><input type="submit" name="action" value="Send data to MongoDB cluster" />
<input type="reset" value="Reset" /></p>
</form>
</div>
I have a controller class and I have debugged it. I have added 2 lines as below in the controller class.
model.addAttribute("employees",employees);
model.addAttribute("visitorForm",visitorForm);
I have seen both the objects are present and populated properly.
When it comes to the page it is as below.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Enter Visitor Details</title>
</head>
<body>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container"></div>
<form action="#" th:action="#{/enterVisitor}" th:object="${visitorForm}" method="post">
<p>Name: <input type="text" th:field="*{name}" required="required"/></p>
<p>Address: <input type="text" th:field="*{address}" required="required"/></p>
<p>Mobile: <input type="text" th:field="*{mobileNumber}" size="10" required="required" maxlength="10"/></p>
<p>Email: <input type="text" th:field="*{email}" /></p>
<p>Purpose: <input type="text" th:field="*{purposeOfvisit}" size="20" required="required"/></p>
<p>In Time:<input type="number" id="inTimee" name="inTimee" contenteditable="false" readonly="readonly"/></p>
<script type="text/javascript">document.getElementById("inTimee").value=new Date().getTime()</script>
<p>Employee to Meet: <select th:field="${visitorForm.id}">
<!-- <option text=""><option> -->
<option th:each="emp:${employees}"
th:value="${emp.id}"
th:text="${emp.name}"/>
</select>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</div>
<script type="text/javascript">
function getDateTime(){
var x = document.getElementById("inTimee").value=new Date().getTime();
}
</script>
</body>
</html>
I am getting an exception saying.
org.thymeleaf.exceptions.TemplateProcessingException: Attribute "value" is required in "option" tags (template: "visitor/enterVisitor" - line 20, col 26)
at org.thymeleaf.spring5.processor.SpringOptionFieldTagProcessor.doProcess(SpringOptionFieldTagProcessor.java:63) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:187) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.Model.process(Model.java:282) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
Here is the visitor form class.
package com.ahmed.visitorapp.forms;
import java.util.ArrayList;
import java.util.List;
import com.ahmed.visitorapp.model.Employee;
public class VisitorForm {
String id;
String name;
String address;
String mobileNumber;
String email;
String purposeOfvisit;
List<Employee> employees;
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPurposeOfvisit() {
return purposeOfvisit;
}
public void setPurposeOfvisit(String purposeOfvisit) {
this.purposeOfvisit = purposeOfvisit;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public void setEmployees(Iterable<Employee> employees) {
if(this.employees==null) {
this.employees = new ArrayList<>();
}
for(Employee emp:employees) {
this.employees.add(emp);
}
}
}
Employee class has fields name and Id. <select> tag causes the exception. How to fix it?
Add "value" attribute to your option like below :
<option th:each="emp:${employees}" th:value="${emp.id}" th:text="${emp.name}" value=""/>
For more detail refer this
Adding a more generic answer in a scenario where your <select> doesn't map to several fields in employees and maps to just one field, you will have to just add the "value" attribute.
There's no need for the th:value attribute
example :
<select th:field="*{employees}">
<option value="Name">Employee Name</option>
</select>
<td th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="red">You must provide a reason for your request.</td>
<td th:if="${#fields.hasErrors('selectedDate')}" th:errors="*{selectedDate}" class="red">You must select a date.</td>
Why are these td being populated by the following messages instead of the messages I have provided above? They also don't take on the css class I provided.
may not be empty may not be empty
Request Entity:
public class RequestModel {
private Long requestId;
#NotNull
#NotBlank
private String selectedDate;
private RequestStatus requestStatus;
#NotNull
#NotBlank
private String description;
private Boolean hasForced;
public String getSelectedDate() {
return selectedDate;
}
public void setSelectedDate(String selectedDate) {
this.selectedDate = selectedDate;
}
public Long getRequestId() {
return requestId;
}
public void setRequestId(Long requestId) {
this.requestId = requestId;
}
public RequestStatus getRequestStatus() {
return requestStatus;
}
public void setRequestStatus(RequestStatus requestStatus) {
this.requestStatus = requestStatus;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Boolean getHasForced() {
return hasForced;
}
public void setHasForced(Boolean hasForced) {
this.hasForced = hasForced;
}
}
Controller:
#RequestMapping(value = "/save", method = RequestMethod.POST)
String saveRequest(Principal principal, #Valid #ModelAttribute(value = "requestModel") RequestModel requestModel, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
// log.info("There are binding errors.");
return "send";
}
...
}
The full HTML form:
<form role="form" th:action="#{/request/save}" th:object="${requestModel}" method="post">
<input type="checkbox" th:field="*{hasForced}" th:checked="${false}" style="display: none;"/>
<p><input id="description" class="descriptionField" type="text" th:field="*{description}"
placeholder="Please provide a reason for your request"
style="width: 500px; border-radius: 4px; padding: 11px 11px 11px 11px;"/></p>
<input id="embeddedDateField" class="dateField" placeholder="YYYY-MM-DD" type="text" th:field="*{selectedDate}" readonly
style="border-radius: 4px; background: #eefdff; text-align: center;"/><br>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div style="margin: 5px; width: 200px;"><input type="submit" value="Submit Request"
style="display: block;"></div>
<td th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="red">You must provide a reason for your request.</td>
<td th:if="${#fields.hasErrors('selectedDate')}" th:errors="*{selectedDate}" class="ed">You must select a date.</td>
</form>
What's going on here?
These messages are coming from validation annotation default values. To set your own you need to provide them like below or you can change from properties file using MessageSource.
#NotNull(message="You must select a date.")
#NotBlank(message="You must select a date.")
private String selectedDate;
Im running a Spring MVC application using JPA for persistence. I have a form which has an update button. When this button is clicked its supposed to update a users record in the database. The User table has an embedded table Address in it. I am able to access all the fields in the User table but not the embedded table. Here is my Request mapping
#RequestMapping(value="/user/{userid}",method=RequestMethod.POST)
public String Update(#ModelAttribute("user")User user,#PathVariable("userid") String userid,Model model){
Here is my User.java
#Entity
#Table(name="User")
public class User {
#Id
#Column(name = "userid")
private String id;
#Column(name="firstname")
private String firstname;
#Column(name="lastname")
private String lastname;
#Column(name="title")
private String title;
#Embedded
private Address address;
#ManyToMany
#JoinTable(name="phone_user", joinColumns={#JoinColumn(name="userid")},
inverseJoinColumns={#JoinColumn(name="phoneid")})
private List<Phone> phones;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Phone> getPhones() {
return phones;
}
public void setPhones(List<Phone> phones) {
this.phones = phones;
}
}
Note the #Embedded tag of Address field.
Here is my Address.java
#Embeddable
public class Address {
String street;
String city;
String state;
String zip;
#Column(name="street")
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
#Column(name="city")
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
#Column(name="state")
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
#Column(name="zip")
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
Here is my JSP which sends the form data
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<form method="POST" action="/cmpe275/user/${userid}">
<table>
<tr>
<td>Name</td>
<td><input type="text" readonly="readonly" name="userid" value="${id}"/></td>
</tr>
<tr><tr><tr><tr><tr><tr><tr><tr><tr>
<td>First Name</td>
<td><input type="text" name="firstname" value="${firstname}"/></td>
<td>Last Name</td>
<td><input type="text" name="lastname" value="${lastname}"/></td>
</tr>
<tr>
<tr><tr><tr><tr>
<td>Street</td>
<td><input type="text" name="street" value="${street}"/></td>
<td>City</td>
<td><input type="text" name="city" value="${city}"/></td>
<td>State</td>
<td><input type="text" name="state" value="${state}"/></td>
<td>Zip</td>
<td><input type="text" name="zip" value="${zip}"/></td>
</tr>
<tr><tr><tr><tr>
<td><input type="submit" onclick="updateUser();" name="Update" value="Update"/></td>
<td><input type="button" name="Delete" value="Delete"/></td>
</table>
</form>
</body>
<script>
function updateUser(){
console.log("hi");
}
</script>
</html>
I am unable to access the address fields using the getter/setters.
For example - In my handler mapping - To get the first name of the updated profile I can access it using :
user.getFirstName()
But If i want to access the updated Address I do a
user.getAddress.getCity()
I get a null value.
Any idea why?
I think this
<td><input type="text" name="street" value="${street}"/></td>
<td>City</td>
<td><input type="text" name="city" value="${city}"/></td>
<td>State</td>
<td><input type="text" name="state" value="${state}"/></td>
<td>Zip</td>
<td><input type="text" name="zip" value="${zip}"/></td>
should be
<td><input type="text" name="address.street" value="${address.street}"/></td>
<td>City</td>
<td><input type="text" name="address.city" value="${address.city}"/></td>
<td>State</td>
<td><input type="text" name="address.state" value="${address.state}"/></td>
<td>Zip</td>
<td><input type="text" name="address.zip" value="${address.zip}"/></td>
A spring controller is expecting the #ModelAttribute or #RequestBody to be structured like the POJO. So if you where not using a form and sending this data vs some js it would look something like
{
'firstname':'peter',
'lastname': 'griffen',
'address': {
'street':'31 Spooner Street'
}
}
What you had was the object completely flat. Which might work if you add the correct setters in the User class.
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 {
}