Send multipartfile jsp spring mvc to controller - java

I have a JSP project with Spring MVC. And I have a screen with a registration form (CRUD). I put an input file field to attach files. And I'm trying to send the attached file to the Model. But without success. Could someone tell me what is wrong with my implementation?
index.jsp:
<div class="modal fade" id="modalNovoResultado" tabindex="-1" role="dialog"
aria-labelledby="novoResultadoModal" aria-hidden="true">
<div class="modal-dialog" role="document">
<form:form method="POST" id="newResultado" modelAttribute="exameForm" action="criarResultado.do">
<div class="modal-content novo-resultado" style="padding: 0px !important;" >
<div class="modal-line novo-resultado"></div>
<div class="modal-header novo-resultado">
<p class="modal-title novo-resultado" id="exampleModalLabel" style="margin-top:10px;">Novo
resultado de exame</p>
</div>
<div class="modal-body pb-0">
<div class="container">
<div class="row mt-1">
<div class="form-group text-left col-md-6 tipo-exame">
<label class="modal-resultado">
Tipo de exame: <span class="required">*</span>
</label>
<form:select class="selectpicker form-control" id="tipoExameNew" path="tipoExame">
<form:option value="" selected hidden>Selecione</form:option>
<form:option value="999" selected hidden>Antígeno SarsCovid-19</form:option>
</form:select>
</div>
<div class="form-group text-left col-md-6 mb-0">
<label class="modal-resultado">
Anexe de um a três arquivos: <span class="required">*</span>
<img class="anexar-exame"
src="/PCBS-GestaoNovamed/includes/img/icon-nav-anexar.svg" alt=""
data-toggle="modal">
<form:input path="arquivo" id="fileModal" type="file" name="arquivo"/>
</label>
<label class="anexo-subtitle" style="font-size: 12px;">Arquivos PDF, JPG ou PNG, com
no máximo 10mb</label>
</div>
</div>
<div class="row">
<div style="margin-left: 230px;">
<div class="row botoes-formulario" style="float: right;">
<input type="submit" class="add-unidade-button cadastrar" value="Cadastrar"
onclick="validaForm()"/>
</div>
</div>
</div>
</div>
</div>
</div>
</form:form>
</div>
</div>
javascript:
function adicionarExame(element, event) {
event.preventDefault();
if (validaForm() > 0) return;
var form = document.getElementById('newResultado');
console.log("form:" + $(form).serialize());
$.ajax({
method: 'POST',
url: element.action,
data: $(form).serialize(),
cache: false,
success: function (status) {
Swal.fire({
customClass: {
title: 'title-class',
popup: 'popup-class popup-green',
content: 'content-class',
actions: 'actions-class-green'
},
type: 'success',
title: 'Resultado cadastrado com sucesso.',
text: ''
}).then(function () {
//window.location.reload();
})
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(thrownError);
var msgErro = 'Erro inesperado';
if (xhr.status === 400) {
msgErro = 'Erro ao cadastrar resultado.';
}
Swal.fire({
customClass: {
title: 'title-class',
popup: 'popup-class popup-red',
content: 'content-class',
actions: 'actions-class-red'
},
type: '',
title: msgErro,
text: ''
})
}
});
}
controller:
#RequestMapping(value = "criarResultado.do", method = RequestMethod.POST)
public ResponseEntity<ExameVO> cadastrarNovoExame(
#Valid #ModelAttribute(Constants.MA_MODEL_RESULTADO_EXAME) ExameForm exameForm,
BindingResult bindingResult,
Model model) {
LOGGER.error("entrou em criarResultado form" + exameForm.toString());
}
model:
#Component
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ExameForm implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//#NotNull(message = Constants.MSG_ERRO_CAMPO_OBRIGATORIO)
private String cpf;
//#NotNull(message = Constants.MSG_ERRO_CAMPO_OBRIGATORIO)
//#DateTimeFormat(pattern = "dd/MM/yyyy")
private String dataNascimento;
//#NotNull(message = Constants.MSG_ERRO_CAMPO_OBRIGATORIO)
private Long tipoExame;
//#NotNull(message = Constants.MSG_ERRO_CAMPO_OBRIGATORIO)
//private List<ExameArquivoVO> resultadoExameArquivos;
private MultipartFile arquivo;
private String observacao;
private String excluido;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento(String dataNascimento) {
this.dataNascimento = dataNascimento;
}
public Long getTipoExame() {
return tipoExame;
}
public void setTipoExame(Long tipoExame) {
this.tipoExame = tipoExame;
}
public String getObservacao() {
return observacao;
}
public void setObservacao(String observacao) {
this.observacao = observacao;
}
public String getExcluido() {
return excluido;
}
public void setExcluido(String excluido) {
this.excluido = excluido;
}
/*
public List<ExameArquivoVO> getResultadoExameArquivos() {
return resultadoExameArquivos;
}
public void setResultadoExameArquivos(List<ExameArquivoVO> resultadoExameArquivos) {
this.resultadoExameArquivos = resultadoExameArquivos;
}
*/
public MultipartFile getArquivo() {
return arquivo;
}
public void setArquivo(MultipartFile arquivo) {
this.arquivo = arquivo;
}
public ExameVO toVo() {
ExameVO vo = new ExameVO();
vo.setId(this.getId());
vo.setCpf(this.getCpf());
vo.setDataNascimento(this.getDataNascimento());
vo.setTipoExame(this.getTipoExame());
vo.setObservacao(this.getObservacao());
vo.setExcluido(this.getExcluido());
//vo.setResultadoExameArquivos(this.getResultadoExameArquivos());
vo.setFile(this.getArquivo());
return vo;
}
#Override
public String toString() {
return "ExameForm [id=" + id + ", cpf=" + cpf + ", dataNascimento=" + dataNascimento + ", tipoExame="
+ tipoExame + ", arquivo=" + arquivo + ", observacao=" + observacao + ", excluido=" + excluido + "]";
}
}

