Request syntactically incorrect - java

I am trying to post some variables to my controller which are then entered into a DB. But i keep getting an error stating that the request is syntactically incorrect.
Here is the form.
<form:form action="addLink" method="POST" commandName="link" >
<table id="productFinderTable">
<tbody align="left">
<tr align="left">
<td colspan="2">Gender:<input style="width: 798px;" type="number" name="gender" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Garment:<input style="width: 798px;" type="number" name="garment" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Product Class:<input style="width: 798px;" type="number" name="productclass" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Sport:<input style="width: 798px;" type="text" name="sport" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Link:<input style="width: 798px;" type="text" name="link" value="http://www.google.ie" /></td>
</tr>
<tr align="left">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</tbody>
</table>
</form:form>
The Entity Link
package com.wlgore.webapp.fab.pfsa.db;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "LINK")
public class Link implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column
private String hash;
#Column
#NotNull
private String link;
#Column
#NotNull
private Integer garment;
#Column
#NotNull
private Integer productclass;
#Column
#NotNull
private Integer gender;
#Column
private String sport;
/**
* #return the link
*/
public String getLink() {
return link;
}
/**
* #param link the link to set
*/
public void setLink(String link) {
this.link = link;
}
/**
* #return the garment
*/
public Integer getGarment() {
return garment;
}
/**
* #param garment the garment to set
*/
public void setGarment(Integer garment) {
this.garment = garment;
}
/**
* #return the productclass
*/
public Integer getProductclass() {
return productclass;
}
/**
* #param productclass the productclass to set
*/
public void setProductclass(Integer productclass) {
this.productclass = productclass;
}
/**
* #return the gender
*/
public Integer getGender() {
return gender;
}
/**
* #param gender the gender to set
*/
public void setGender(Integer gender) {
this.gender = gender;
}
/**
* #return the sport
*/
public String getSport() {
return sport;
}
/**
* #param sport the sport to set
*/
public void setSport(String sport) {
this.sport = sport;
}
/**
* #return the hash
*/
public String getHash() {
return hash;
}
/**
* #param hash the hash to set
*/
public void setHash(String hash) {
this.hash = hash;
}
}
Controller
#RequestMapping(value = "/addLink", method = RequestMethod.POST)
public #ResponseBody String addNewCommand(#ModelAttribute("link") Link link, BindingResult result)throws Exception{
/***
* Here we receive the relvant variables 1.Gender 2.Garment 3.Product
* Class 4.Sport 5.Link
* */
try {
if (result.hasErrors()) {
throw new Exception("Invalid post!");
} else {
String hash = HashFunction.gen(8);
Link linkExists = dao.getById(hash);
while (null != linkExists) {
hash = HashFunction.gen(8);
linkExists = dao.getById(hash);
}
System.out.println(hash);
link.setHash(hash);
dao.create(link);
return new ObjectMapper().writeValueAsString("Test Message");
}
} catch (Exception e) {
return new ObjectMapper().writeValueAsString(new ErrorJSON(e));
}
}

I don’t think #ModelAttribute is the correct annotation here. For BindingResult to work, you also need #Valid on the form bean.

Related

BindigResult.hasErrors It doesn't work Spring frameworkd validation

