HTTP Status 400 – Bad Request - Spring MVC - java

i've got this error on my project.
HTTP Status 400 – Bad Request.
The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
InsertClient.jsp
<form:form action="/moldar/saveCliente/" method="POST" modelAttribute="cliente">
<div class="form-group">
<label for="exampleSelect1">Pais</label>
<form:select path="pais" class="form-control" id="pais" name="wwww">
<c:forEach var="lista" items="${listaPaises}">
<option value="${lista.id}">${lista.nome}</option>
</c:forEach>
</form:select>
</div>
<div class="form-group">
<label for="exampleSelect1">Estado</label>
<form:select path="estado" class="form-control" id="estado" name="qqqqq">
<option value="">Selecione um estado</option>
<c:forEach var="lista" items="${listaEstados}">
<option value="${lista.id}">${lista.nome}</option>
</c:forEach>
</form:select>
</div>
<div class="form-group">
<label for="exampleSelect1">Cidade</label>
<form:select path="cidade" class="form-control" id="cidade" name="batata">
<option value="null">Selecione uma cidade</option>
<c:forEach var="lista" items="${listaCidades}">
<option value="${lista.id}">${lista.nome}</option>
</c:forEach>
</form:select>
</div>
My Controllers
#RequestMapping(value = "/saveCliente", method = RequestMethod.POST)
public String adicionarCliente(#ModelAttribute("cliente") Cliente cliente) {
clienteDao.saveOrUpdate(cliente);
return "redirect:/clientes";
}
#RequestMapping(value = "/addCliente", method = RequestMethod.GET, headers = "Accept=application/json")
public String inserirCliente(Model model) {
List<Estado> listaEstados = estadoDao.list(null);
List<Cidade> listaCidades = cidadeDao.list(null);
List<Pais> listaPaises = paisDao.list(null);
model.addAttribute("listaPaises", listaPaises);
model.addAttribute("listaEstados", listaEstados);
model.addAttribute("pais", new Pais());
model.addAttribute("cliente", new Cliente());
model.addAttribute("estado", new Estado());
model.addAttribute("cidade", new Cidade());
model.addAttribute("listaCidades", listaCidades);
return "inserirCliente";
}
Model
#Entity
#Table (name= "clientes")
public class Cliente {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column
private Integer id;
#Column
private String nome;
#Column
private String cpf;
#OneToOne
#JoinColumn (name="pais")
private Pais pais;
#OneToOne
#JoinColumn (name="estado")
private Estado estado;
#OneToOne
#JoinColumn (name="cidade")
private Cidade cidade;
#Column
private String logradouro;
#Column
private String numero;
#Column
private String cep;
#Column
private String email;
I have trying everything.
Can someone help me ? Please ?

In your Contoller this line of code
public String adicionarCliente(#ModelAttribute("cliente") Cliente cliente)
In your Cliente class the variables like pais
<form:select path="pais" class="form-control" id="pais" name="wwww">
you cannot bind this path="pais" to Cliente class variable pais , Because pais is not a String Type it is an Object type.
You can Create another class to Bind the input Selection Options to the variables.
class Client {
private String pais;
private String estado;
private String cidade;
public String getPais() {
return pais;
}
public void setPais(String pais) {
this.pais = pais;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
}

Related

Spring Validator validate method never called

I have two close to each other controllers - one for products and one for users.
I'd like to add Spring Validation to both controllers.
So I added ProductValidator and UserValidator classes which implement Validator.
ProductValidator works fine.
The problem is UserValidator is never called.
InitBinder method is being called, but validation doesn't work.
At the same time everything works fine with products in ProductController.
Here's the code of user logic.
UserController
#Controller
#RequestMapping(path = "/users")
public class UserController {
private final UserService userService;
private final RoleService roleService;
private PasswordEncoder passwordEncoder;
#Autowired
public UserController(UserService userService, RoleService roleService, PasswordEncoder passwordEncoder) {
this.userService = userService;
this.roleService = roleService;
this.passwordEncoder = passwordEncoder;
}
#Autowired
#Qualifier("userValidator")
private UserValidator userValidator;
#InitBinder("user")
private void initBinder(WebDataBinder binder) {
binder.setValidator(userValidator);
binder.registerCustomEditor(Role.class, "roles", new RoleEditor(roleService));
}
...
#RequestMapping(path = "/save", method = RequestMethod.POST)
public ModelAndView submit(#ModelAttribute("user") #Valid User user,
BindingResult result) {
...
}
...
}
UserValidator
#Component("userValidator")
public class UserValidator implements Validator {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
#Autowired
public UserValidator(UserRepository userRepository, RoleRepository roleRepository) {
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
#Override
public boolean supports(Class<?> paramClass) {
return User.class.equals(paramClass);
}
#Override
public void validate(Object obj, Errors errors) {
User user = (User) obj;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "username.required", "Enter username");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "firstName.required", "Enter user first name");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "lastName.required", "Enter user last name");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "password.required", "Enter user password");
User userToFind = userRepository.findByUsername(user.getUsername()).orElse(new User());
if (Objects.isNull(user.getId()) && Objects.nonNull(userToFind.getId())) {
errors.rejectValue("username", "username.already.exist", "user with this username already exists");
}
if (Objects.isNull(user.getRoles())) {
errors.rejectValue("roles", "role.required", "role must be assigned");
}
Role adminRole = roleRepository.getAdminRole();
if (Objects.nonNull(user.getId())
&& Objects.nonNull(user.getRoles())
&& !user.getRoles().contains(adminRole)
&& userRepository.findUsersWithAdministratorRole().size() == 1) {
errors.rejectValue("roles", "admin.required", "at least one admin role must exist");
}
}
public ErrorMessage validateUserToDelete(UUID id) {
ErrorMessage errorMessage = new ErrorMessage();
List<String> errors = new ArrayList<>();
Set<User> admins = userRepository.findUsersWithAdministratorRole();
if (admins.size() == 1) {
errors.add(String.format("User with email %s is the one with Admin role. Impossible to delete last Admin user."
, userRepository.findById(id).get().getUsername()));
}
errorMessage.setErrors(errors);
return errorMessage;
}
}
User
#Entity
#Table(name = "users")
public class User {
private UUID id;
private String username;
private String password;
private String firstName;
private String lastName;
private BigDecimal money;
private Set<Role> roles;
private Set<Product> products;
#Id
#Type(type="org.hibernate.type.PostgresUUIDType")
#Column(name = "id", columnDefinition = "uuid")
#GeneratedValue(strategy = GenerationType.AUTO)
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
#Column(name = "username")
#NotEmpty
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password")
#NotEmpty
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "first_name")
#NotEmpty
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "last_name")
#NotEmpty
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "money")
#DecimalMin(value = "0.0", inclusive = false)
#Digits(integer = 10, fraction = 2)
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.REFRESH})
#JoinTable(
name = "users_roles",
joinColumns = { #JoinColumn(name = "user_id") },
inverseJoinColumns = { #JoinColumn(name = "role_id") }
)
#NotNull
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.REFRESH})
#JoinTable(
name = "checkout",
joinColumns = { #JoinColumn(name = "user_id") },
inverseJoinColumns = { #JoinColumn(name = "product_id") }
)
public Set<Product> getProducts() {
return products;
}
public void setProducts(Set<Product> products) {
this.products = products;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id.equals(user.id) && username.equals(user.username) && password.equals(user.password) && firstName.equals(user.firstName) && lastName.equals(user.lastName);
}
#Override
public int hashCode() {
return Objects.hash(id, username, password, firstName, lastName);
}
}
user.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<c:import url="${contextPath}/WEB-INF/jsp/header.jsp"/>
</head>
<body>
<c:import url="${contextPath}/WEB-INF/jsp/navibar.jsp"/>
<div class="container">
<div class="row">
<security:authorize access="hasRole('ROLE_ADMIN')">
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group me-2" role="group" aria-label="Second group">
Back to users
</div>
</div>
</security:authorize>
</div><br>
<form:form action="/users/save" method="post" modelAttribute="user">
<div class="form-group">
<div class="row">
<form:label path="id">User ID:</form:label><br>
<form:input path="id" type="UUID" readonly="true" class="form-control" id="id" placeholder="User ID" name="id" value="${user.id}"/>
<br>
<form:label path="username">username (email address):</form:label><br>
<form:input path="username" type="text" class="form-control" id="username" placeholder="Enter username" name="username" value="${user.username}"/>
<form:errors path="username" cssClass="error"/>
<br>
<form:label path="password">Password:</form:label><br>
<form:input path="password" type="text" class="form-control" id="password" placeholder="Enter password" name="password" value="${user.password}"/>
<form:errors path="password" cssClass="error"/>
<br>
<form:label path="firstName">First name:</form:label><br>
<form:input path="firstName" type="text" class="form-control" id="firstName" placeholder="Enter first name" name="firstName" value="${user.firstName}"/>
<form:errors path="firstName" cssClass="error"/>
<br>
<form:label path="lastName">First name:</form:label><br>
<form:input path="lastName" type="text" class="form-control" id="lastName" placeholder="Enter last name" name="lastName" value="${user.lastName}"/>
<form:errors path="lastName" cssClass="error"/>
<br>
<form:label path="money">Money:</form:label><br>
<form:input path="money" type="number" class="form-control" id="money" placeholder="Enter money" name="money" value="${user.money}"/>
<form:errors path="money" cssClass="error"/>
<br>
<security:authorize access="hasRole('ROLE_ADMIN')">
<form:label path="roles">Roles:</form:label><br>
<c:forEach items="${roles}" var="role">
<form:checkbox path="roles" id="${roles}" label="${role.name}" value="${role}"/></td>
</c:forEach>
<br>
<form:errors path="roles" cssClass="error"/><br><br>
</security:authorize>
</div>
<div class="row">
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group me-2" role="group" aria-label="Second group">
<form:button type="submit" value="Submit" class="btn btn-primary">Save</form:button>
</div>
</div>
</div>
</div>
</form:form>
</div>
</body>
</html>
If you look at the classname from your debugger com.intellias.testmarketplace.controller.UserController$$EnhancerBySpringCGLIB$$309171b7 you see the $$EnhancerBySpringCGLIB. That part indicates that a proxy is being generated by Spring. A proxy can be generated for various reasons but the most common one for controllers is security, the #PreAuthorize annotation comes to mind. Another option is the #Timed annotation to do monitoring on the controller.
As your initBinder method is private this will be invoked directly on the proxy and not on the actual bean instance. This is due to a class proxy being created, which works by extending your class. A method is being generated with the same signature and the interceptor is invoked and then the call is passed on to the actual method. However this will only work for public and protected methods not for private or final methods. Those will be directly invoked on the empty proxy (the fields are null as that doesn't need the dependencies).
As your method is private it is invoked on the proxy. The proxy doesn't have the fields set, so the userValidator is null. So effectivly there is no Validator being set on the WebDataBinder and thus no validation will and can be done.
To fix, make the method public (or protected) so that it will properly be called on the actual bean and not the proxy.
For the future and as a rule of thumb you probably want your methods with annotations in a controller to be public anyway instead of `private.
The issue was in private access modifier for initBinder method combined with #PreAuthorize annotation on some UserController methods.
Many thanks to #M.Deinum for patience and help.

Why I Can't Do Mapping using Many-To-One

Do anyone knows why I can't do mapping using many-to-one?
This is my model
#Entity(name="trxrawatjalan")
public class Rawatjalan implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int idRawatjalan;
#Column(nullable = false, insertable = false, updatable = false)
private int idPasien;
#Column(nullable = false, insertable = false, updatable = false)
private int idDokter;
#Column(nullable = false, insertable = false, updatable = false)
private int idTreatment;
public Rawatjalan() {
}
public Rawatjalan(int idRawatjalan) {
this.idRawatjalan = idRawatjalan;
}
public int getIdPasien() {
return idPasien;
}
public void setIdPasien(int idPasien) {
this.idPasien = idPasien;
}
public int getIdDokter() {
return idDokter;
}
public void setIdDokter(int idDokter) {
this.idDokter = idDokter;
}
public int getIdTreatment() {
return idTreatment;
}
public void setIdTreatment(int idTreatment) {
this.idTreatment = idTreatment;
}
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name= "idPasien", nullable = false)
private Pasien pasien;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name= "idDokter", nullable = false)
private Dokter dokter;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name= "idTreatment", nullable = false)
private Treatment treatment;
public int getIdRawatjalan() {
return idRawatjalan;
}
public void setIdRawatjalan(int idRawatjalan) {
this.idRawatjalan = idRawatjalan;
}
#Override
public String toString () {
return "Rawatjalan{" +
"idRawatjalan=" + idRawatjalan +
'}';
This is my trxindex.jsp:
<c:forEach var="rawatjalan" items="${rawatjalans}">
<tr>
<td>${rawatjalan.idRawatjalan}</td>
<td>${rawatjalan.pasien.idPasien}</td>
<td>${rawatjalan.dokter.idDokter}</td>
<td>${rawatjalan.treatment.idTreatment}</td>
<td><span class="glyphicon glyphicon-pencil"></span></td>
<td><span class="glyphicon glyphicon-trash"></span></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<form class="form-horizontal" method="POST" action="save-treatment">
<input type="hidden" name="idRawatjalan" value="${rawatjalan.idRawatjalan}"/>
<div class="form-group">
<label class="control-label col-md-3">Id Pasien</label>
<div class="col-md-7">
<input type="text" class="form-control" name="rawatjalan.pasien.idPasien" value="${rawatjalan.pasien.idPasien}"/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">id Dokter</label>
<div class="col-md-7">
<input type="text" class="form-control" name="rawatjalan.dokter.idDokter" value="${rawatjalan.dokter.idDokter}"/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">id Treatment</label>
<div class="col-md-7">
<input type="text" class="form-control" rows="3" name="rawatjalan.treatment.idTreatment" value="${rawatjalan.treatment.idTreatment}"/>
</div>
</div>
This is my controller:
#Autowired
private TrxService trxService;
#GetMapping("/data-rawatjalan")
public String dataRawatjalans(HttpServletRequest request){
request.setAttribute("rawatjalans", trxService.findAll());
request.setAttribute("mode", "MODE_TASKS");
return "indextrx";
}
#GetMapping("/new-rawatjalan")
public String newRawatjalan(HttpServletRequest request){
request.setAttribute("mode", "MODE_NEW");
return "indextrx";
}
#PostMapping("/save-rawatjalan")
public String saveRawatjalan(#ModelAttribute Rawatjalan rawatjalan, BindingResult bindingResult, HttpServletRequest request){
trxService.save(rawatjalan);
request.setAttribute("rawatjalans", trxService.findAll());
request.setAttribute("mode", "MODE_TASKS");
return "indextrx";
}
#GetMapping("/update-rawatjalan")
public String updateRawatjalan(#RequestParam int idRawatjalan, HttpServletRequest request){
request.setAttribute("rawatjalan", trxService.findRawatjalan(idRawatjalan));
request.setAttribute("mode", "MODE_UPDATE");
return "indextrx";
}
#GetMapping("/delete-rawatjalan")
public String deleteRawatjalan(#RequestParam int idRawatjalan, HttpServletRequest request){
trxService.delete(idRawatjalan);
request.setAttribute("rawatjalans", trxService.findAll());
request.setAttribute("mode", "MODE_TASKS");
return "indextrx";
}
This is my service:
#Service
#Transactional
public class TrxService {
private final TrxinapRepository trxinapRepository;
public TrxService(TrxinapRepository trxinapRepository) {
this.trxinapRepository = trxinapRepository;
}
public List<Rawatjalan> findAll(){
List<Rawatjalan> rawatjalans = new ArrayList<>();
for(Rawatjalan rawatjalan : trxinapRepository.findAll()){
rawatjalans.add(rawatjalan);
}
return rawatjalans;
}
public Rawatjalan findRawatjalan(int idRawatjalan){
return trxinapRepository.findOne(idRawatjalan);
}
public void save(Rawatjalan rawatjalan){
trxinapRepository.save(rawatjalan);
}
public void delete(int idRawatjalan){
trxinapRepository.delete(idRawatjalan);
}
}
My Repository
package bootsample.dao;
import bootsample.mod`enter code here`el.Rawatjalan;
import org.springframework.data.repository.CrudRepository;
public interface TrxinapRepository extends CrudRepository<Rawatjalan, Integer>{
}
2019-05-19 03:10:50.977 ERROR 1712 --- [nio-8030-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [An exception occurred processing JSP page /WEB-INF/jsp/indextrx.jsp at line 77
74:
75:
76: ${rawatjalan.idRawatjalan}
77: ${rawatjalan.pasien.idPasien}
78: ${rawatjalan.dokter.idDokter}
79: ${rawatjalan.treatment.idTreatment}
80:
Stacktrace:] with root cause
javax.el.PropertyNotFoundException: Property 'pasien' not found on type bootsample.model.Rawatjalan

Spring+Velocity unsuccessful attempts to save object

I`ve ran into a problem with controller/vm data transfer and could not find any solution.
Ive got a User (see class below)
package com.Entity;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.*;
import java.util.Date;
#Entity
#Transactional
#Table(name = "USERS")
public class User {
private Long id;
private UserType type;
private String email;
private String password;
private String name;
private String tel;
private Date regDate;
private Date lastActive;
private Agent office;
//Constructors
public User(){
}
public User(UserType type, String email, String password, String name, String tel, Agent office) {
this.type = type;
this.email = email;
this.password = password;
this.name = name;
this.tel = tel;
this.regDate = new Date();
this.lastActive = null;
this.office = office;
}
//Getters
#Id
#SequenceGenerator(name = "USERID_SEQ", sequenceName = "USERID_SEQ",allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERID_SEQ")
#Column(name = "ID")
public Long getId() {
return id;
}
#Column(name = "TYPE")
public UserType getType(){
return type;
}
#Column(name = "EMAIL")
public String getEmail() {
return email;
}
#Column(name = "PASSWORD")
public String getPassword() {
return password;
}
#Column(name = "NAME")
public String getName() {
return name;
}
#Column(name = "TEL")
public String getTel() {
return tel;
}
#Column(name = "DATE_REG")
public Date getRegDate() {
return regDate;
}
#Column(name = "LAST_ACTIVE")
public Date getLastActive() {
return lastActive;
}
#ManyToOne (targetEntity = Agent.class, fetch = FetchType.EAGER)
#JoinColumn(name = "OFFICEID")
public Agent getOffice() {
return office;
}
// Setters
}
Controller for it
package com.Controllers;
import com.Entity.AgentType;
import com.Entity.User;
import com.Services.AgentService;
import com.Services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
//TODO: TEST CONTROLLER SUBJECT TO DELETE
#Controller
public class ViewController {
#Autowired
private UserService userService;
#Autowired
private AgentService agentService;
#RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView listUsersPage(){
List<User>list = userService.getAll();
return new ModelAndView("fragments/userss.vm","users",list);
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public ModelAndView edit(#PathVariable Long id){
return new ModelAndView("fragments/edit.vm",
"user", (User)userService.getById(id));
}
//FUNCTIONAL
#RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
public ModelAndView delete(#PathVariable Long id){
userService.delete(userService.getById(id));
return new ModelAndView("redirect:/list");
}
#RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(User user){
User user1 = user;
//userService.update(user1);
return new ModelAndView("redirect:/list");
}
//Model Attributes
#ModelAttribute
public void userTypesList(Model model){
model.addAttribute("types", userService.getPositions());
}
#ModelAttribute
public void officesList(Model model){
model.addAttribute("offices", agentService.getAllByType(AgentType.OFFICE));
}
}
and a pages (.vm) to add new or edit existing users(just one example the edit page):
<title>EDIT USER</title>
<body>
<form method="post" action="/update">
id:
<input type="text" name="id" path="id" value="$user.id"/> <br>
Type:
<select name="type" path="type">
<option hidden selected>$user.type</option>
#foreach($type in $types)
<option value="$type">$type</option>
#end
</select> <br>
e-mail:
<input type="text" name="email" path="email" value="$user.email"/> <br>
Password:
<input type="text" name="password" path="password" value="$user.password"/> <br>
Name:
<input type="text" name="name" path="name" value="$user.name"/> <br>
Tel:
<input type="text" name="tel" path="tel" value="$user.tel"/> <br>
Reg Date:
<input type="date" name="regDate" path="regDate" value="$user.regDate"/> <br>
Last Active:
<input type="date" name="lastActive" path="lastActive" value="$user.lastActive"/> <br>
Office:
<select name="office" path="office">
<option hidden selected value="$user.office">$user.office.name</option>
#foreach($office in $offices)
<option value="$office">$office.name</option>
#end
</select> <br>
<input type="submit" value="Update"/>
</form>
</body>
The problem is that I cant manage to save the updated User via /update(User user). Ive tried different ways, but still no success.
Whis this code I`m getting HTTP Status 400 – Bad Request. The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
Could you please help me out? What is wrong with it?
In your code you are missing a couple of things.
Frist of all, you miss the model attribute specified in the form:
<form method="post" action="/update" modelAttribute="user">
Second, you are missing the model attribute specified in the post method:
#RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(#ModelAttribute("user") User user){
User user1 = user;
userService.update(user1);
return new ModelAndView("redirect:/list");
}
If you need further details, you can read Getting Started with Forms in Spring MVC

Unable to get updated values in a dynamically created form using Spring Boot and Thymeleaf

I have created a dynamic form in Thymeleaf which populates feedbacks from all users in a table format on the UI. The form is first called when the GET Api of the controller gets hit. Relevant code for the same is given below :
allfeedbacks.html
<h2>Dynamic form</h2>
<form action="#" th:action="#{/updatefb}" th:object="${feedbacklist}"
method="post">
<table>
<tr>
<th>Message</th>
<th>Status</th>
<th>Comments</th>
</tr>
<tr th:each="feedback : ${feedbacklist.myfbList}">
<td th:text="${feedback.message}" th:field="${feedback.message}">The
first name</td>
<td><select>
<option value="Pending"
th:selected="${feedback.status == 'Pending'}">Pending</option>
<option value="In Process"
th:selected="${feedback.status == 'In Process'}">In
Process</option>
<option value="Done" th:selected="${feedback.status == 'Done'}">Done</option>
</select></td>
<td><input type="text" placeholder="Enter Comment Here"
name="comments" th:text="${feedback.comment}"
th:field="${feedback.comment}" /></td>
</tr>
</table>
<button type="submit">Submit</button>
</form>
Basically I have created two beans, one is the Feedback.java bean while the other is FeedbackList.java bean. Code for the same is given below :
Feedback.java
#Entity
#Table(name = "feedback")
public class Feedback implements Serializable {
private static final long serialVersionUID = -3009157732242241606L;
#Id
private String id;
public String getId() {
return id;
}
public String getMessage() {
return message;
}
public String getStatus() {
return status;
}
public String getComment() {
return comment;
}
#Column(name = "message")
private String message;
#Column(name = "status")
private String status;
#Column(name = "comment")
private String comment;
public Feedback() {
}
public Feedback(String message, String status) {
this.message = message;
this.status = status;
this.id = UUID.randomUUID().toString();
}
FeedbackList.java
public class FeedbackList {
ArrayList<Feedback> myfbList;
public ArrayList<Feedback> getMyfbList() {
return myfbList;
}
public void setMyfbList(ArrayList<Feedback> myfbList) {
this.myfbList = myfbList;
}
}
Relevant code from my Controller class is as follows :
#RequestMapping(value = "/getAll", method = RequestMethod.GET)
public String getAllFeedbacks(#Valid FeedbackList feedbacklist,
BindingResult bindingResult, Model model) {
ArrayList<Feedback> fbarray = new ArrayList<>();
for (Feedback fb : repository.findAll()) {
fbarray.add(fb);
}
feedbacklist.setMyfbList(fbarray);
model.addAttribute("feedback", new Feedback());
model.addAttribute("feedbacklist", feedbacklist);
return "allfeedbacks";
}
#RequestMapping(value = "/updatefb", method = RequestMethod.POST)
public String updatefbStatus(#Valid FeedbackList feedbacklist,
BindingResult
bindingResult, Model model) {
//feedbacklist is coming as NULL below
for (Feedback fb : feedbacklist.getMyfbList()) {
System.out.println(fb.getComment());
System.out.println(fb.getMessage());
System.out.println(fb.getStatus());
}
// Code to update the database with the new status and comment would go
// here
return "result";
}
The form is getting properly rendered on the UI when I fire the Get request, however, when I make some changes in the form and submit it ( POST ), feedbacklist is coming as NULL. Could anyone please guide me with this ?
To use a list inside a form with Thymeleaf is a little bit more tricky, you need to use an specific syntax, here i show you an example.
<tr th:each="feedback : ${feedbacklist.myfbList}">
<td th:field="*{myfbList[__${feedbackStat.index}__].message}">The
first name
</td>
...//Same for others fields
</tr>
In thymeleaf you have to use the Stat object to say the array position where you want to set the value, also as normal fields inside an object you have to use the '*' notation.

Display multi images with condition

I try to display a part of gallery's photo=> this is result when i did the search action. This result have avatar like a picture and infomation like username or email.
I create Photo.java like child of Users.java in relationship #ManytoOne
Here is my code :
Photo.java----
#Entity
public class Photo extends Model{
#Id
public Long id;
public String path;
#ManyToOne
#JoinColumn(name = "user_id")
public Users user;
}
Users.java-----
#Entity
public class Users extends Model{
#Id
public Long id;
#Constraints.Required
public String username;
#Constraints.Required
public String email;
#Constraints.Required
public String password;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
public List<Photo> photo = new ArrayList<Photo>();
public Users(){}
public Users(String username,String email,String password){
this.username=username;
this.email=email;
this.password=password;
}
}
Search.java -----
public static Result search(){
DynamicForm form = form().bindFromRequest();
String name = form.get("name");
Finder<Long, Users> find = new Finder<Long, Users>(Long.class, Users.class);
List<Users> users = find.where().like("username", '%'+ name +'%').findList();
if (form.get("name")=="" || users.isEmpty() || users==null){
return ok(search_again.render());
}
else{
return ok (search_result.render(users));
}
}
search_result.scala.html----
#(users : List[Users])
#main(nav= "search"){
<h3>Result</h3>
<input class="button" type="button" value="Back to Search">
<input class="button" type="button" value="Back to Home">
<p>Found #users.size() result(s) : </p>
<div class="sresult">
#for(user <- users){
<div id="sresult">
<div id="haha"><img src="#routes.Assets.at("upload/"+user.photo.path)"></div>
//Error here. Why "user.photo.path" not working ?
<p>
#user.username</a></br>
#user.password</a></br>
#user.email</a>
</p>
</div>
}
</div>
}
Why "user.photo.path" not working ? any ideal in my case ?

Categories