Related

There was an unexpected error (type=Internal Server Error, status=500). class java.lang.String cannot be cast to class com.app.inventory.model.Product

Hello comunity I need your help with a problem in my proyect, i need to add details in the database at the same time, I have been researching how to do, I found the solution is using a iterator or a bucle for, When I use the bucle obvious I need to use arrays, I did it, But I have a object, i did the conversion (cast), but when i add the details at the web i can't because appears this error
Basically the error is the program can't cast a String to Object(Class)
There was an unexpected error (type=Internal Server Error, status=500).
class java.lang.String cannot be cast to class com.app.inventory.model.Product (java.lang.String is in module java.base of loader 'bootstrap'; com.app.inventory.model.Product is in unnamed module of loader
org.springframework.boot.devtools.restart.classloader.RestartClassLoader #6817e14)
java.lang.ClassCastException: class java.lang.String cannot be cast to class com.app.inventory.model.Product (java.lang.String is in module java.base of loader 'bootstrap'; com.app.inventory.model.Product is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader #6817e14)
Model
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id_orden_compra;
#Temporal(TemporalType.DATE)
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date Fecha;
#Column(name="SubTotal",length=40)
private int SubTot;
#Column(name="Total",length=40)
private int Total;
#ManyToOne
#JoinColumn(name="id_Supplier_fk", referencedColumnName = "id_Proveedor")
private Supplier id_Supplier_fk;
#OneToMany(mappedBy = "id_PurchaseOrder_fk", cascade = CascadeType.ALL)
private List<Detalle_OrderCompra> detalles = new ArrayList<>();
public long getId_orden_compra() {
return id_orden_compra;
}
public void setId_orden_compra(Long id_orden_compra) {
this.id_orden_compra = id_orden_compra;
}
public Date getFecha() {
return Fecha;
}
public void setFecha(Date fecha) {
Fecha = fecha;
}
public Supplier getId_Supplier_fk() {
return id_Supplier_fk;
}
public int getSubTot() {
return SubTot;
}
public void setSubTot(int subTot) {
SubTot = subTot;
}
public int getTotal() {
return Total;
}
public void setTotal(int total) {
Total = total;
}
public void setId_Supplier_fk(Supplier id_Supplier_fk) {
this.id_Supplier_fk = id_Supplier_fk;
}
public Purchaseorder(Long id_orden_compra, Date fecha, int subTot, int total, Supplier id_Supplier_fk) {
super();
this.id_orden_compra = id_orden_compra;
Fecha = fecha;
SubTot = subTot;
Total = total;
this.id_Supplier_fk = id_Supplier_fk;
}
public Purchaseorder(Date fecha, int subTot, int total, Supplier id_Supplier_fk) {
super();
Fecha = fecha;
SubTot = subTot;
Total = total;
this.id_Supplier_fk = id_Supplier_fk;
}
public Purchaseorder(Date fecha) {
super();
Fecha = fecha;
}
public Purchaseorder() {
super();
}
//With this constructor I add the details in the database
public void añadirDetalles(int can, Product id_prod_fk){
this.detalles.add(new Detalle_OrderCompra(can, id_prod_fk ,this));
}
public List<Detalle_OrderCompra> getDetalles() {
return detalles;
}
public void setDetalles(List<Detalle_OrderCompra> detalles) {
this.detalles = detalles;
}
public void SetDetalle(long id_Detalle_OrderCompra,int can, Product id_prod_fk) {
this.detalles.add(new Detalle_OrderCompra(id_Detalle_OrderCompra,can, id_prod_fk, this));
}
}
Model
#Entity
#Table(name = "Detalle_OrdenCompra")
public class Detalle_OrderCompra implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id_Detalle_OrderCompra;
#Column(name="Cantidad",length=40)
private int Can;
#ManyToOne
#JoinColumn(name="id_prod_fk", referencedColumnName = "id_prod")
private Product id_prod_fk;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name="id_PurchaseOrder_fk", referencedColumnName = "id_orden_compra")
private Purchaseorder id_PurchaseOrder_fk;
public long getId_Detalle_OrderCompra() {
return id_Detalle_OrderCompra;
}
public void setId_Detalle_OrderCompra(long id_Detalle_OrderCompra) {
this.id_Detalle_OrderCompra = id_Detalle_OrderCompra;
}
public int getCan() {
return Can;
}
public void setCan(int can) {
Can = can;
}
public Product getId_prod_fk() {
return id_prod_fk;
}
public void setId_prod_fk(Product id_prod_fk) {
this.id_prod_fk = id_prod_fk;
}
public Purchaseorder getId_PurchaseOrder_fk() {
return id_PurchaseOrder_fk;
}
public void setId_PurchaseOrder_fk(Purchaseorder id_PurchaseOrder_fk) {
this.id_PurchaseOrder_fk = id_PurchaseOrder_fk;
}
public Detalle_OrderCompra(long id_Detalle_OrderCompra, int can, Product id_prod_fk,
Purchaseorder id_PurchaseOrder_fk) {
super();
this.id_Detalle_OrderCompra = id_Detalle_OrderCompra;
Can = can;
this.id_prod_fk = id_prod_fk;
this.id_PurchaseOrder_fk = id_PurchaseOrder_fk;
}
public Detalle_OrderCompra(int can, Product id_prod_fk, Purchaseorder id_PurchaseOrder_fk) {
super();
Can = can;
this.id_prod_fk = id_prod_fk;
this.id_PurchaseOrder_fk = id_PurchaseOrder_fk;
}
public Detalle_OrderCompra() {
super();
}
}
I'm not Using the service because is not nessesary
Controller
#Controller
public class PurchaseorderController {
#Autowired
PurchaseorderDao purorderdao;
#Autowired
PurchaseorderRepository purorrepo;
#Autowired
SupplierDao supdao;
#Autowired
ProductDao prodao;
#Autowired
Detalle_OrderCompraRepository detOrrepo;
#RequestMapping({ "/PurchaseOrderWEB", "/" })
public String ListUser(Model modelo) {
modelo.addAttribute("Purchase", purorderdao.EncontrarPurchase());
List<Supplier> lstSupplier = supdao.EncontrarSupplier();
modelo.addAttribute("Supplier", lstSupplier);
List<Product> lstProduct = prodao.EncontrarProduct();
modelo.addAttribute("Product", lstProduct);
List<Detalle_OrderCompra> lstdetalle = detOrrepo.findAll();
modelo.addAttribute("Detalle_OrdenCompra", lstdetalle);
return "PurchaseOrderWEB";
}
#PostMapping({ "/Purchasecrear" })
public String createDet(Purchaseorder purchaseorder, HttpServletRequest request) {
String[] DetallesIDs = request.getParameterValues("detallesIDs");
String[] DetallesCan = request.getParameterValues("detallesCan");
Object[] DetallesProd = request.getParameterValues("detallesProd");
//With this bucle for i add the Details
for (int i = 0; i < DetallesCan.length; i++) {
if (DetallesIDs != null && DetallesIDs.length > 0) {
purchaseorder.SetDetalle(Long.valueOf(DetallesIDs[i]), Integer.valueOf(DetallesCan[i]),
(Product) (DetallesProd[i]));
} else {
purchaseorder.añadirDetalles(Integer.parseInt(DetallesCan[i]),
(Product) (DetallesProd[i]));
}
}
purorrepo.save(purchaseorder);
return "redirect:/";
}
}
HTML
<head>
<meta charset="utf-8">
<title>Crud Purchase Order</title>
<link rel="stylesheet" th:href="#{/css/bootstrap.min.css}" />
<link rel="stylesheet" th:href="#{/css/StylesUS.css}" />
<script src="https://code.jquery.com/jquery-3.6.1.js"
integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI="
crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#4.4.1/dist/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<script type="text/javascript" src="../static/js/UpdateProduct.js"
th:src="#{/js/UpdateProduct.js}"></script>
</head>
<body>
<a><button class="ov-btn-grow-box"
onclick="document.getElementById('id01').style.display='block'">Crear</button></a>
<a class="ov-btn-slide-close" th:href="#{/}">Regresar</a>
<div id="id01" class="modal">
<span onclick="document.getElementById('id01').style.display='none'"
class="close" title="Close Modal">×</span>
<div class="container">
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 container justify-content-center card">
<center>
<h1>Registro de Ordenes de compra</h1>
</center>
<div class="ard-body">
<form th:action="#{/Purchasecrear}" method="post">
<div class="form-row row">
<div class="col-md-6">
<div class="form-group">
<label>Fecha:</label><br> <input type="date" name="Fecha"><br>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Subtotal:</label><br> <input type="text"
placeholder="Ingrese nombre producto" name="Subtotal"><br>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Total:</label><br> <input type="number"
placeholder="Ingrese precio compra" name="Total"><br>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Proveedores:</label> <select class="form-select"
name="id_Supplier_fk">
<th:block th:each="sup : ${Supplier}">
<option th:text="${sup.nom}" th:value="${sup.id_Proveedor}"></option>
</th:block>
</select>
</div>
</div>
<!-- Agregamos Los Detaless -->
<div class="form-group row">
<label class="col-form-label col-sm-4">Detalles #1 : </label>
<h4>Cantidad</h4>
<div class="col-sm-4">
<input type="text" name="detallesCan" class="form-control"
placeholder="Nombre" required>
</div>
<h4>Producto</h4>
<select class="form-select" name="detallesProd" id="id_prod_fk">
<th:block th:each="prod : ${Product}">
<option th:text="${prod.nom}" th:value="${prod.id_prod}"></option>
</th:block>
</select>
</div>
<div class="form-group row">
<label class="col-form-label col-sm-4">Detalles #2 : </label>
<h4>Cantidad</h4>
<div class="col-sm-4">
<input type="text" name="detallesCan" class="form-control"
placeholder="Nombre" required>
</div>
<h4>Producto</h4>
<select class="form-select" name="detallesProd" id="id_prod_fk">
<th:block th:each="prod : ${Product}">
<option th:text="${prod.nom}" th:value="${prod.id_prod}"></option>
</th:block>
</select>
</div>
<div class="form-group row">
<label class="col-form-label col-sm-4">Detalles #3 : </label>
<h4>Cantidad</h4>
<div class="col-sm-4">
<input type="text" name="detallesCan" class="form-control"
placeholder="Nombre" required>
</div>
<h4>Producto</h4>
<select class="form-select" name="detallesProd" id="id_prod_fk">
<th:block th:each="prod : ${Product}">
<option th:text="${prod.nom}" th:value="${prod.id_prod}"></option>
</th:block>
</select>
</div>
<div class="container">
<button type="submit" class="ov-btn-slide-left">Guardar</button>
<br> <br>
<button type="button" onclick="document.getElementById('id01').style.display='none'" class="o-btn-slide-left">Cancelar</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I'm using Spring Tool Suite
I just need to fill two tables and add many details at the same time
I fill the form, but It doesn't add the details, i don't know what happend, please if you don't understnad please contact me

