Spring get data from html select - spring

I'm using Spring MVC to build website.
I have a simple form in HTML:
<form action="#" th:action="#{/new_product}" th:object="${webProduct}" method="post">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Des: <input type="text" th:field="*{description}" /></p>
<p>Price: <input type="text" th:field="*{price}" /></p>
<p>Category: </p>
<select>
<th:forEach th:each="category : ${categories}">
<option th:text="${category.name}" th:value="${category.category_id}"></option>
</th:forEach>
</select>
<p><input type="submit" value="Save" /></p>
</form>
When user click button I call the method:
#RequestMapping(value = "/new_product", method = RequestMethod.POST)
public String setNewProduct(#Valid WebProduct product, Model model){
//productService.add(product, "test");
System.out.println("Value: " + product.getName());
System.out.println("Value: " + product.getDescription());
System.out.println("Value: " + product.getPrice());
System.out.println("Value: " + product.getCategoryId());
return "add_ok";
}
Name, description, price are showing but categoryId not. Where is the problem?

Related

Thymeleaf errors are not showing on page but validation is fine

Controller:
#PostMapping("/saveExpense/{walletId}")
public String saveExpense(#PathVariable(value = "walletId") long walletId,
#ModelAttribute("wallets") #Valid Transaction transaction, BindingResult result, Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
long userId = user.getId();
Wallet wallet = walletService.getWalletById(walletId);
boolean thereAreErrors = result.hasErrors();
if (thereAreErrors) {
model.addAttribute("transaction", transaction);
return "redirect:/api/transaction/showNewTransactionForm/" + walletId;
}
transaction.setWallet(wallet);
transactionService.saveExpense(transaction, walletId, userId);
return "redirect:/api/wallet/userWallet/balance/" + userId;
}
This is form inside Thymeleaf:
<form action="#" id="Expense" class="hidden" th:action="#{/api/transaction/saveExpense/{walletId} (walletId=${id})}"
th:object="${transaction}" method="POST">
<input type="text" th:field="*{amount}" placeholder="Enter amount" class="form-control mb-4 col-4">
<p th:if="${#fields.hasErrors('amount')}" th:class="${#fields.hasErrors('amount')}? error">
Invalid Age</p>
<input type="text" th:field="*{note}" placeholder="Enter note" class="form-control mb-4 col-4">
<input type="date" th:field="*{date}" class="form-control mb-4 col-4">
<select th:field="${transaction.expenseCategories}">
<option value="0">Select expense category</option>
<option
th:each="expenseCategories : ${expenseCategories}"
th:value="${expenseCategories}"
th:text="${expenseCategories.displayName}"
></option>
</select>
<button type="submit" class="btn btn-info col-2"> Save Wallet</button>
</form>
Here is the part of field that I want to display error:
<input type="text" th:field="*{amount}" placeholder="Enter amount" class="form-control mb-4 col-4">
<p th:if="${#fields.hasErrors('amount')}" th:class="${#fields.hasErrors('amount')}? error">
Invalid Age</p>
And inside model:
#Min(value = 0, message = "Please, insert a positive amount")
private double amount;
So for example, if I try to set amount -1 and after I submit form, that data is not saved in database so that is fine, but I cant see errors on page, I just get redirected to same page but no errors are showing.
Just to mention, I already tried to find something useful here on SO but nothing worked so far

how to get the data from nested object entity class to thymeleaf

