1
When receiving data from POST (AJAX) I only receive the id from Category and validate the class Product
the following error occurs:
Resolved [org.springframework.http.converter.Httpmessagenotreadableexception: JSON parse error: Cannot Construct instance of br.com.projectName.pedidos.model.Category (Although at least one Creator exists): no String-argument constructor/Factory method to deserialize from String value ('1'); nested Exception is com.fasterxml.Jackson.databind.exc.Mismatchedinputexception: Cannot Construct instance of br.com.projectName.pedidos.model.Category (Although at least one Creator exists): no String-argument constructor/Factory method to deserialize from String value ('1') at [Source: (Pushbackinputstream); line: 1, column: 76] (through Reference chain: br.com.projectName.pedidos.model.Product["Category"])]
Product (Model)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@OneToOne
@NotEmpty(message = "Selecione uma categoria para este Produto")
private Category category;
@Column
@NotEmpty(message = "Insita um nome válido para este campo")
private String name;
@Column
private boolean excluded = false;
//getter and setters
}
Category (Model)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private long id;
@Column
@NotEmpty(message = "Defina o nome da categoria")
private String name;
//getter and setters
}
Productcontroller
When there is a request via ajax via Post it receives the data and validates it.
@PostMapping("newProduct/")
public ResponseEntity<?> processFormProduct (@Valid @RequestBody Product product, BindingResult bindingResult) {
AjaxResponse result = new AjaxResponse();
Product productExists = productService.findByNameAndCategory(product.getName(), product.getCategory().getId());
if (productExists != null) {
bindingResult.rejectValue("name", "error.name", "Já existe um produto com esse nome na categoria seleciona");
}
if (bindingResult.hasErrors()) {
return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
} else {
productService.saveProduct(product);
result.setMsg("Produto cadastrado com sucesso!");
result.setType("create");
return ResponseEntity.ok(result);
}
}
Javascript script for AJAX request
$("#productForm").submit(function (event) {
event.preventDefault();
$(".validation-message").css("display", "block").html("");
$.ajax({
type: "POST",
contentType: "application/json",
url: $(this).attr("action"),
data: JSON.stringify($(this).serializeJSON()),
dataType: 'json',
cache: false,
success: function (data) {
if(data.type=="create"){
window.location.href = "/admin/produtos/?added=true";
}else{
window.location.href = "/admin/produtos/?updated=true";
}
},
error: function (e) {
var obj = Object.assign({}, e.responseJSON);
Object.keys(obj).forEach(function(item){
var field = obj[item].field;
var label = $($("input[name='"+field+"']").next(".validation-message"));
var msg = obj[item].defaultMessage;
if($(label).html()==""){
$(label).css("display", "block").html(msg);
}else{
$(label).append(", " + msg);
}
});
}
});
});
Formúlario (New Product)
<form id="productForm" th:action="@{/admin/produtos/newProduct/}" th:object="${product}" method="post">
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputNome" class="col-form-label">Nome</label>
<input type="text" class="form-control" id="inputNome" th:field="*{name}"
placeholder="Buquês">
</div>
<div class="form-group col-md-6">
<label for="selCategoria" class="col-form-label">Categoria</label>
<select id="selCategoria" class="form-control" th:field="*{category}">
<option th:value="null" selected>Selecione...</option>
<option th:each="categ : ${categorys}" th:value="${categ.id}" th:text="${categ.name}" ></option>
</select>
</div>
</div>
<button type="submit" class="btn btn-primary">Cadastrar</button>
</form>