Cant upload photos and store them as blob to mysql

I am trying to upload a photo with html and store it as a blob using Spring JPA
this is my ORM class.
#Entity(name = "Option")
#Table(name = "options")
public class Option {
#Id
#GeneratedValue(
strategy = GenerationType.IDENTITY
)
#Column(
name = "id",
unique = true,
updatable = false
)
private Long id;
#Column(
name = "img_name",
nullable = false,
columnDefinition = "TEXT"
)
private String imgName;
#Column(
name = "img_description",
nullable = false,
columnDefinition = "TEXT"
)
private String imgDesc;
#Lob()
#Column(
name="img_src",
columnDefinition = "bytea"
)
private byte[] imgSrc;
public Option(String imgName, String imgDesc) {
this.imgName=imgName;
this.imgDesc=imgDesc;
}
public Option() {
}
public byte[] getImgSrc() {
return imgSrc;
}
public void setImgSrc(byte[] imgDesc_i) {
this.imgSrc = imgDesc_i;
}
public String getImgName() {
return imgName;
}
public void setImgName(String imgName) {
this.imgName = imgName;
}
public String getImgDesc() {
return imgDesc;
}
public void setImgDesc(String imgDesc) {
this.imgDesc = imgDesc;
}
#Override
public String toString() {
return "Option{" +
"id=" + id +
", imgName='" + imgName + '\'' +
", imgDesc='" + imgDesc + '\'' +
'}';
}
public Option(Long id, String imgName, String imgDesc) {
this.id = id;
this.imgName = imgName;
this.imgDesc = imgDesc;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
and here is my form
<form action="#" th:action="#{/add}" th:object="${option}" method="post">
<div class="modal-body">
<div class="form-group">
<input type="hidden" th:field="*{id}" class="form-control" required>
</div>
<div class="form-group">
<label>Description</label>
<input type="text" th:field="*{imgDesc}" class="form-control" required>
</div>
<div class="form-group">
<label>Image name</label>
<input type="text" th:field="*{imgName}" class="form-control" required>
</div>
<div class="form-group">
<label class="form-label" >Upload image</label>
<input th:field="*{imgSrc}" type="file" class="form-control" />
</div>
</div>
<div class="modal-footer">
Cancel
<input type="submit" class="btn btn-success" value="Save">
</div>
</form>
and this is my controller
#PostMapping("/add")
public String addOption(#ModelAttribute("option") Option option) {
optionService.save(option);
return "redirect:/admin";
}
The problem is that I keep img src in Option class as array of bytes.
at MySQL dbms shows that type of imgSrc is blob
so when I am trying to save using jpa repository, it just saves image name.
could someone help me to solve issue?
thank You

Convert String to Money Thymeleaf

I am having a problem converting input String to money. I am creating a spring boot application with thymeleaf. I have a web page where user inputs the data and there is a particular field where he inputs the String and it needs to be converted to type joda.money as in my pojo class that field has money data type. This is a full governor_form.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>[[${pageTitleG}]]</title>
<link rel="stylesheet" type="text/css" th:href="#{/webjars/bootstrap/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container-fluid">
<div class="text-center"><h2>[[${pageTitleG}]]</h2></div>
<form th:action="#{/governors/save}" method="post" th:object="${governor}" style="max-width: 550px; margin: 0 auto;">
<input type="hidden" th:field="*{idGovernor}">
<div class="border border-secondary rounded p-3">
<div class="form-group row">
<label class="col-sm-4 col-form-label">Full name:</label>
<div class="col-sm-8">
<input type="text" th:field="*{fullName}" class="form-control" required minlength="5" maxlength="70">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Age</label>
<div class="col-sm-8">
<input type="number" step="0.01" th:field="*{age}" class="form-control" required>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Position</label>
<div class="col-sm-8">
<input type="text" step="0.01" th:field="*{position}" class="form-control" required>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Date of Intercession</label>
<div class="col-sm-8">
<input type="date" th:field="*{dateOfIntercession}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Date of Resignation</label>
<div class="col-sm-8">
<input type="date" th:field="*{dateOfResignation}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Per Capita Income</label>
<div class="col-sm-8">
<input type="number" step="0.01" th:field="*{perCapitaIncome}" class="form-control" required>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Population Below Poverty</label>
<div class="col-sm-8">
<input type="number" step="0.01" th:field="*{populationBelowPoverty}" class="form-control" required min="0" max="99">
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">State</label>
<div class="col-sm-8">
<select th:field="*{state}" class="form-control" required>
<th:block th:each="state : ${listStates}">
<option th:text="${state.officialStateName}" th:value="${state.idState}"/>
</th:block>
</select>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary m-2">Save</button>
<button type="button" class="btn btn-secondary m-2" onclick="cancelForm()">Cancel</button>
</div>
</div>
</form>
</div>
<script type="text/javascript">
function cancelForm() {
window.location = "[[#{/governors}]]";
}
</script>
</body>
</html>
This is where he inputs that data:
<div class="form-group row">
<label class="col-sm-4 col-form-label">Per Capita Income</label>
<div class="col-sm-8">
<input type="number" step="0.01" th:field="*{perCapitaIncome}" class="form-control" required>
</div>
</div>
So if i'm not mistaken Hibernate is having a problem converting a String input from thymeleaf to type money as I get the following error:
: Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'governor' on field 'perCapitaIncome': rejected value [1100]; codes [typeMismatch.governor.perCapitaIncome,typeMismatch.perCapitaIncome,typeMismatch.org.joda.money.Money,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [governor.perCapitaIncome,perCapitaIncome]; arguments []; default message [perCapitaIncome]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.joda.money.Money' for property 'perCapitaIncome'; Cannot convert value of type 'java.lang.String' to required type 'org.joda.money.Money' for property 'perCapitaIncome': no matching editors or conversion strategy found]]
This is the joda.money dependency:
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>1.0.1</version>
</dependency>
This is a POJO class:
#Entity
#Table(name = "governor")
public class Governor implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_governor")
private Integer idGovernor;
#Column(name = "pib")
private String fullName;
#Column(name = "age")
private Integer age;
#Column(name = "position")
private String position;
#Column(name = "date_of_intercession")
private java.sql.Date dateOfIntercession;
#Column(name = "date_of_resignation")
private java.sql.Date dateOfResignation;
#Column(name = "per_capita_income")
private Money perCapitaIncome;
#Column(name = "population_below_poverty")
private Integer populationBelowPoverty;
#ManyToOne
#JoinColumn(name = "id_state", nullable = false)
private State state;
public State getState() {return state;}
public void setState(State state) {this.state = state;}
public Integer getIdGovernor() {
return this.idGovernor;
}
public void setIdGovernor(Integer idGovernor) {
this.idGovernor = idGovernor;
}
public String getFullName() {
return this.fullName;
}
public void setFullName(String fullName) {this.fullName = fullName;}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPosition() {
return this.position;
}
public void setPosition(String position) {
this.position = position;
}
public java.sql.Date getDateOfIntercession() {
return this.dateOfIntercession;
}
public void setDateOfIntercession(java.sql.Date dateOfIntercession) {
this.dateOfIntercession = dateOfIntercession;
}
public java.sql.Date getDateOfResignation() {
return this.dateOfResignation;
}
public void setDateOfResignation(java.sql.Date dateOfResignation) {
this.dateOfResignation = dateOfResignation;
}
public Money getPerCapitaIncome() {
return this.perCapitaIncome;
}
public void setPerCapitaIncome(Money perCapitaIncome) {
this.perCapitaIncome = perCapitaIncome;
}
public Integer getPopulationBelowPoverty() {
return this.populationBelowPoverty;
}
public void setPopulationBelowPoverty(Integer populationBelowPoverty) {
this.populationBelowPoverty = populationBelowPoverty;
}
}
This is a controller:
#Controller
public class GovernorController {
#Autowired
GovernorService governorService;
#Autowired
GovernorRepository governorRepository;
#Autowired
StateRepository stateRepository;
#Autowired
StateService stateService;
#GetMapping("/governors")
public String showAllGovernors(Model model){
List<Governor> listGovernors = governorService.findAllGovernors();
model.addAttribute("listGovernors", listGovernors);
return "governors";
}
#GetMapping("/governors/new")
public String showNewGovernorForm(Model model){
List <State> listStates = stateService.findAll();
model.addAttribute("listStates", listStates);
model.addAttribute("governor", new Governor());
model.addAttribute("pageTitleG", "Add New Governor");
return "governor_form";
}
#PostMapping("/governors/save")
public String saveGovernor (Governor requestGovernor, RedirectAttributes redirectAttributes){
governorRepository.save(requestGovernor);
redirectAttributes.addFlashAttribute("messageG", "The governor has been saved successfully!");
return "redirect:/governors";
}
#GetMapping("/governors/edit/{id}")
public String showEditGovernorForm(#PathVariable("id") Integer id, Model model, RedirectAttributes redirectAttributes){
try {
Governor governor = governorService.findGovernorById(id);
List <State> listStates = stateService.findAll();
model.addAttribute("listStates", listStates);
model.addAttribute("governor", governor);
model.addAttribute("pageTitleG", "Edit Governor (ID: " + id + ")");
return "governor_form";
} catch (EntityNotFoundException e) {
redirectAttributes.addFlashAttribute("messageG", e.getMessage());
return "redirect:/governors";
}
}
#GetMapping("/governors/delete/{id}")
public String deleteGovernor(#PathVariable("id") Integer id, Model model, RedirectAttributes redirectAttributes){
try {
governorService.deleteGovernor(id);
redirectAttributes.addFlashAttribute("messageG", "The governor ID " + id + " has been deleted!");
} catch (StateNotFoundException e) {
redirectAttributes.addFlashAttribute("messageG", e.getMessage());
}
return "redirect:/governors";
}
}
How do I convert String to Money?
One solution would be to create custom deserilizer for Money field, and then use Jackson to set it.
Here is code snippet:
MoneyDeserializer.java :
public class MoneyDeserializer extends StdDeserializer<BigMoney> {
private static final long serialVersionUID = 2518470236548239933L;
public MoneyDeserializer() {
super(Money.class);
}
#Override
public BigMoney deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
return BigMoney.of(CurrencyUnit.USD, jp.readValueAs(Double.class));
}
}
Governor.java
import com.example.demo.filter.MoneyDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.joda.money.BigMoney;
import org.joda.money.Money;
import java.io.Serializable;
public class Governor implements Serializable {
private Integer idGovernor;
private String fullName;
private Integer age;
private String position;
private java.sql.Date dateOfIntercession;
private java.sql.Date dateOfResignation;
private BigMoney perCapitaIncome;
private Integer populationBelowPoverty;
public Integer getIdGovernor() {
return this.idGovernor;
}
public void setIdGovernor(Integer idGovernor) {
this.idGovernor = idGovernor;
}
public String getFullName() {
return this.fullName;
}
public void setFullName(String fullName) {this.fullName = fullName;}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPosition() {
return this.position;
}
public void setPosition(String position) {
this.position = position;
}
public java.sql.Date getDateOfIntercession() {
return this.dateOfIntercession;
}
public void setDateOfIntercession(java.sql.Date dateOfIntercession) {
this.dateOfIntercession = dateOfIntercession;
}
public java.sql.Date getDateOfResignation() {
return this.dateOfResignation;
}
public void setDateOfResignation(java.sql.Date dateOfResignation) {
this.dateOfResignation = dateOfResignation;
}
public BigMoney getPerCapitaIncome() {
return this.perCapitaIncome;
}
#JsonDeserialize(using = MoneyDeserializer.class)
public void setPerCapitaIncome(BigMoney perCapitaIncome) {
this.perCapitaIncome = perCapitaIncome;
}
public Integer getPopulationBelowPoverty() {
return this.populationBelowPoverty;
}
public void setPopulationBelowPoverty(Integer populationBelowPoverty) {
this.populationBelowPoverty = populationBelowPoverty;
}
#Override
public String toString() {
return "Governor{" +
"idGovernor=" + idGovernor +
", fullName='" + fullName + '\'' +
", age=" + age +
", position='" + position + '\'' +
", dateOfIntercession=" + dateOfIntercession +
", dateOfResignation=" + dateOfResignation +
", perCapitaIncome=" + perCapitaIncome +
", populationBelowPoverty=" + populationBelowPoverty +
'}';
}
}
NOTE: On your form, you are passing age field as Double, but in your class it's declared as Integer. So you will get exception during deserilization process.
Same thing applys for populationBelowPoverty field . Also, your date format is dd/MM/YYYY and I think this is not supported format for jackson. It should be YYYY-MM-dd.
Anyway, for example, if you send a JSON like this:
{
"idGovernor":1,
"fullName":"Test",
"age":1,
"dateOfIntercession":"2022-06-09",
"dateOfResignation":"2022-06-17",
"perCapitaIncome":"123.932",
"position":"position",
"populationBelowPoverty":"98"
}
to this controller method:
#PostMapping(value = "/test/governor")
public Governor testGovernor(#RequestBody Governor governor) {
return governor;
}
You should get response like this :
{
"idGovernor": 1,
"fullName": "Test",
"age": 1,
"position": "position",
"dateOfIntercession": "2022-06-09",
"dateOfResignation": "2022-06-17",
"perCapitaIncome": {
"amount": 123.932,
"zero": false,
"negative": false,
"positive": true,
"amountMajorLong": 123,
"negativeOrZero": false,
"amountMinorLong": 12393,
"amountMinor": 12393,
"positiveOrZero": true,
"minorPart": 93,
"scale": 3,
"amountMinorInt": 12393,
"currencyUnit": {
"code": "USD",
"numericCode": 840,
"decimalPlaces": 2,
"symbol": "$",
"numeric3Code": "840",
"countryCodes": [
"PR",
"MP",
"IO",
"FM",
"PW",
"GU",
"BQ",
"TC",
"VG",
"AS",
"VI",
"TL",
"UM",
"MH",
"EC",
"US"
],
"pseudoCurrency": false
},
"currencyScale": false,
"amountMajorInt": 123,
"amountMajor": 123
},
"populationBelowPoverty": 98
}
In your case, since you are using thymeleaf you can adjust this idea to your needs.