I am working with the Spring Framework, I have a model mapped to a controller with which I am trying to do some validations with the annotations offered by Spring, I use the BindingResult hasErrors() interface and also the #Validate annotation, however although I leave fields empty in my models (and specifies the #NotEmpty annotation) I can't get the hasErrors to change its state, it stays false. Am I forgetting something?
#Entity
#Table(name = "Clientes")
public class Cliente {
#Id
#Column(name= "ID_cliente")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idCliente;
#Column(name= "Productos_cliente", nullable = true)
private String productosCliente;
#Column(name= "Primer_nombre")
#NotEmpty(message = "El nombre no puede estar vacio")
private String primerNombre;
#Column(name= "Segundo_nombre")
#NotEmpty
private String segundoNombre;
#Column(name= "Primer_apellido")
#NotEmpty
private String primerApellido;
#Column(name= "Segundo_apellido")
#NotEmpty
private String segundoApellido;
#Column(name= "Ciudad_cliente")
private String ciudadCliente;
#Column(name= "Direccion_cliente")
private String direccionCliente;
#Column(name= "Correo_electronico")
#NotEmpty
private String email;
#Column(name= "Contraseña")
#NotEmpty
private String contraseña;
public Cliente(String productosCliente, String primerNombre, String segundoNombre, String primerApellido, String segundoApellido, String email, String contraseña ){
this.productosCliente = productosCliente;
this.primerNombre = primerNombre;
this.segundoNombre = segundoNombre;
this.primerApellido = primerApellido;
this.segundoApellido = segundoApellido;
this.email = email;
this.contraseña = contraseña;
}
/**
* #return Integer return the idCliente
*/
public Integer getIdCliente() {
return idCliente;
}
/**
* #param idCliente the idCliente to set
*/
public void setIdCliente(Integer idCliente) {
this.idCliente = idCliente;
}
/**
* #return String return the productosCliente
*/
public String getProductosCliente() {
return productosCliente;
}
/**
* #param productosCliente the productosCliente to set
*/
public void setProductosCliente(String productosCliente) {
this.productosCliente = productosCliente;
}
/**
* #return String return the primerNombre
*/
public String getPrimerNombre() {
return primerNombre;
}
/**
* #param primerNombre the primerNombre to set
*/
public void setPrimerNombre(String primerNombre) {
this.primerNombre = primerNombre;
}
/**
* #return String return the segundoNombre
*/
public String getSegundoNombre() {
return segundoNombre;
}
/**
* #param segundoNombre the segundoNombre to set
*/
public void setSegundoNombre(String segundoNombre) {
this.segundoNombre = segundoNombre;
}
/**
* #return String return the primerApellido
*/
public String getPrimerApellido() {
return primerApellido;
}
/**
* #param primerApellido the primerApellido to set
*/
public void setPrimerApellido(String primerApellido) {
this.primerApellido = primerApellido;
}
/**
* #return String return the segundoApellido
*/
public String getSegundoApellido() {
return segundoApellido;
}
/**
* #param segundoApellido the segundoApellido to set
*/
public void setSegundoApellido(String segundoApellido) {
this.segundoApellido = segundoApellido;
}
/**
* #return String return the ciudadCliente
*/
public String getCiudadCliente() {
return ciudadCliente;
}
/**
* #param ciudadCliente the ciudadCliente to set
*/
public void setCiudadCliente(String ciudadCliente) {
this.ciudadCliente = ciudadCliente;
}
/**
* #return String return the direccionCliente
*/
public String getDireccionCliente() {
return direccionCliente;
}
/**
* #param direccionCliente the direccionCliente to set
*/
public void setDireccionCliente(String direccionCliente) {
this.direccionCliente = direccionCliente;
}
/**
* #return String return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return String return the contraseña
*/
public String getContraseña() {
return contraseña;
}
/**
* #param contraseña the contraseña to set
*/
public void setContraseña(String contraseña) {
this.contraseña = contraseña;
}
}
Controller:
#Controller
#Validated
public class FormController {
#Autowired
ClienteServices service;
#GetMapping("/register")
public String formLoggin(Model model, Cliente cliente, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente", cliente);
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}
}
register.html:
<body>
<div style="display: flex; flex-direction: column; min-width: 500; min-height: 800; align-items: center; justify-content: center;">
<h3 th:text="${Title}"></h3>
<form th:action="#{/register}" th:object="${cliente}" method="post">
<div>
<label for="Primer nombre">Primer nombre</label>
<div>
<input id="username" name="username" type="text" th:field="*{primerNombre}">
<div th:if="${#fields.hasErrors('primerNombre')}" th:errors="*{primerNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Segundo nombre</label>
<div>
<input id="Secondname" name="Secondname" type="text" th:field="*{segundoNombre}">
<div th:if="${#fields.hasErrors('segundoNombre')}" th:errors="*{segundoNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Primer apellido</label>
<div>
<input id="Surname" name="Surname" type="text" th:field="*{primerApellido}">
</div>
</div>
<div>
<label for="Segundo apellido">Segundo apellido</label>
<div>
<input id="secondSurname" name="secondSurname" type="text" th:field="*{segundoApellido}">
</div>
</div>
<div>
<label for="Email">Correo electrónico</label>
<div>
<input id="Email" name="email" type="email" th:field="*{email}">
</div>
</div>
<div>
<label for="contraseña">Contraseña</label>
<div>
<input id="contraseña" name="password" type="password" th:field="*{contraseña}">
</div>
</div>
<div>
<label for="contraseña">Ciudad</label>
<div>
<input id="City" name="City" type="text" th:field="*{ciudadCliente}">
</div>
</div>
<div>
<label for="contraseña">Dirección</label>
<div>
<input id="Dir" name="Dir" type="text" th:field="*{direccionCliente}">
</div>
</div>
<div class="card-footer">
<button type="submit">Enviar</button>
</div>
</form>
</div>
Every thing seems to be fine. Try changing your controller this way . Create a new object when sending it to the form like below instead of sending it through parameter as it might not be able to bind object properly:
#GetMapping("/register")
public String formLoggin(Model model, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente",new cliente()); //change this line
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid #ModelAttribute("cliente") Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}
This is generally a result from only including the javax.validation API and not an implementation. You probably have something like the following in your depenendencies list.
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
This is only the API not an implementation. This is much like including the JPA jakarta.persistence-api and expect JPA to work (but you still need an implementation like Hibernate ORM). For the validation this is the same you need an implementation, mostly used is hibernate-validator. So you could add
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.5.Final</version>
</dependency>
NOTE: You have to use version 6.x as 7+ is for the new Jakarta Validation API which isn't supported yet (as of Spring Framework 6 / Spring Boot 3 it will).
However as you are already using Spring Boot I would strongly encourage you to use.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
This will include both the API and an implementation (the aformentioned hibernate-validator one). It will make sure you have a compatible version for this version of Spring / Spring Boot.
Instead of annotating with '#NotEmpty' you can follow this method:
#Column(name= "Correo_electronico", nullable = false)
private String email;
When you use this method either Jpa or Hibernate will throw an error if the value is empty.

Thymeleaf form causes errors at th:field

I'm very new to Thymeleaf and I'm trying to make a registration form but it keeps giving me error 500's when I try to add th: attributes to my form. I assume it has something to do with the form not seeing the UserModel but I can't be sure. I feel like I've tried everything so any help would be greatly appreciated!
Here's my registration form:
<!DOCTYPE html>
<html xmlns:th=”http://www.thymeleaf.org” xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="layouts/defaultTemplate">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Register - AZSnowSports</title>
</head>
<body>
<div layout:fragment="content">
<form action="#" th:action="#{doRegister}" th:object="${userModel}" method="POST">
<table>
<tr>
<td>First Name:</td><td><input type="text" th:field="*{firstName}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}">First Name Error</h5></td>
</tr>
<tr>
<td>Last Name:</td><td><input type="text" th:field="*{lastName}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}">Last Name Error</h5></td>
</tr>
<tr>
<td>EMail:</td><td><input type="email" th:field="*{email}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">EMail Error</h5></td>
</tr>
<tr>
<td>Address:</td><td><input type="text" th:field="*{address}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('address')}" th:errors="*{address}">Address Error</h5></td>
</tr>
<tr>
<td>Phone Number:</td><td><input type="number" th:field="*{phoneNumber}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('phoneNumber')}" th:errors="*{phoneNumber}">Phone Number Error</h5></td>
</tr>
<tr>
<td>Username:</td><td><input type="text" th:field="*{username}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username Error</h5></td>
</tr>
<tr>
<td>Password:</td><td><input type="password" th:field="*{password}"></td><td><h5 style="color: red" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</h5></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
Here's my controller:
package com.azsnowsports.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.azsnowsports.model.UserModel;
#Controller
#RequestMapping("/register")
public class RegisterController {
#GetMapping("/")
public String display(Model model)
{
// Display the login form view
model.addAttribute("title", "Register Form");
return "register";
}
#PostMapping("/doRegister")
public String doRegister(#Valid UserModel userModel, BindingResult bindingResult, Model model)
{
//Check for validation errors
if (bindingResult.hasErrors())
{
model.addAttribute("title", "Register Form");
return "register";
}
return "registerSuccess";
}
}
And here's my user model:
package com.azsnowsports.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class UserModel {
/**
* The user's first name
*/
#NotNull(message="FirstName is a required field.")
#Size(min = 1, max = 32, message="First Name must be between 1 and 32 characters.")
private String firstName;
/**
* The user's last name
*/
#NotNull(message="Last name is a required field.")
#Size(min = 1, max = 32, message="Last name must be between 1 and 32 characters.")
private String lastName;
/**
* The user's email
*/
#NotNull(message="EMail is a required field.")
private String email;
/**
* The user's address
*/
#NotNull(message="Address is a required field.")
private String address;
/**
* The user's phone number
*/
#NotNull(message="Phone Number is a required field.")
private int phoneNumber;
/**
* The user's username
*/
#NotNull(message="Username is a required field.")
#Size(min = 1, max = 32, message="Username must be between 1 and 32 characters.")
private String username;
/**
* The user's password
*/
#NotNull(message="Password is a required field.")
#Size(min = 1, max = 32, message="Password must be between 1 and 32 characters.")
private String password;
/**
* Constructor
*
* #param firstNameVal The first name of the user
* #param lastNameVal The last name of the user
* #param emailVal The email of the user
* #param addressVal The address of the user
* #param phoneNumber The phone number of the user
* #param usernameVal The username for the user
* #param passwordVal The password for the user
*/
public UserModel(String firstNameVal, String lastNameVal, String emailVal, String addressVal,
int phoneNumberVal, String usernameVal, String passwordVal)
{
this.firstName = firstNameVal;
this.lastName = lastNameVal;
this.email = emailVal;
this.address = addressVal;
this.phoneNumber = phoneNumberVal;
this.username = usernameVal;
this.password = passwordVal;
}
/**
* #return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* #param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* #return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* #param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the address
*/
public String getAddress() {
return address;
}
/**
* #param address the address to set
*/
public void setAddress(String address) {
this.address = address;
}
/**
* #return the phoneNumber
*/
public int getPhoneNumber() {
return phoneNumber;
}
/**
* #param phoneNumber the phoneNumber to set
*/
public void setPhoneNumber(int phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* #return the username
*/
public String getUsername() {
return username;
}
/**
* #param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* #return the password
*/
public String getPassword() {
return password;
}
/**
* #param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
Heres a screenshot of my file structure:
I added model.addAttribute("userModel", new UserModel()); into the root map of the model so it now looks like this:
#GetMapping("/")
public String display(Model model)
{
// Display the login form view
model.addAttribute("title", "Register Form");
model.addAttribute("userModel", new UserModel());
return "register";
}
This fixed it and it runs fine now!

How i get value another class when i using #ManyToMany

I have 2 class. Requests and Services class.
Requests class.
import com.eziz.clients.Clients;
import com.eziz.services.Services;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "request")
public class Requests {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long requestId;
#Column(nullable = false, length = 80)
private String requestComment;
#Column(nullable = false, length = 15)
private String requestStatus;
#DateTimeFormat(pattern = "dd-MM-yyyy")
#Column(nullable = false)
private String requestExpiryTime;
#DateTimeFormat(pattern = "dd-MM-yyyy")
#Column(nullable = false)
private String requestDateCreated;
#ManyToOne
#JoinColumn(name = "requestClientId")
private Clients client;
#ManyToMany
#JoinColumn(name = "requestServiceId")
private Set<Services> service = new HashSet<>();
// #ManyToOne
// #JoinColumn(name = "requestService")
// private Services services;
//
public Long getRequestId() {
return requestId;
}
public void setRequestId(Long requestId) {
this.requestId = requestId;
}
public String getRequestComment() {
return requestComment;
}
public void setRequestComment(String requestComment) {
this.requestComment = requestComment;
}
public String getRequestStatus() {
return requestStatus;
}
public void setRequestStatus(String requestStatus) {
this.requestStatus = requestStatus;
}
public String getRequestExpiryTime() {
return requestExpiryTime;
}
public void setRequestExpiryTime(String requestExpiryTime) {
this.requestExpiryTime = requestExpiryTime;
}
public String getRequestDateCreated() {
return requestDateCreated;
}
public void setRequestDateCreated(String requestDateCreated) {
this.requestDateCreated = requestDateCreated;
}
public Clients getClient() {
return client;
}
public void setClient(Clients client) {
this.client = client;
}
public Set<Services> getService() {
return service;
}
public void setService(Set<Services> service) {
this.service = service;
}
}
Service Class.
package com.eziz.services;
import javax.persistence.*;
#Entity
#Table(name = "service")
public class Services {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long serviceId;
#Column(nullable = false, length = 20)
private String serviceName;
#Column(nullable = false, length = 30)
private String serviceCategory;
#Column(nullable = false)
private double servicePrice;
public Long getServiceId() {
return serviceId;
}
public void setServiceId(Long serviceId) {
this.serviceId = serviceId;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getServiceCategory() {
return serviceCategory;
}
public void setServiceCategory(String serviceCategory) {
this.serviceCategory = serviceCategory;
}
public double getServicePrice() {
return servicePrice;
}
public void setServicePrice(double servicePrice) {
this.servicePrice = servicePrice;
}
#Override
public String toString() {
return this.serviceName;
}
}
Now i get serviceName with ManyToMany in Service class.
But i can not get another value.i am need do this without toString.
<div class="modal header">
<h5 class="modal-title" id="modalTitle">Request Details</h5>
<button aria-label="Close" class="close" data-dismiss="modal"
type="button">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="content content-fixed content-auth">
<div class="container">
<h1 class="tx-color-01 mg-b-5" align="center">
SIFARIŞ MƏLUMATLARI </h1>
<hr>
<table class="table">
<tr th:object="${request}">
<tr>
<th scope="col">Sifariş ID</th>
<td scope="col" data-label="Sifariş ID" th:text="${request.requestId}"></td>
</tr>
<tr>
<th scope="col">Qeydiyyat tarixi</th>
<td data-label="Qeydiyyat tarixi" th:text="${request.requestDateCreated}"></td>
</tr>
<tr>
<th scope="col">Xidmət</th>
<td data-label="Xidmət" th:text="${request.service}"></td>
</tr>
<tr>
<th scope="col">Təhvil vermə zamanı</th>
<td data-label="Təhvil vermə zamanı" th:text="${request.requestExpiryTime}"></td>
</tr>
<tr>
<th scope="col">Rəy</th>
<td data-label="Rəy" th:text="${request.requestComment}"></td>
</tr>
<tr>
<th scope="col">Status</th>
<td data-label="Status" th:text="${request.requestStatus}"></td>
</tr>
</tr>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Bağla</button>
</div>
I dont can get value when i doing this.
<tr>
<th scope="col">Xidmət</th>
<td data-label="Xidmət" th:text="${request.service.serviceCategory}"></td>
</tr>
or
<tr>
<th scope="col">Xidmət</th>
<td data-label="Xidmət" th:text="${request.service.serviceCount}"></td>
</tr>
how i can do this? How i can get request.service.serviceCount or serviceCategory or serviceName
when i doing request.service this only coming serviceName, because i write here toString method return this.serviceName . i can get all of them with toString method. But i am need separately.
This is my Thymeleaf example
<p>
<span th:each="task : ${foo.tasks}">
<span th:text="${taskStat.index} + ': ' + ${task.name}"></span>
</span>
</p>
<tr th:each="book : ${listBooksTest}">
<td th:text="${book.id}">ID Book</td>
<td th:text="${book.id_author}">ID Author</td>
<td th:text="${book.title}">Title</td>
</td>
</tr>
#GetMapping("/requests/view/{requestId}")
public String requestDetails(#PathVariable(value = "requestId") long requestId, Model model) {
Requests request = requestService.getRequestById(requestId);
List<Clients> listClients = clientService.getAllClients();
List<Services> listServices = serviceRepository.findAll();
model.addAttribute("listServices", listServices);
model.addAttribute("listClients", listClients);
model.addAttribute("request", request);
return "request_detail_modal";
}
Yuxarıda list kimi gətirmişəm, onu burada td-ə gətirmək lazımdı.
<tr>
<th scope="col">Xidmət</th>
<td data-label="Xidmət" th:field="*{service}" th:text="{}"></td>
</tr>

how to store double value from jsp to spring mvc controller

Here is my JSP page:
<c:url var="productSave" value="/admin/products/emi.html" />
<form:form method="Post" action="${productSave}"
modelAttribute="intrest">
<table>
<tr>
<td>Id :</td>
<td><form:input path="financerId" /></td>
</tr>
<tr>
<td>downpayment :</td>
<td><form:input path="downpayment" /></td>
</tr>
<tr>
<td>months :</td>
<td><form:input path="months" /></td>
</tr>
<tr>
<td>intrest :</td>
<td><form:input path="intrest" /></td>
</tr>
<tr>
<td></td>
<td><input onclick="self.close()" type="submit" value="Save" /></td>
</tr>
</table>
</form:form>
Here I am taking intrest field as double in model bean. but when i try to save the entity it throws
Failed to convert value of type 'java.lang.String' to required type 'com.salesmanager.core.model.catalog.product.relationship.FinancerRateofIntrest'; nested exception is org.springframework.core.convert.ConversionFailedException
Controller :
#RequestMapping(value = "/admin/products/emi.html", method = RequestMethod.POST)
public String GetEmiOption(#Valid #ModelAttribute("intrest") FinancerRateofIntrest intrest, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
rateofintrest.save(intrest);
return "admin-products-emi";
}
Entity class:
#Entity
#Table(name = "FinancerRateofIntrest", schema = SchemaConstant.SALESMANAGER_SCHEMA)
public class FinancerRateofIntrest extends SalesManagerEntity<Long, FinancerRateofIntrest> {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ID", unique = true, nullable = false)
#TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_RELATION_SEQ_NEXT_VAL")
#GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
private Long id;
private int financerId;
private String downpayment;
private String months;
private Double intrest;
public Double getIntrest() {
return intrest;
}
public void setIntrest(Double intrest) {
this.intrest = intrest;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getFinancerId() {
return financerId;
}
public void setFinancerId(int financerId) {
this.financerId = financerId;
}
public String getDownpayment() {
return downpayment;
}
public void setDownpayment(String downpayment) {
this.downpayment = downpayment;
}
public String getMonths() {
return months;
}
public void setMonths(String months) {
this.months = months;
}
}
You are using same name for object and variable inside it.
Change varibale name of modelAttribute from intrest to something else like financerRateofIntrest in :
<form:form method="Post" action="${productSave}" modelAttribute="financerRateofIntrest">
And
#RequestMapping(value = "/admin/products/emi.html", method = RequestMethod.POST)
public String GetEmiOption(#Valid #ModelAttribute("financerRateofIntrest") FinancerRateofIntrest intrest, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
rateofintrest.save(intrest);
return "admin-products-emi";
}
Also, from controller method where you return your jsp page.

Displaying Links to Products or Categories from the Controller Servlet into jsp pages

I'm trying to link products to their own jsp page after a user chose a given product. I'm doing something wrong because the data doesn't display once on the product.jsp.
I try to retrieve the data with the variable selectedProduct but it seems the application doesn't recognize it or doesn't know where to retrieve the data for the variableselectedProduct.
I don't know why since, in my opinion, selectedProduct would be the same as selectedCategory... Apparently it is not... Why? Am I missing something?
I've been going through solutions for the past week. Any help is more than welcomed!
Controller Servlet:
package controller;
import cart.ShoppingCart;
import wishlist.Wishlist;
import entity.Category;
import entity.Product;
import java.io.IOException;
import java.util.Collection;
import javax.ejb.EJB;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import session.CategoryFacade;
import session.ProductFacade;
public class ControllerServlet extends HttpServlet {
#EJB
private CategoryFacade categoryFacade;
#EJB
private ProductFacade productFacade;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
HttpSession session = request.getSession();
Category selectedCategory;
Product selectedProduct;
Collection<Product> categoryProducts;
// if category page is requested
if (userPath.equals("/category")) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in session scope
session.setAttribute("selectedCategory", selectedCategory);
// get all products for selected category
categoryProducts = selectedCategory.getProductCollection();
// place category products in session scope
session.setAttribute("categoryProducts", categoryProducts);
}
// if product page is requested
if (userPath.equals("/product")) {
// get productId from request
String productId = request.getQueryString();
if (productId != null) {
// get selected product
selectedProduct = productFacade.find(Short.parseShort(productId));
// place selected product in session scope
session.setAttribute("selectedProduct", selectedProduct);
}}
EDIT BASED ON REQUEST
Product.java:
package entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author PC
*/
#Entity
#Table(name = "product")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p"),
#NamedQuery(name = "Product.findById", query = "SELECT p FROM Product p WHERE p.id = :id"),
#NamedQuery(name = "Product.findByName", query = "SELECT p FROM Product p WHERE p.name = :name"),
#NamedQuery(name = "Product.findByPrice", query = "SELECT p FROM Product p WHERE p.price = :price"),
#NamedQuery(name = "Product.findByDescription", query = "SELECT p FROM Product p WHERE p.description = :description"),
#NamedQuery(name = "Product.findByLastUpdate", query = "SELECT p FROM Product p WHERE p.lastUpdate = :lastUpdate")})
public class Product implements Serializable {
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "price")
private BigDecimal price;
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 16777215)
#Column(name = "name")
private String name;
#Lob
#Size(max = 2147483647)
#Column(name = "description")
private String description;
#Basic(optional = false)
#NotNull
#Column(name = "last_update")
#Temporal(TemporalType.TIMESTAMP)
private Date lastUpdate;
#JoinColumn(name = "category_id", referencedColumnName = "id")
#ManyToMany(mappedBy = "productCollection")
private Collection<Category> categoryCollection;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
private Collection<OrderedProduct> orderedProductCollection;
/**
*
*/
public Product() {
}
/**
*
* #param id
*/
public Product(Integer id) {
this.id = id;
}
/**
*
* #param id
* #param name
* #param price
* #param lastUpdate
*/
public Product(Integer id, String name, BigDecimal price, Date lastUpdate) {
this.id = id;
this.name = name;
this.price = price;
this.lastUpdate = lastUpdate;
}
/**
*
* #return
*/
public Integer getId() {
return id;
}
/**
*
* #param id
*/
public void setId(Integer id) {
this.id = id;
}
/**
*
* #return
*/
public String getName() {
return name;
}
/**
*
* #param name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
*/
public String getDescription() {
return description;
}
/**
*
* #param description
*/
public void setDescription(String description) {
this.description = description;
}
/**
*
* #return
*/
public Date getLastUpdate() {
return lastUpdate;
}
/**
*
* #param lastUpdate
*/
public void setLastUpdate(Date lastUpdate) {
this.lastUpdate = lastUpdate;
}
/**
*
* #return
*/
#XmlTransient
public Collection<Category> getCategoryCollection() {
return categoryCollection;
}
/**
*
* #param categoryCollection
*/
public void setCategoryCollection(Collection<Category> categoryCollection) {
this.categoryCollection = categoryCollection;
}
/**
*
* #return
*/
#XmlTransient
public Collection<OrderedProduct> getOrderedProductCollection() {
return orderedProductCollection;
}
/**
*
* #param orderedProductCollection
*/
public void setOrderedProductCollection(Collection<OrderedProduct> orderedProductCollection) {
this.orderedProductCollection = orderedProductCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Product)) {
return false;
}
Product other = (Product) object;
return !((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)));
}
#Override
public String toString() {
return "entity.Product[ id=" + id + " ]";
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
Product.jsp
<table style="text-align: left; width: 100%; height: 172px;" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td colspan="1" rowspan="6" style="vertical-align: top;">product_gallery<br></td>
<td colspan="1" rowspan="6" style="vertical-align: top;"><img class="img" src="${initParam.productBigImagePath}${product.name}.jpg"><br></td>
<td style="vertical-align: top;">${selectedProduct.name}<br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;">$ ${selectedProduct.price}</td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td colspan="2" rowspan="1" style="vertical-align: top;">${selectedProduct.description}</td>
</tr>
<tr>
<td style="vertical-align: top;">
<form action="addToWishlist" method="post"><br><br>
<input name="productId" value="${product.id}" type="hidden">
<input class="submit" onclick="addedWishlist()" value="<fmt:message key='AddToWishlist'/>" type="submit">
</form><br>
</td>
<td style="vertical-align: top;">
<form action="addToCart" method="post"><br><br>
<input name="productId" value="${product.id}" type="hidden">
<input class="submit" onclick="addedCart()" value="<fmt:message key='AddToCart'/>" type="submit">
</form>
</td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
<td colspan="2" rowspan="1" style="vertical-align: top;">
<ul>
<li style="background-color: rgb(198, 255, 201); width:100%; text-align:center; border-radius:2em;">
<fmt:message key='ContinueShopping'/>
</li>
</ul>
<br>
</td>
</tr>
</tbody>
</table>
Category.jsp
<table style="text-align: left; width: 100%;" border="0" cellpadding="0" cellspacing="40px">
<c:forEach var="product" items="${categoryProducts}" varStatus="iter">
<td>
<tbody>
<tr>
<td style="vertical-align: middle; text-align: center;" class="cell">
<a href="product?${product.id}">
<img class="img" alt="" src="${initParam.productImagePath}${product.name}.jpg" />
<div class="caption">
<br>view details</div>
</a>
<br>
</td>
<td style="vertical-align: middle; width: 140px; text-align: center; ">${product.name}
<br>
</td>
<td style="vertical-align: middle; width: 120px; text-align: center; line-height:100%;">$${product.price}
<br>
</td>
<td style="vertical-align: middle; width: 136px; text-align: center; line-height:20%;">
<form id="wishlistForm" action="addToWishlist" method="post">
<br>
<br>
<input name="productId" value="${product.id}" type="hidden">
<input class="submit" onclick="addedWishlist()" value="<fmt:message key='AddToWishlist'/>" type="submit">
</form>
<br>
</td>
<td style="vertical-align: middle; width: 136px; text-align: center; line-height:20%;">
<form id="cartForm" action="addToCart" method="post">
<br>
<br>
<input name="productId" value="${product.id}" type="hidden">
<input class="submit" onclick="addedCart()" value="<fmt:message key='AddToCart'/>" type="submit">
</form>
<br>
</td>
</tr>
</tbody>
</c:forEach>
</table>
You're setting as session attribute a selectProduct which is an individual product:
Product selectedProduct;
...
session.setAttribute("selectedProduct", selectedProduct);
<c:forEach> in JSTL tags is for Collections, Lists or Arrays not for individual objects.
Due this it's normal that your first scenario with: <c:forEach var="product" items="${selectedProduct}" varStatus="iter"></c:forEach> it's blank, because you cannot iterate over a simple bean.
In your second scenario you're iterating over ${categoryProducts}. I suppose that you are setting this object as session attribute (it's not show in your snippet but surely is on it), at least this object is a collection, so in your server I suppose you've:
Collection<Product> categoryProducts;
...
session.setAttribute("categoryProducts", categoryProducts);
In this case if you are using <c:forEach var="product" items="${categoryProducts}" varStatus="iter"></c:forEach> you're iterating over all products in this category this is why all products appears in your page.
In your third case like the second one you are using <c:forEach var="product" items="${categoryProducts}" varStatus="iter"></c:forEach>, so you're assigning each step of the loop an element from categoryProducts collection to a product object, however inside this loop you're using ${selectedProduct} instead of ${product} so for each iteration you're using the same object instead of the object give it from the collection.
I think if you want to show only one product in your product.jsp, and this product is stored on selectedProduct session attributte, then to solve your problem don't use <c:forEach>, remove it from your product.jsp (since you only want to show one product), and in the jsp code use ${selectedProduct.yourProperty} instead of ${product.yourProperty}.
EDIT BASED ON COMMENT
Try with the follow product.jsp, if it continues to show a blank page, check that you're really setting a session attribute named selectedProduct with your product, and it has a value for it's members (selectProduct.getName(), selectProduct.getDescription(), selectProduct.getPrice() are not blank). Check the code inside your if, maybe it's never executed or in case it's executed your selectProduct has some empty fields
if (productId != null) {
// get selected product
selectedProduct = productFacade.find(Short.parseShort(productId));
// place selected product in session scope
session.setAttribute("selectedProduct", selectedProduct);
}
Product.jsp:
<table style="text-align: left; width: 100%; height: 172px;" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td colspan="1" rowspan="6" style="vertical-align: top;">product_gallery<br></td>
<td colspan="1" rowspan="6" style="vertical-align: top;"><img class="img" src="${initParam.productBigImagePath}${selectedProduct.name}.jpg"><br></td>
<td style="vertical-align: top;">${selectedProduct.name}<br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;">$ ${selectedProduct.price}</td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
</tr>
<tr>
<td colspan="2" rowspan="1" style="vertical-align: top;">${selectedProduct.description}</td>
</tr>
<tr>
<td style="vertical-align: top;">
<form action="addToWishlist" method="post"><br><br>
<input name="productId" value="${selectedProduct.id}" type="hidden">
<input class="submit" value="<fmt:message key='AddToWishlist'/>" type="submit">
</form><br>
</td>
<td style="vertical-align: top;">
<form action="addToCart" method="post"><br><br>
<input name="productId" value="${selectedProduct.id}" type="hidden">
<input class="submit" value="<fmt:message key='AddToCart'/>"type="submit">
</form>
</td>
</tr>
<tr>
<td style="vertical-align: top;"><br></td>
<td style="vertical-align: top;"><br></td>
<td colspan="2" rowspan="1" style="vertical-align: top;">
<ul>
<li style="background-color: rgb(198, 255, 201); width:100%; text-align:center; border-radius:2em;">
<fmt:message key='ContinueShopping'/>
</li>
</ul>
<br>
</td>
</tr>
</tbody>
</table>
Hope this helps,
Edit with working answer
// if product page is requested
} else if (userPath.equals("/viewProduct")) {
String productId = request.getQueryString();
if (productId != null) {
// get selected product
selectedProduct = productFacade.find(Integer.parseInt(productId));
// place selected product in session scope
session.setAttribute("selectedProduct", selectedProduct);
}
userPath = "/product";

Categories