i have 2 entity class, parkingUser and parkingDetails,
user can have many parking details(one to many).
parkingUserobject contain:
[id, firstName, lastName,parkingDetails[id, entryDate,...,user_id(FK)]]
in parkingUser i had List of parkingDetails(its my FK)
#OneToMany(mappedBy = "parkingUsers", cascade = CascadeType.ALL, orphanRemoval = true)
private List<parkingDetails> parkingDetails = new ArrayList<parkingDetails>();
what i want to achive is to access the data of nested object,
like that:
parkingUser.getParkingDetails.getEntryTime()
this is my controller:
#GetMapping("/exitform")
public String exitForm(#RequestParam ("userId") int theId, Model model) {
parkingUsers parkingUsers = parkingUsersService.findByID(theId);
model.addAttribute("user",parkingUsers);
model.addAttribute("exitDateAndTime", new java.util.Date());
return "exit-form";
}
and my thymeleaf snift code:
<th:block th:object="${user}">
<form action="#" th:action="#{/saveDateAndTimeOfExitParking}" th:object="${user.parkingDetails}" method="POST">
<input type="hidden" th:field="*{id}"/>
<input type="text" th:field="*{firstName}">
<br>
<input type="text" th:field="*{lastName}">
<br>
<input type="text" th:field="*{license}">
<br>
<!-- i want to get the value of entryDate on parkingDetails object -->
<input type="text" th:field="*{user.parkingDetails.entryDate}">
<br>
<!-- i want to get the value of entryTime on parkingDetails object -->
<input type="text" th:field="*{user.parkingDetails.entryTime}">
<br>
<input type="text" th:value="${#dates.format(exitDateAndTime, 'dd-MM-yyyy')}">
<br>
<input type="text" th:value="${#dates.format(exitDateAndTime, 'HH:mm:ss')}">
<br>
<button type="submit" class="btn btn-info mb-11 col-15">Exit Car</button>
</form>
</th:block>

Why isn't the thymeleaf object recognized?

The first code snipped is me adding(or rather trying) the attribute 'NewUser' to use in html.
The error pops up for 'th:field="*{name}"'.
Error:
Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'
#RequestMapping("home")
public String newUser(Model model) {
User newUser = new User();
newUser.setId(100l);
newUser.setName("Test");
newUser.setEmail("test#what.com");
newUser.setPermission(0);
model.addAttribute(newUser);
return "index";
}
<form action="#" th:action="#{/home/add}" th:object="${newUser}" method="get">
<p>Id: <input type="text" th:field="*{name}" /></p>
<p>Message: <input type="text" th:field="*{email}" /></p>
<p>Message: <input type="text" th:field="*{permission}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
I think the cause is you didn't create the getter method for the fileds: name, email, and permission. So, when the thymeleaf try to render the page, it cannot read the value of the name field, or email field, or permission field.
I was adding another model and it seems like it was causing issues, so I ended up doing this and everything is working fine.
The 'userList' model is used elsewhere in the code.
#GetMapping("home")
public String index(Model model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("userList", userService.getUsers());
return "index";
}
<form th:object="${user}" th:action="#{/home/add}" method="get">
<p>Id: <input type="text" th:field="*{name}" /></p>
<p>Message: <input type="text" th:field="*{email}" /></p>
<p>Message: <input type="text" th:field="*{permission}" /></p>
<p><input type="submit" value="Submit" /> <input/></p>
</form>
maybe this will help someone...the issue is that you didn't provide the model that thymleaf will use to map your form input value. so you just have to pass as parameter "user model" like that .....
public String newUser(User model) {
}
.....thymleaf will use it to map your form field ...it work fine for me

Spring Required request part 'file' is not present