Validation failed for object='auctionItem'

When trying to submit my form to create a new auction this error appears in the browser:
Whitelabel Error Page:
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
Thu Mar 30 21:00:15 BST 2017
There was an unexpected error (type=Bad Request, status=400)
Validation failed for object='auctionItem'. Error count: 2
I can't seem to find any specific errors within my log, so I am having trouble finding the two validation errors show on the error page. I am pretty lost at this point. Hopefully someone can help me out, its preventing me from making progress at the moment.
JSP File:
<body id="product" class="product">
<header>
<%#include file="../jsp/Header.jsp" %>
</header>
<div>
<div class="container">
<div class ="row">
<div class="center_column">
<h2 style=" ">Create New Listing</h2>
<mvc:form class="form-inline" action="sell" method="post" modelAttribute="newAuction" id="addNewAuc">
<div class="form-inline" cssClass="TitleBlock">
<label class="control-label">Title</label>
<div>
<mvc:input path="aTitle" type="text" required="true" cssClass="Title" class="form-control" placeholder="Please enter title of item" maxlength="55" minlength="40"/>
</div>
</div>
<div class="form-group ">
<label class="control-label">Item Condition</label>
<div style="padding-top: 4px;">
<mvc:select path="aCondition">
<mvc:option value="New">New</mvc:option>
<mvc:option value="Used">Used</mvc:option>
</mvc:select>
</div>
</div>
<div class="form-group ">
<label class="control-label" style = "padding-left: 15px;">Can the item be returned?</label>
<div style="padding-top: 4px; padding-left: 15px;">
<mvc:select path="aReturns">
<mvc:option value="You can return">Yes</mvc:option>
<mvc:option value="Seller does not offer returns">No</mvc:option>
</mvc:select>
</div>
</div>
<div class="form-inline">
<label class="control-label">Description</label>
<div>
<mvc:textarea path="aDescription" required="true" cssClass="Desc" class="form-control" rows="3" name="Description" placeholder="Item description"/>
</div>
</div>
<div class="form-inline">
<label class="control-label">Category</label>
<div style="padding-top: 4px;">
<mvc:select path="categories">
<mvc:option value="category1">Electronics</mvc:option>
<mvc:option value="category2">Fashion</mvc:option>
<mvc:option value="category3">Home & Gardens</mvc:option>
<mvc:option value="category4">Toys & Games</mvc:option>
<mvc:option value="category5">Sports & Leisure</mvc:option>
</mvc:select>
</div>
</div>
<div class="form-inline">
<label class="control-label ">Minimum Price</label>
<div style="padding-top: 4px;">
<mvc:input path="aBottomPrice" type="number" step="any" required="true" class="form-control" placeholder="?"/>
</div>
</div>
<div class="form-inline">
<label class="control-label ">Starting Price</label>
<div style="padding-top: 4px;">
<mvc:input path="aTopPrice" type="number" step="any" required="true" class="form-control" placeholder="?"/>
</div>
</div>
<div class="form-inline">
<label class="control-label">End of listing</label>
<div style="padding-top: 4px;">
<mvc:input path="aEnd" type="text" id="datetimepicker" required="true" class="form-control" placeholder="YYYY-MM-DD"/>
</div>
</div>
</mvc:form>
<div class="form-inline">
<div style="padding-top: 10px;">
<button type="submit" name="submit" class="btn btn-success" form="addNewAuc">Next</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
AuctionItem Class
#Entity
#Table(name = "auction_items")
public class AuctionItem {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int idauction;
#Column(name = "auctionTitle")
private String aTitle;
#Column(name = "auctionDescription")
private String aDescription;
#Column(name = "auctionStatus")
private String aStatus;
#Column(name = "auctionStart")
private Date aStart;
#Column(name = "auctionEnd")
private Date aEnd;
private String endTimeAsString;
#Column(name = "auctionCondition")
private String aCondition;
#Column(name = "auctionTopPrice")
private double aTopPrice;
#Column(name = "auctionBottomPrice")
private double aBottomPrice;
private long auctionDuration;
private String aReturns;
#ManyToOne
#JoinColumn(name = "owner")
private User owner;
#ManyToOne
#JoinColumn(name = "cId")
private Category categories;
public long getAuctionDuration() {
return auctionDuration;
}
public void setAuctionDuration(long auctionDuration) {
this.auctionDuration = auctionDuration;
}
public int getaID() {
return idauction;
}
public void setaID(int idauction) {
this.idauction = idauction;
}
public String getaTitle() {
return aTitle;
}
public void setaTitle(String aTitle) {
this.aTitle = aTitle;
}
public String getaDescription() {
return aDescription;
}
public void setaDescription(String aDescription) {
this.aDescription = aDescription;
}
public String getaStatus() {
return aStatus;
}
public void setaStatus(String aStatus) {
this.aStatus = aStatus;
}
public Date getaStart() {
return aStart;
}
public void setaStart(Date aStart) {
this.aStart = aStart;
}
public Date getaEnd() {
return aEnd;
}
public void setaEnd(Date aEnd) {
this.aEnd = aEnd;
}
public String getaCondition() {
return aCondition;
}
public void setaCondition(String aCondition) {
this.aCondition = aCondition;
}
public double getaTopPrice() {
return aTopPrice;
}
public void setaTopPrice(double aTopPrice) {
this.aTopPrice = aTopPrice;
}
public double getaBottomPrice() {
return aBottomPrice;
}
public void setaBottomPrice(double aBottomPrice) {
this.aBottomPrice = aBottomPrice;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
public String getaReturns() {
return aReturns;
}
public void setaReturns(String aReturns) {
this.aReturns = aReturns;
}
public Category getCategories() {
return categories;
}
public void setCategories(Category categories) {
this.categories = categories;
}
public String getEndTimeAsString() {
return endTimeAsString;
}
public void setEndTimeAsString(String EndTimeAsString) {
this.endTimeAsString = EndTimeAsString;
}
}
Maybe you missed " BindingResult " in Controller.
Example:
import org.springframework.validation.BindingResult;
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(
#ModelAttribute("userlogin") #Valid LoginProfile userlogin,
BindingResult userloginResult)

JSON sent over AJAX to Spring+Hibernate based application does not get persisted

I am sending JSON object to a Spring+Hibernate+MySQL application.
Bellow is index.html where you can see the javascript making the request. Then there is Customer.java entity and CustomerRestController.java responsible for the request processing. Somehow my database is not getting updated.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#btnBooking').click(function(){
var custName=$('#userName').val();
var custAddress=$('#address1').val();
var JSONObject= {"name":custName, "address":custAddress};
//var jsonData = JSON.stringify( JSONObject );
$.ajax({
type: "POST",
url: "http://192.168.1.12:8080/HomeServiceProvider/rest/customer/saveCustomer",
data: JSON.stringify( JSONObject ),
dataType: "json",
processData: true,
contentType: "application/json; charset=utf-8",
success: function(data, status, jqXHR){
alert("success..."+data);
},
error: function(xhr){
alert("error"+xhr.responseText);
}
});
});
});
</script>
</head>
<body>
<form class="form-horizontal" id="scheduleLaterForm" name="scheduleLaterForm" action="#" method="post">
<div class="col-lg-8">
<div class="form-group">
<label class="col-lg-3 control-label">Name:<font style="color: red;">*</font></label>
<div class="col-lg-9">
<input class="form-control" id="userName" name="userName" placeholder="Full Name" value="" type="text">
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Address:<font style="color: red;">*</font></label>
<div class="col-lg-9">
<input class="form-control" name="address1" id="address1" placeholder="Full address" value="" type="text">
</div>
</div>
<div class="form-group marg-bot-45">
<label class="col-lg-3 control-label"></label>
<div class="col-lg-9">
<button type="button" class="btn btn-info" id="btnBooking"> Confirm Booking </button>
</div>
</div>
</div>
</form>
</body>
</html>
Customer.java
#Entity
#Table(name="CUSTOMER")
public class Customer implements Serializable{
private static final long serialVersionUID = -82689141527424144L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column (name="CUST_ID")
private int custId;
#Column (name="NAME")
private String name;
#Column (name="ADDRESS")
private String address;
public int getCustId() {
return custId;
}
public void setCustId(int custId) {
this.custId = custId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
CustomerRestController.java
#RestController
#RequestMapping("/customer")
public class CustomerRestController {
private static Logger log = LogManager.getLogger(CustomerRestController.class);
#Value("${msg.customeradded}")
private String message;
#Value("${msg.successcode}")
private int code;
#Autowired
private CustomerService customerService;
#RequestMapping(value = "/saveCustomer", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody Status saveCustomer(#RequestBody Customer customer){
try {
customerService.saveCustomer(customer);
return new Status(code, message);
} catch (Exception e) {
return new Status(0, e.toString());
}
}
#RequestMapping(value="/getAllCustomer",method=RequestMethod.GET, headers="Accept=application/json")
public #ResponseBody List<Customer> getAllCustomer(){
List<Customer> customers = null;
try {
customers = customerService.getAllCustomer();
log.info("Size:"+customers.size());
log.info("customers:"+customers);
} catch(Exception e) {
e.printStackTrace();
}
return customers;
}
}
CustomerService.java
public interface CustomerService {
public void saveCustomer(Customer customer);
public List<Customer> getAllCustomer();
}
CustomerServiceImpl.java
#Service
public class CustomerServiceImpl implements CustomerService {
private static Logger log = LogManager.getLogger(CustomerServiceImpl.class);
#Autowired
private CustomerDao customerDao;
public void saveCustomer(Customer customer) {
log.info("customer first name:" + customer.getCustName());
customerDao.saveCustomer(customer);
}
public List<Customer> getAllCustomer() {
List<Customer> customers = customerDao.getAllCustomer();
log.info("Size:"+customers.size());
log.info("customers:"+customers);
return customers;
}
}
Name of My table is CUSTOMER and columns are
colomn1: CUST_ID
colomn2: NAME
colomn3: ADDRESS

Categories