I'm trying to upload an image with a form, it's going to be the profile picture, but I get the error:
Required request part 'file' is not present
I'm really new with spring, so I don't know what's wrong here's part of the code:
This is the form
<form th:action="#{/form}" th:object="${cliente}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>Nombre</label>
<input class="form-control" type="text" th:field="*{nombre}" placeholder="Nombre"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('nombre')}" th:errors="*{nombre}"></small>
</div>
<div class="form-group">
<label>Apellido</label>
<input class="form-control" type="text" th:field="*{apellido}" placeholder="Apellido"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('apellido')}" th:errors="*{apellido}"></small>
</div>
<div class="form-group">
<label>Email</label>
<input class="form-control" type="text" th:field="*{email}" placeholder="correo#ejemplo.com"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></small>
</div>
<div class="form-group">
<label>Fecha</label>
<input class="form-control" type="text" th:field="*{createAt}" placeholder="DD/MM/YYYY"/>
<small class="form-text text-danger" th:if="${#fields.hasErrors('createAt')}" th:errors="*{createAt}"></small>
</div>
<div class="form-group">
<label>Imagen</label>
<input type="file" name="file" class="form-control" th:field="*{foto}">
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value="Guardar Cambios" />
</div>
<input type="hidden" th:field="*{id}" />
</form>
This is the controller function
#RequestMapping(value="/form", method=RequestMethod.POST)
public String guardar(#Valid Cliente cliente, BindingResult result,
#RequestParam("file") MultipartFile foto, RedirectAttributes flash) {
String mensaje;
if(result.hasErrors()) {
return "form";
}
if(!foto.isEmpty()) {
Path directorioRecursos = Paths.get("src//main//resources//static/uploads");
String pathRoot = directorioRecursos.toFile().getAbsolutePath();
try {
byte[] bytes = foto.getBytes();
Path rutaCompleta = Paths.get(pathRoot + "//" + foto.getOriginalFilename());
Files.write(rutaCompleta, bytes);
flash.addFlashAttribute("info", "Foto subida correctamente");
cliente.setFoto(foto.getOriginalFilename());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(cliente.getId() != null) {
mensaje = "Cliente actualizado correctamente";
}
else {
mensaje = "Cliente creado correctamente";
}
clienteservice.save(cliente);
flash.addFlashAttribute("success", mensaje);
return "redirect:listar";
}
This is my application properties
spring.http.multipart.file-size=10MB
spring.http.multipart.max-request-size=10MB
spring.http.multipart.enabled=true
Can you see what's wrong?
you're attaching a file to a string field with the th:field="*{foto}" ,
remove the th:field part in the input , should be like this:
<input type="file" name="file" class="form-control" />

Spring MVC :- Form Submission (HTTP Status 400 - The request sent by the client was syntactically incorrect.)

There are two forms each having one submit button in my jsp page ... I want to send form 1 to my controller which consists of two images and few form fields.
Controller.java
#RequestMapping(value="/schoolDetails",method=RequestMethod.GET)
public ModelAndView getschoolDetails(){
ModelAndView model = new ModelAndView();
School schools=new School();
Map referenceData = new HashMap();
referenceData.put("schoolObject", schools);
ModelAndView mav = new ModelAndView("schoolDetails", referenceData);
return mav;
}
#RequestMapping(value="/addSchoolDetails",method=RequestMethod.POST)
public String addSchoolDetails(#ModelAttribute("schoolObject") School school,
#RequestParam("image") MultipartFile image,#RequestParam("logo") MultipartFile logo){
if(result.hasErrors()){
return "schoolDetails"; }
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
CustomUser user=null;
if (principal instanceof CustomUser) {
user = ((CustomUser)principal);
}
return "schoolDetails";
}
schoolDetails.jsp
<form:form method="POST" role="form" action="/GenericApp/addSchoolDetails" enctype="multipart/form-data" modelAttribute="schoolObject">
<div class="col s3" id="sName">School Name :</div>
<input id="form_text" name="schoolname" type="text" placeholder="School Name"/>
<div class="col s3" id="sName">Email ID :</div>
<input id="form_text" name="email" type="email" placeholder="Email ID"/>
<div class="col s3" id="sName">State :</div>
<select name="state" id="state_id" >
<option>State</option>
<option>Karnataka</option>
</select>
<div class="col s12 m4 l4" id="sName">Upload School Logo :</div>
<input type="file" name="logo" id="fileUpload" accept="image/x-png, image/gif, image/jpeg"/>
<span class="button teal ">Choose a Image</span>
<button class="waves-effect waves-light btn" type="submit" name="action">Submit</button>
</form:form>
As your jsp does not contain any tag having name image correct your jsp file by adding tag with name image also , as below
<form:form method="POST" role="form" action="/GenericApp/addSchoolDetails" enctype="multipart/form-data" modelAttribute="schoolObject">
<div class="col s3" id="sName">School Name :</div>
<input id="form_text" name="schoolname" type="text" placeholder="School Name"/>
<div class="col s3" id="sName">Email ID :</div>
<input id="form_text" name="email" type="email" placeholder="Email ID"/>
<div class="col s3" id="sName">State :</div>
<select name="state" id="state_id" >
<option>State</option>
<option>Karnataka</option>
</select>
<div class="col s12 m4 l4" id="sName">Upload School Logo :</div>
<input type="file" name="logo" id="fileUpload" accept="image/x-png, image/gif, image/jpeg"/>
<span class="button teal ">Choose a Image</span>
<input type="file" name="image" id="image" accept="image/x-png, image/gif, image/jpeg"/>
<button class="waves-effect waves-light btn" type="submit" name="action">Submit</button>
</form:form>

Resources